2021-12-08(수) 5주차 3일
배열 → JSON 문자열
숫자에는 더블 쿼테이션 안 붙임
자원과 그 자원을 가리키는 주소
URL(Uniform Resource Locator)
패킷(Packet)
패킷 = 데이터 + IP 주소(출발지 IP, 목적지 IP) + PORT 번호(출발지 PORT, 목적지 PORT)
데이터를 주고 받으려면 보내는 이의 주소, PORT 번호
이삿짐을 쪼갠다.
2층 이삿짐이 먼저 도착할 수 있다.
짐을 풀 때는 모든 차가 다 도착한 다음 짐을 푼다.
데이터를 주고 받을 때도
5MB
1024 byte로 쪼갠다.
다 도착하면 하나로 합친다.
패킷 번호를 가지고 하나로 조립
이게 바로 OS가 하는 일
TCP/IP 라는 프로그램이 하는 일
IP Address : 컴퓨터와 컴퓨터를 구분
컴퓨터에 부여되는 번호
PORT 번호 : 프로그램 구분
프로그램에 부여되는 번호
Client
Server
Server에도 IP Address가 있고, Client도 IP Address가 있음
서버 주소가 매일 바뀌면 미치는 거
서버쪽은 고정 IP 사용
클라이언트는 동적 IP
Domain name
PORT 번호도 고정 시킴
클라이언트는 동적 PORT
데이터를 주고 받을 동안 사용하는 PORT 번호
운영체제로부터 받음
컴퓨터마다 IP Address가 있어야 구분할 수 있다
서버 컴퓨터는 고정 IP를 사용해야 한다.
서비스를 제공하는 서버는 PORT 번호가 고정되어 있어야 한다.
서버는 PORT 번호를 고정한다.
HTTP - 80 (프록시 서버)
HTTPS - 443
SMTP - 25
0 ~ 1023 : 잘 알려진 포트(well-known port), 사용하지 않는 것이 좋음
우리는 지금 8080 쓰고 있음
URL(Uniform Resource Locator)
http://서버주소:포트번호/lang/variable/exam.html
/lang/variable/exam.html
: 고정 자원의 경로
정적 자원(static resource)
이 자원에 대해서 요청을 하면
야야야 이 자원 좀 줘
읽어서 그대로 리턴
이런 자원이 고정 자원
자원 중에서 프로그램이 있음
프로그램 자원에 대해서도 URL을 붙인다
URL은 파일에 대해서만 URL을 부여하는 게 아니라 프로그램에 대해서도 부여 가능
http://서버주소:포트번호/lang/variable/exam4/test3
/lang/variable/exam4/test3
: 동적 자원의 경로 (실행시킬 프로그램의 경로)
동적 자원(dynamic resource)
프로그램을 실행한 후 그 결과를 리턴
⟹ 실행할 때마다 결과가 바뀔 수 있다.
⟹ 그래서 '동적'이라 부른다.
<a href="/lang/variable/exam4/test3">서버에 요청하기</a>
현재 화면을 그대로 둔 상태에서 별도로
그게 바로 AJAX 기술
웹 브라우저가 호출하는 메소드
콜백
화면의 일부만 최신 정보를 받고 싶어
JSON.parse()
배열이면 자바스크립트 배열로 만들어서 리턴
객체면 자바스크립트 객체로 만들어서 리턴
xhr.onload = function() {
// 서버에서 받은 JSON 형식의 배열을 자바스크립트 배열로 변환한다.
var names = JSON.parse(xhr.responseText);
for (var i = 0; i < names.length; i++) {
console.log(names[i]);
}
};
for of 반복문
cb : callback 약자
forEach(배열, 콜백함수)
배열.forEach(콜백함수)
내가 호출하는 게 아니라 forEach에서 호출한다 (콜백함수)
cb를 보면 콜백이구나
먼저 forEach 함수를 정의해준다.
function forEach(arr, cb) {
for (var item of arr) {
cb(item);
}
}
// 서버에서 받은 JSON 형식의 배열을 자바스크립트 배열로 변환한다.
var names = JSON.parse(xhr.responseText);
// 반복문을 직접 실행하는 대신에 그 일을 할 함수를 호출한다.
forEach(names, function(name) {
var li = document.createElement("li"); // <li><li>
li.innerHTML = name; // <li>홍길동<li>
xNamelist.appendChild(li);
})
test3_11.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>변수 활용</title>
</head>
<body>
<h1>배열 다루기</h1>
<a href="/lang/variable/exam4/test3">서버에 요청하기</a>
<button type="button" id="x-btn">배열 가져오기</button>
<ul id="x-namelist">
</ul>
<script>
var xNamelist = document.querySelector("#x-namelist");
var xBtn = document.querySelector("#x-btn");
xBtn.addEventListener("click", function() {
// 서버에 요청할 때 사용할 도구를 준비한다.
var xhr = new XMLHttpRequest();
// 서버에서 응답을 받았을 때(load 이벤트 발생) 호출될 함수를 등록한다.
xhr.onload = function() {
// 서버에서 받은 JSON 형식의 배열을 자바스크립트 배열로 변환한다.
var names = JSON.parse(xhr.responseText);
// 반복문을 직접 실행하는 대신에 그 일을 할 함수를 호출한다.
forEach(names, function(name) {
var li = document.createElement("li"); // <li><li>
li.innerHTML = name; // <li>홍길동<li>
xNamelist.appendChild(li);
})
};
// 서버와 연결한다.
// 서버 요청에 필요한 URL 정보를 설정한다.
xhr.open(
"GET", // HTTP 요청 방식
"/lang/variable/exam4/test3", // 요청 URL
true); // 비동기 여부 지정
// 서버에 요청 정보를 보낸다.
xhr.send();
});
function forEach(arr, cb) {
for (var item of arr) {
cb(item);
}
}
</script>
</body>
</html>
test3_12.html
배열.forEach(콜백함수)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>변수 활용</title>
</head>
<body>
<h1>배열 다루기</h1>
<a href="/lang/variable/exam4/test3">서버에 요청하기</a>
<button type="button" id="x-btn">배열 가져오기</button>
<ul id="x-namelist">
</ul>
<script>
var xNamelist = document.querySelector("#x-namelist");
var xBtn = document.querySelector("#x-btn");
xBtn.addEventListener("click", function() {
// 서버에 요청할 때 사용할 도구를 준비한다.
var xhr = new XMLHttpRequest();
// 서버에서 응답을 받았을 때(load 이벤트 발생) 호출될 함수를 등록한다.
xhr.onload = function() {
// 서버에서 받은 JSON 형식의 배열을 자바스크립트 배열로 변환한다.
var names = JSON.parse(xhr.responseText);
// 반복문을 직접 실행하는 대신에 그 일을 할 함수를 호출한다.
// 배열에 내장된(built-in) forEach() 사용하기
names.forEach(function(name) {
var li = document.createElement("li"); // <li><li>
li.innerHTML = name; // <li>홍길동<li>
xNamelist.appendChild(li);
})
};
// 서버와 연결한다.
// 서버 요청에 필요한 URL 정보를 설정한다.
xhr.open(
"GET", // HTTP 요청 방식
"/lang/variable/exam4/test3", // 요청 URL
true); // 비동기 여부 지정
// 서버에 요청 정보를 보낸다.
xhr.send();
});
</script>
</body>
</html>
fetch 사용
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>변수 활용</title>
</head>
<body>
<h1>배열 다루기</h1>
<a href="/lang/variable/exam4/test3">서버에 요청하기</a>
<button type="button" id="x-btn">배열 가져오기</button>
<ul id="x-namelist">
</ul>
<script>
var xNamelist = document.querySelector("#x-namelist");
var xBtn = document.querySelector("#x-btn");
xBtn.addEventListener("click", function() {
var result = fetch("/lang/variable/exam4/test3");
result.then(function() {
console.log("결과 받았음!");
});
/*
// 서버에 요청할 때 사용할 도구를 준비한다.
var xhr = new XMLHttpRequest();
// 서버에서 응답을 받았을 때(load 이벤트 발생) 호출될 함수를 등록한다.
xhr.onload = function() {
// 서버에서 받은 JSON 형식의 배열을 자바스크립트 배열로 변환한다.
var names = JSON.parse(xhr.responseText);
// 반복문을 직접 실행하는 대신에 그 일을 할 함수를 호출한다.
// 배열에 내장된(built-in) forEach() 사용하기
names.forEach(function(name) {
var li = document.createElement("li"); // <li><li>
li.innerHTML = name; // <li>홍길동<li>
xNamelist.appendChild(li);
})
};
// 서버와 연결한다.
// 서버 요청에 필요한 URL 정보를 설정한다.
xhr.open(
"GET", // HTTP 요청 방식
"/lang/variable/exam4/test3", // 요청 URL
true); // 비동기 여부 지정
// 서버에 요청 정보를 보낸다.
xhr.send();
*/
});
</script>
</body>
</html>
var result = fetch("/lang/variable/exam4/test3");
result.then(function() {
console.log("결과 받았음!");
});
결과를 받았을 때 호출될 함수를 등록한 거
결과는 함수의 파라미터 값으로 넘어오기로 약속이 되어 있다.
자바스크립트의 모든 함수에는 arguments 라는 내장 변수가 있다.
내장 변수 (built-in 변수)
arguments라는 배열에 저장됨
자바스크립트의 모든 함수에는 arguments라는 배열이 있다.
var result = fetch("/lang/variable/exam4/test3");
result.then(function() {
console.log(arguments);
});
var result = fetch("/lang/variable/exam4/test3");
result.then(function(response) {
console.log(response);
});
포장된 상태로 준다.
포장을 벗겨낸다. 자바스크립트 객체로 만들어 달라고 한다.
var result = fetch("/lang/variable/exam4/test3");
result.then(function(response) {
console.log(response.json());
});
xBtn.addEventListener("click", function() {
var result = fetch("/lang/variable/exam4/test3");
var result2 = result.then(function(response) {
return response.json();
});
result2.then(function() {
console.log("서버가 보낸 데이터에 대해 json 처리가 끝난 후 호출됨")
});
xBtn.addEventListener("click", function() {
var result = fetch("/lang/variable/exam4/test3");
var result2 = result.then(function(response) {
return response.json();
});
result2.then(function(jsonData) {
console.log(jsonData)
});
function chain
어떤 메소드가 리턴한 값을 기반으로 해서 함수를 줄줄이 사용하는 것을 메소드 체이닝(method chaining)이라고 부른다.
f1()
작업을 수행한 후 그 결과에 대해서 f2()
를 실행한다. f2()
의 결과에 대해서 f3()
를 실행한다.
얘가 리턴한 결과에 대해서 계속 이어지면서 작업을 함
한 줄로 표현하면 f1().f2().f3()
fetch()
체인
fetch().then(cb).then(cb)
↑ ↑ ↑
응답 작업완료후
AJAX 요청 ⟶ 호출 ⟶ 호출
xhr.open()
전화 연결
xhr.send()
말하기
fetch("/lang/variable/exam4/test3").then().then();
fetch("/lang/variable/exam4/test3").then(function() {console.log("okok1")}).then(function() {console.log("okok2")});
xBtn.addEventListener("click", function() {
fetch("/lang/variable/exam4/test3")
.then(function(response) {
return response.json();
})
.then(function(names) {
console.log(names);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>변수 활용</title>
</head>
<body>
<h1>배열 다루기</h1>
<a href="/lang/variable/exam4/test3">서버에 요청하기</a>
<button type="button" id="x-btn">배열 가져오기</button>
<ul id="x-namelist">
</ul>
<script>
var xNamelist = document.querySelector("#x-namelist");
var xBtn = document.querySelector("#x-btn");
xBtn.addEventListener("click", function() {
fetch("/lang/variable/exam4/test3")
.then(function(response) {
return response.json();
})
.then(function(names) {
names.forEach(function(name) {
var li = document.createElement("li"); // <li><li>
li.innerHTML = name; // <li>홍길동<li>
xNamelist.appendChild(li);
})
});
});
</script>
</body>
</html>
test3_14.html - java-lang-boot/src/main/resources/static/lang/variable/exam4
fetch("/lang/variable/exam4/test3")
http://localhost:8080/lang/variable/exam4/test3 ⟸ 메소드 URL
http://localhost:8080/lang/variable/exam4/test3_14.html ⟸ html URL
http://localhost:8080/lang/variable/exam4/test3_14.html
fetch("test3")
<script>
var xNamelist = document.querySelector("#x-namelist");
var xBtn = document.querySelector("#x-btn");
xBtn.addEventListener("click", function() {
// 현재 요청한 자원의 경로를 기준으로 상대 경로를 지정하는 것이 유지보수에 더 좋다.
// => 절대 경로: / 로 시작하는 경우
// 상대 경로: / 로 시작하지 않는 경우
// => 상대경로일 경우
// 현재 경로를 자동으로 붙인다.
// 요청하는 실제 경로는 현재 자원의 경로를 기준으로 계산한다.
fetch("test3")
.then(function(response) {
return response.json();
})
.then(function(names) {
names.forEach(function(name) {
var li = document.createElement("li"); // <li><li>
li.innerHTML = name; // <li>홍길동<li>
xNamelist.appendChild(li);
})
});
});
</script>
웹 브라우저가
스프링 부트는 단순히 읽어서 리턴하는 거
스프링 부트가 실행하는 건 Exam4에 있는 메소드
html은 처음부터 끝까지 웹 브라우저가 실행
상대 경로를 지정했을 때 실제 경로로 바꿔주는 건 웹 브라우저가 알아내서 요청
스프링 부트는 자바 클래스를 실행
실행 주체가 누구인지 정확하게 알고 있기
html 안에 있는 자바스크립트 코드가 웹 브라우저가 자바스크립트 엔진으로 실행
웹 브라우저는 2개의 엔진이 있다. Webkit 엔진, V8 엔진
자바스크립트가 스프링 부트에서 실행되는 게 아니라 웹 브라우저에서 실행되는 거
같은 우선순위에서는 먼저 나온 것을 먼저 계산한다.
com.eomcs.lang.ex05.Exam0130.java
리터럴끼리 산술 연산한 결과도 리터럴로 간주한다.
그 결과 값이 변수의 범위 내의 값이면 허락한다.
4 바이트 11이라고
2 바이트에 못 집어 넣어
short는 연산이 안 돼서 일단 short를 int 메모리에 담고 연산을 수행한다
모든 종류의 데이터에 대해 산술 연산자를 사용할 수 있는 것은 아니다.
System.out.println(10 && 10); // 컴파일 오류!이다.
자바는 숫자에 대해서 논리 연산 안 됨
int와 int의 연산 결과는 항상 int이다.
결과는 같은 타입
그 결과는 int
연산자와 데이터 타입
byte + byte
↓ ↓
int + int => int
두 개의 타입이 다르면 연산을 할 수 없다.
하나를 더 큰 쪽으로 바꿈
int + float
↓
float => float
long + float
↓
float => float
주의!
정수를 부동소수점으로 바꿀 때 값이 잘릴 수 있다.
✓ 같은 타입끼리만 연산 가능
✓ 다른 타입일 경우 형변환(암시적 형변환) 후 연산 수행
내부적으로 몰래
암시적 형변환
암시적 형변환
int i = 100;
float j = 3.14;
float s = i + j;
i 를 암시적 형변환
float 임시 메모리 준비
명시적 형변환
int i = 5;
int j = 2;
float s;
s = (float) i / (float) j;
변수 i 의 형이 바뀌는 게 아님
프로그램이 종료될 때까지 i 는 int형
원래 변수의 형은 그대로임
com.eomcs.lang.ex05.Exam0142.java
com.eomcs.lang.ex05.Exam0450.java
440 ~ 480
com.eomcs.lang.ex05.Exam0510.java
레지스트리
임시 메모리에 있는 데이터는 실행이 끝나면 버려진다.
연산을 수행할 때 암시적 형변환이 이루어진다.
com.eomcs.lang.ex05.Exam0160.java
부동소수점을 2진수로 바꾸는 과정에서 0000000001
맨 끝에 임의의 값이
끝나지 않는 수인 경우에는 000000001이 붙음
부동소수점 비교할 때 조심하기
결과 뒤에 극소수의 값이 붙는다.
988.7654110000001
EPSILON
두 수를 뺀 나머지가 극소수에 해당되면 두 수는 같다고 퉁친다
빼고 난 다음에 그 차이는 음수가 되면 안 됨
Math.abs 절댓값으로 바꾼 뒤 비교
com.eomcs.lang.ex05.Exam0220.java
예제 한 개 한 개 꼼꼼하게 보고 가기
Float.POSITIVE_INFINITY
com.eomcs.lang.ex05.Exam0222.java
여기까지 부동소수점
산술 연산자(+, -, *, /, %) 정리
① 정수 기본 연산은 int 이다.
② 같은 타입이어야만 연산 가능 ⟹ 결과도 같은 타입
다른 타입인 경우 → 암시적 형변환 → 타입을 일치시킴
③ 연산자 우선 순위
()
++a
, a--
*
, /
, %
+
, -
⋮
비교 연산자(<, <=, >, >=, ==, !=) 정리
① 부동소수점 비교 시 예측 결과와 다른 경우를 조심!
IEEE 754에서 부동소수점을 2진수로 바꿀 때 극소수의 값이 붙는 문제
무시할 값을 빼서 최종결과를 확인
a=false, b=true, r=false
330번
논리 연산자 : && vs &
lang.ex05.Exam0340.java
340번
논리 연산자 : || vs |
||
: 왼쪽 값으로 이미 결과를 알 수 있기 때문에 오른쪽 문장은 실행하지 않는다.
|
: 왼쪽 값으로 결과를 확정할 수 있더라도 무조건 오른쪽 문장을 실행한다.
r = a | (b = true);
← 오른쪽 문장도 실행하므로 b는 최종적으로 true가 된다.
lang.ex05.Exam0350.java
350번
비트 연산자(&, |, ^, ~)
| : 피연산자 중 한쪽의 값이 1이면, 1을 결과로 얻는다. 그 외에는 0을 얻는다.
& : 피연산자 양쪽이 모두 1이어야만 1을 결과로 얻는다. 그 외에는 0을 얻는다.
^ : 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.
~ : 피연산자를 2진수로 표현했을 때, 0은 1로, 1은 0으로 바꾼다. (논리부정 연산자)
이미지 프로세싱
포토샵에서 이미지 처리할 때 많이 씀
음성을 확대할 때 많이 씀
| : 어떤 색을 강화시키고 싶을 때 (기존 값 강화)
& : 어떤 색을 좀 빼고 싶을 때
^ : 크로마킹. 배경 이미지와 사람을 결합시켜서 같으면 투명하게 만드는 거
초록색.. 그린 스크린
비트 연산에서 not은 ! 연산자가 아니라 ~ 연산자 이다.
lang.ex05.Exam0351.java
비트 연산자 & 를 이용하여 % 연산 구현하기
57 → 00111001
1 → 00000001
57 & 1 → 00111001 & 00000001
2를 나눈 나머지를 구하는 것과 같다
실행 속도 측면에서 57에서 2를 나누는 것보다 비트연산을 수행하는게 실행속도가 훨씬 빠름
2를 나눈 나머지를 구할 때 %를 쓰지 않고 & 1
을 쓰는 경우도 많음
2로 나눈 나머지 구하는 거 → 홀수인지 짝수인지 알아내는 거
2로 나눈 나머지가 0이면 짝수, 1이면 홀수
& 연산자를 이용해서 % 2
57에서 4로 나눈 나머지 구하기
나머지는 0 또는 1 또는 2 또는 3이 나온다.
3으로 & 연산한다
57 0011 1001
& 3 0000 0011
---------------
01
주의!
& 연산자를 사용해서 나머지 값을 구하려면 나누는 값이 2의 제곱수여야 한다.
1, 2, 4, 8, 16 ⋯ 이렇게만 가능
6으로 나눈 나머지, 13으로 나눈 나머지 등은 & 연산자로 처리할 수 없다.
com.eomcs.lang.ex05.Exam0351.java
Exam0354
픽셀에서 파란색의 값을 강화시키고 싶다.
Exam0410
1비트 이동은 곱하기 2 한 것과 같은 효과를 준다.
논리 연산자 (&&, ||, ^, !)
① boolean 타입에 대해 사용
boolean && boolean
boolean || boolean
boolean ^ boolean
!boolean
② && vs &, || vs |
값 && (식)
값 || (식)
앞의 값으로 결과를 예측할 수 있다면 뒤의 식을 실행하지 않는다.
값 & 값
값 | 값
앞의 값이 무엇인지 상관없이 뒤의 식까지 모두 실행!
비트 논리 연산자 (&, |, ^, ~)
| : 피연산자 중 한쪽의 값이 1이면, 1을 결과로 얻는다. 그 외에는 0을 얻는다.
& : 피연산자 양쪽이 모두 1이어야만 1을 결과로 얻는다. 그 외에는 0을 얻는다.
^ : 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.
~ : 피연산자를 2진수로 표현했을 때, 0은 1로, 1은 0으로 바꾼다. (논리부정 연산자)
① 사용
정수 & 정수
정수 | 정수
정수 ^ 정수
~정수
⟹ 비트 단위로 수행
② 활용
& : 기존 색상을 뺄 때, 화면 필터 효과 → % 연산 수행
| : 기존 색상을 강화할 때, 화면 필터 효과
^ : 크로마킹 기법, 화면 필터, 화면 필터 효과
~ : 색상 반전
비트 이동 연산자
① 사용
정수 << 이동비트수 ⟹ 정수 × 2^이동비트수
정수 >> 이동비트수 ⟹ 정수 / 2^이동비트수
정수 >>> 이동비트수
② 활용
21 * 2 = 21 << 1
21 * 4 = 21 << 2
21 * 8 = 21 << 3
21 * 16 = 21 << 4
java.util.ArrayList arr;
Ctrl 키 누른 채로 클릭해서 이동
비트 이동은 부동소수점 연산이 안 이루어져서 빠름
음수의 경우는 양수로 바뀔 수 있다.
725
725 << 1 = 725 * 10¹
= 7250
725 << 2 = 725 * 10²
= 72500
자릿수 이동
원리는 똑같음
412번
정수 << 비트이동개수
정수가 int인 경우
int 타입의 값에 대해 비트 이동을 할 때는 0 ~ 31까지만 유효하다.
만약 31을 넘는 경우 32로 나눈 나머지 값을 비트 이동으로 간주한다.
비트이동개수 % 32 = 0 ~ 31까지 유효
비트이동개수 &
32로 나눈 나머지
3 <<
33 % 32 = 1 → 00100001
65 % 32 = 1 → 01000001
97 % 32 = 1 → 01100001
5비트만 유효하다.
앞에 있는 값은 무시
int 타입의 값에 대해 비트 이동을 할 때는 0 ~ 31까지만 유효하다.
만약 31을 넘는 경우 32로 나눈 나머지 값을 비트 이동으로 간주한다.
long 타입의 경우 비트 이동은 0 ~ 63까지 유효하다.
비트 이동 연산 응용
① 특정 위치의 바이트값을 추출할 때
481번까지 알아서 보기
510번 조건 연산자
삼항연산자
조건 연산자
문장 vs 식
02-자바기초2 / 57 페이지
510번
조건 ? 표현식1 : 표현식2
문장(statement) : 실행 명령, 더 상위 개념
표현식(expression) : 결과를 리턴하는 실행 명령 = 값을 리턴하는 문장
C:\Users\JYH\git\eomcs-java\eomcs-servlet\app\src\main\webapp
css, javascript, jquery, myquery 복사
C:\Users\JYH\git\bitcamp-study\java-lang-boot\app\src\main\resources\static
붙여넣기
Author And Source
이 문제에 관하여(2021-12-08(수) 5주차 3일), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@banana/5주차-3일저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)