2021-09-05

0905 웹을 지탱하는 기술

 1. 웹 뒷받침하는 기술

1) 서버 & 클라이언트 : 자원을 가지고 있는 쪽을 서버라고 부른다

2) 자원 요청 어떻게 하는가? : 자원을 식별해주는 주소 URI를 부른다.

2-2) URI의 구성 : sheme(방법. http 인지 ssh인지 그런것들) / 호스트명 ( 서버 컴퓨터의 ip주소) / 자원의 경로 

3) HTTP /1.1 : 서로다른 컴퓨터간에 통신을 하고 정보를 주고받기 위한 규약


2 . 동적컨텐츠와 정적컨텐츠

1) 동적컨텐츠를 생성해주는 기술 : CGI -> 요청시마다 프로세스를 새로 띄우기 때문에 효율성 매우 떨어짐

2) Servlet & JSP : 일단 프로세스 띄우고( 웹 컨테이너) 그 안에서 servlet이 request를 처리하기 때문에 효율 높다

3) 프레임워크의 필요성 : 비슷한 틀 만들어서 jsp servlet작업하는데 이부분을 프레임워크화해서 개발효율성을 높이자!


3. request header와 response헤더

통신규약(HTTP)에 정해진 내용들이 담겨있다.

이를테면 request header에는 어떤 method로, 어떤 uri에, 어떤 통신규약(HTTP 1.1) 으로요청할 것인지 의 내용이있다.

그외에도 accept라는 필드:내용을 살펴보면 수신할수있는 컨텐츠 타입을 지정할 수 있다. 나는 text/plain만 받을거야! 라고 설정하면. 그외의 요청은 수신할 필요가 없으므로 훨씬 효율적으로 요청을 처리할 수 있다.

response헤더의 경우 contents도 담아야 하기 때문에 훨씬 길다.

한번의 요청 - 한번의 자원으로 이루어진다.사진이 많이 포함되어있는 요청이라면 그만큼의 요청 수가 날라간다. 


4. 사설 ip와 글로벌 ip 

ip주소 고갈문제를 해결하기 위해 등장하였다. 일정범위 이내에서는 사설ip만 사용함으로써 ip를 효율적으로 사용할수있게 되었다. 그래서 ip추적이라는 개념이 - 거의 불가능한게, 어짜피 밖에서 보이는 내 아이피는 글로벌 ip이다. 글로벌 ip는 계속바뀌기때문에 일개인이 이걸 바탕으로 주소를 알아내기란 불가능하다고 할 수 있다. 다만 글로벌 ip는 해당 주변 ISP가 할당하는 것이므로, 그 근처이겠구나(?) 정도로까지는 알 수 있을지도..


5. 호스트명(ip)어떻게 알아내는가 ?

DNS가 ip를 인간이 기억하기 쉬운 영문주소로 변환해준다.


6. 포트번호

통신을 위해서는 URI뿐만아니라 포트번호도 필요하다. ip주소만으로는 해당 호스트 컴퓨터의 어떤 어플리케이션을 이용할것인지 몰르기때문이다. 카카오톡으로 보냈는데 네이트온으로 오는 일은 없지 않은가. 일반적으로 웹의 경우 많이 사용되기 때문에 보통 80번을 사용한다. well-known-port라고 한다. 그래서 웹 애플리케이션을 이용할때 우리는 포트번호를 굳이 붙이지 않아도 되는것이다. 

0904 아파치 카프카 실습 준비

 1. 아마존 aws console이용해서 리눅스환경을 만들자

2. EC2인스턴스 생성(프리티어). 더불어서 key도 새로 만들어서 받아놓자.

3. 인바운드 규칙 편집.

인바운드란 ? 외부에서 -> 해당 서버(내경우에는 EC2서버) 로 들어올 수 있는 아이피 및 포트번호 설정. 주키퍼 및 카프카에서 해당 인스턴스에 접근할 수 있도록 포트번호와 아이피를 열어둔다. 이번은 시험용이니까 anywhere로 해도 괜찮지만.. 실제라면 ip를 특정해주는 것이 보안상 안전할 것이다! 

아웃바운드란 ? EC2서버 에서 -> 바깥 네트워크로 나가는 설정. 기본적으로모두열려있음. 

4. puttygen을 사용해서 private key를 만들고 저장한다.

5. putty를 사용해서 Auth란에 해당 프라이빗 키를 넣고, public ip 에 EC2의 ip를 넣고 접속한다.

6. 나는 이번에 amzon2타입인스턴스로 만들었기 때문에 - 기본적으로 유저네임은 ec2-user이다.


접속 성공.



자바 및 아파지 카프카 설치. wget 명령어(web상에 있는 파일을 다운로드 할 수 있게 해주는 명령어) 를 이용 + tar 명령어로 압축을 푼다. 

2021-09-03

0903 set, linkedList, map

 1. set 은 언제 사용하는가?

- 순서에 상관없이, 중복하지 않는 데이터를 저장

- 인덱스없이 그냥 해당 데이터가 존재하는지 존재하지 않는지만 확인하고 싶을 때 사용

- 구현한 주요 클래스로는 HashSet, TreeSet, LinkedHashSet이 있다.

1) HashSet : 가장 대표격인 Set클래스. 해쉬값으로 저장한다. 

2) TreeSet : 이진트리 + balanced Tree = 레드 블랙트리구조를 가진다.

이진트리의 장점 = 중위탐색으로 , 정렬된 결과를 반환할수있다. 루트의 하위 왼쪽 노드는 루트노드보다 작은 숫자, 루트의 하위 오른쪽노드는 루트노드보다 큰 숫자.

이진트리의 약점( depth가 n만큼 증가할 수 있다는 점) 을 보완하여, 조회삭제수정 연산에서 logn의 매우 향상된 성능을 보인다.


2. HashSet

- set의 생성자중 독특한 점 : load factor

- load factor란, 해당 셋에 얼마만큼 원소가 차있는가를 나타낸다. 이 값은 0.75로 자바에서는 셋팅되어있다(default 값, 사용자가 건드리지 않은 경우.) 

만약 set에 저장된 원소의 개수가 많아져서 0.75를 초과하게 될 경우, set의 크기는 2배로 resize되며 이 과정에서 다시 원소들의 해쉬값을 계산하고 새 배열로 이동하는 연산이 이루어진다. 이 과정에서 성능 하락 있을 수 있음. 0.75가 웬만하면 최적화된 수치라고 하니 적어두 근 몇년간 자바견습생이 건드릴 일은 아마 없을 것..ㅎㅎ


3. LinkedList

- list의 일종이자, queue와 deque를 구현하고 있다. 

- deque는 double ended queue이다.

- 배열 중간의 데이터가 수정/삭제 연산이 많이 이루어진다면, LinkedList를 사용하는 것을 고려해본다. 

- linkedList가 데려오는 iterator 는 두가지 종류가 있는데 , 일반적인 Iterator와 ListIterator 가 있다. ListIterator는 특이하게 previous() 가 가능하다. 원소의 앞뒤에 붙은 원소를 탐색할 수 있어야 하기 때문에. next()로 다음으로 가는 것도 가능하고 이전으로 가능것도 가능한 것이다.  


<Map>

1 . key, value를 가진다. key는 고유해야 하므로, equals와 hashcode를 구현해야 한다.

2. 만약 equals, hashcode를 구현하지 않은 타입을 key로 저장할경우 해당 객체의 메모리주소를 가지고 객체의 동일성을 판단하게 되므로, 논리적으로는 같아보이는 값이 여러번 저장될 것이다.

3. Map은 Collection에 속하지 않는다. put(), get()으로 넣고 뺀다.

4. keySet() 메소드로 key만 Set타입으로 뽑아볼 수 있다.

5. values() 메소드로 값만 Collection타입으로 뽑아볼 수 있다.

6. Map을 구현한 Properties클래스라는 것이 있다. 

1) 따라서 마찬가지로 key, value로 값을 저장한다.

2) 추가적으로, 데이터를 읽고 쓰기 위한 메소드들을 제공한다. 

3) system properties를 이 객체를 통해 확인해 볼 수 있다. ( encoding type, user.dir 같은 속성들..) 

2021-09-02

0902 Collections, List탐구

 1. 대표적인 자료구조 : List, Set, Queue, Map

List, Set, Queue는 Collection을 상속한다. Map만 따로.

2. List의 대표격인 - ArrayList가 있다.

3. List의 하나로 Stack이 있다. Stack 은 일반적인 list관련 메소드 + pop(), peek(), empty(), push()를 지원한다. Vector클래스를 상속하고 있기 때문이다. 

4. list에서 요소를 뽑아내는 방법은 크게 세가지를 들 수 있다.

1) iterator사용 2) for(int=0;i=list.size(); i++) 3)향상된 for문 사용

effective java에서는 3)을 쓸것을 권하고 있다. 보기에도 편하고 ( 2번보다의 장점) , iterater를 썼을때 변수가 많이 만들어져서 실수할 위험도 줄어든다 (1번보다의 장점)

단 알고리즘 풀이라든지. 인덱스정보가 필요한 경우 2를 사용할 수도 있겠다. 상황에 따라 적절한 메서드를 구현하자.

5. ArrayList의 생성자

1) new ArrayList() 

2) new ArrayList(int size)

배열의 크기를 지정할 수 있다.

3) new ArrayList(다른 리스트);

단 이것은 shallow copy이므로 사용에 주의한다. clone()메서드도 마찬가지로 shallow카피를 한다. 만약에 원본 객체의 값이 달라지면 모든 리스트에 파급효과가 미친다!!! 객체 자체를 담은 게 아니라, 객체의 주소를 담은 것이기 때문이다.

그러므로 의도치 않은 파급효과를 막고싶다면 - 카피하려는 객체 자체도 cloneable을 구현해주어야 한다. 




위와같이.. 원본객체 하나만 바뀌어도 다바뀐다. 이럼 완죤 망하는 거다. ㅜㅜ 어디서 값이 바뀐건지 추적도 쉽지않다. 값이 바뀌는 지점과 확인하는 지점이 멀어지면 멀어질수록- 디버깅은 힘들어지는 것이다.... (상상만 해도 무섭다;)

---------------------------------------------------------------------------------------------
6. arrayList -> 배열로 만들기
1) String[] str = (String[]) ArrayList().toArray();
이런식의 강제 캐스팅은 실패한다. toArray의 파라메터에 아무것도 넘기지 않으면
Object[] 타입을 리턴하기 때문이다. 
여기서 유의할 점은 - String은 분명히 Object의 하위타입이 맞다.
또한 String[]은 Obejct[]의 하위타입이 맞다.
그러므로 컴파일도 잘 된다. 
막나가서 - 해당 ArrayList안에 int타입이 들어가 있었다고 치자. 근데 그래도 컴파일 잘된다!!
그러다가 런타임에서 오류가 난다... 런타임에서는 String[]으로 변하기 때문이다. 
( 이래서 배열을 쓰지말구 제네릭을 이용한 Collection클래스를 권장하는 것이다. Collection은 런타임에서 이런 타입에러를 잡아주기 때문이다.)
배열은 공변, Collection은 불공변이다.

2) 그러므로 배열로 바꾸어야 할 일이있다면
toArray(new String[0])과 같이, 원하는 타입의 파라메터를 넣어준다.
해당 배열의 크기가 ArrayList의 size보다 작을 경우, 임의로 배열을 생성해서 값을 넣어준다. 

3) 아니면 java8문법 사용한다. streams api

0902 generic과 wildcard 2

 

1. wildcard는 메서드의 파라메터로서만 사용할 수 있다. 안그러면 저렇게 에러를 뱉는다.

return 값으로 ? 가 된다니 타입에 엄격한 자바세계에서는 말도 안된다!

알지도 못하는 타입으로 내가 어떻게 돌려주랴?! 하는 컴파일러의 툴툴거림이 들리는 듯하다.



2. Bounded경계를 정할 수 있다.

PECS원칙에 따라,producer-extends, consumer-super 


출처: https://starblood.tistory.com/entry/Java-PECS-producerextends-consumersuper-에-관하여 [Drink and Be happy]

하도록 설계한다. ( 이부분 어렵다. ㅜㅜ)



  이와같은 Car를 상속한 Bus 클래스가 있다.

Bus클래스는 자기만의 메소드 getPassenger를 추가로 가지고 있다.



3. 당연하게도 Bus타입만의 메소드는 부를 수 없다. 

4. 언제 ?를 사용하고, 언제 T 를 사용하는가

: ?는 보통 해당 원소의 데이터와 상관없을 때 사용한다고 한다. ?의 의미자체가, '들어오는 너가 어떤 타입이든 상관하지 않는다' 라는 뜻을 내포하고 있기 때문이다.

이를 테면 - <? extends Number> 같은 경우를 들수있겠다. 너가 어떤타입이든간에, Number의 하위타입이기만 하면된다. 그런뜻. 추측컨대 이러한 경우는 -  ?로 들어오는 타입의 기능을 사용하는 것이 아니라 Number의 기능만 있으면 되는 메서드 일 것이다.

물론 기능적으로는 <? extends Number>이라고 쓰던, <T extends Number> 이라고 쓰던, 똑같이 동작할 수도 있다. 하지만 어떠한 내용의 메소드를 구현하고자 하는지, 해당 목적에 따라 적절하게 타입파라메터를 작성하는 것이, 훨씬 명확해질 것이다.

0902 access log

 apache 의 경우, access_log 폴더 밑에 만들어진다.

이 로그는 액세스가 완료된 후 생성되기 때문에, 만약에 네트워크 장애로 정상적인 접속이 계속되서 지연될 경우 , 생성되지 않는다. 

이럴때는 L4를 끊은 후에, 다른 서버로 돌려주고, 로그를 찍고, 에러를 분석한다.

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

이제 로그 항목의 각 부분을 설명한다.

127.0.0.1 (%h)
서버에 요청을 한 클라이언트(원격 호스트)의 IP 주소이다. HostnameLookups가 On이라면 호스트명을 찾아서 IP 주소 자리에 대신 쓴다. 그러나 이 설정은 서버를 매우 느리게 할 수 있으므로 추천하지 않는다. 호스트명을 알려면 대신 나중에 logresolve와 같은 로그를 처리하는 프로그램을 사용하는 것이 좋다. 여기에 나온 IP 주소는 사용자가 사용하는 컴퓨터 주소가 아닐 수 있다. 프록시 서버가 사용자와 서버사이에 존재한다면, 원래 컴퓨터 주소가 아니라 프록시의 주소가 기록될 것이다.
- (%l)
출력에서 "빼기기호"는 요청한 정보가 없음을 나타낸다. 이 경우 여기에 나올 정보는 클라이언트 컴퓨터의 identd가 제공할 클라이언트의 RFC 1413 신원이다. 이 정보는 매우 믿을 수 없기때문에, 긴밀히 관리되는 내부 네트웍이 아니라면 절대로 이 정보를 사용하면 안된다. IdentityCheck가 On이 아니라면 아파치 웹서버는 이 정보를 알아보려고 시도하지도 않는다.
frank (%u)
이는 HTTP 인증으로 알아낸 문서를 요청한 사용자의 userid이다. 보통 이 값은 CGI 스크립트에게 REMOTE_USER 환경변수로 넘겨진다. 요청의 상태코드가 401이라면 (아래 참고) 사용자가 아직 인증을 거치지 않았으므로 이 값을 믿으면 안된다. 문서를 암호로 보호하지 않는다면 이 항목은 이전 항목과 같이 "-"이다.
[10/Oct/2000:13:55:36 -0700] (%t)
서버가 요청처리를 마친 시간. 형식은:

[day/month/year:hour:minute:second zone]
day = 숫자 2개
month = 숫자 3개
year = 숫자 4개
hour = 숫자 2개
minute = 숫자 2개
second = 숫자 2개
zone = (`+' | `-') 숫자 4개

로그 형식문자열에 %{format}t를 사용하여 다른 형식으로 시간을 출력할 수 있다. format은 C 표준 라이브러리의 strftime(3)과 같다.
"GET /apache_pb.gif HTTP/1.0" (\"%r\")
클라이언트의 요청줄이 쌍따옴표로 묶여있다. 요청줄은 매우 유용한 정보를 담고 있다. 첫째, 클라이언트가 사용한 메써드는 GET이다. 둘째, 클라이언트는 자원 /apache_pb.gif를 요청한다. 세번째, 클라이언트는 HTTP/1.0 프로토콜을 사용한다. 요청줄의 여러 부분을 따로 로그할 수도 있다. 예를 들어, 형식문자열 "%m %U%q %H"은 "%r"과 똑같이 메써드, 경로, 질의문자열, 프로토콜을 로그한다.
200 (%>s)
이는 서버가 클라이언트에게 보내는 상태코드이다. 이 정보는 (2로 시작하는 코드) 요청이 성공하였는지, (4로 시작하는 코드) 클라이언트에 오류가 있는지, (5로 시작하는 코드) 서버에 오류가 있는지 알려주므로 매우 중요하다. 상태코드의 전체 목록은 HTTP 규약 (RFC2616 section 10)에서 찾을 수 있다.
2326 (%b)
마지막 항목은 응답 헤더를 제외하고 클라이언트에게 보내는 내용의 크기를 나타낸다. 클라이언트에게 보내는 내용이 없다면 이 값은 "-"이다. 내용이 없는 경우 "0"을 로그하려면 대신 %B를 사용한다.

출처: https://httpd.apache.org/docs/2.4/ko/logs.html

0902 generic 과 wildcard

 

wildcard <?> 으로 선언한 객체를 특정타입(String)으로 지정하자 컴파일 에러가 난다.

알수없는 타입을 특정타입으로 지정하여 반환하는 것이 불가능하기 때문이다.



따라서 ?로 파라메터를 받을 경우, object로 반환하여야 컴파일 에러가 나지않는다.



만약 wildcard로 넘어오는 타입이 정해져있다면, 분기문을 이용하여 각각 처리해줄수도 있다.

0328 fdisk, mkfs, mount, fstab

 1. 하드디스크를 붙인다. 2. fdisk -l로 하드디스크를 확인한다.  - interactiive한 커맨드모드 사용하여 (m) 붙인 하드디스크의 파티셔닝을 한다.  - 마지막에 w를 해야 실제로 반영이 된다.  3. mkfs를 하여 어떤 파일시스...