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

붙여넣기

좋은 웹페이지 즐겨찾기