클래스도 제공한다.
761 | 이는 값을 갖거나 갖지 않을 수 있는 컨테이너 객체이다.
762 |
763 | - 값이 존재한다면 Optional 클래스는 값을 감싼다
764 | - 값이 없다면 Optional.empty메서드로 Optional을 리턴한다
765 |
766 | ### 5. CompletaleFuture
767 | https://m.blog.naver.com/PostView.nhn?blogId=horajjan&logNo=220328527952&proxyReferer=https%3A%2F%2Fwww.google.com%2F
768 |
769 | > 미래를 예약하는 값이나, 그냥 Future 에 비해 장점이 많다. 예를 들어 서로 독립적인 비동기 동작이든 아니면 하나의 비동기 동작이 다른 비동기 동작의 결과에 의존하는 상황이든 여러 비동기 동작을 조립하고 조합할 수 있다.
770 |
771 | 한 문장으로만 표현하자면, **람다 표현식** 과 **파이프라인 (.xx.yy)** 이 가장 큰 장점
772 | ~~~java
773 | ExecutorService executor = Executors.newSingleThreadExecutor();
774 |
775 | CompletableFuture.runAsync(()->{
776 | try{Thread.sleep(1000);} catch(Exception e){};
777 | System.out.println("Hello!");
778 | try{Thread.sleep(1000);} catch(Exception e){};
779 | },executor)
780 | .thenRun(()->System.out.println("World"));
781 |
782 | System.out.println("async request is ready.");
783 | ~~~
784 |
785 | 두개의 비동기 task 가 **자연스럽게 연결** 되었다. (A완료시 B실행)
786 |
787 | 1) Executor를 통해 비동기 task 가 수행될 쓰레드를 생성하고
788 | 2) CompletableFuture.runAsync를 통해 다른 쓰레드에서 비동기 식으로 동작할 로직를 선언하고
789 | 3) CompletableFuture.thenRun 를 통해 첫번째 task 가 완료된 이후에 연속적으로 동작할 로직을 선언함
790 |
791 | 따라서 장점을 따지자면
792 | - 태스크간 조합과 결합이 용이하다 (연속적 연결)
793 | - 여러 Completable Future 를 합쳐서, 마지막 놈 되는대로 결합가능
794 | - thenCompose 매소드는 첫 번째 연산의 결과를 두 번째 연산으로 전달한다
795 | - exceptionally 로 예외처리가 용이하다
796 | - 커스텀 Executor를 사용하여 스레드 풀의 크기를 조절하는 등 애플리케이션에 맞는 최적화된 설정을 만들 수 있다 (오버로딩 된 supplyAsync)
797 |
798 | ### 6. New date / time APIs
799 |
800 | ## 12. 객체 직렬화 (Serialization)
801 | http://woowabros.github.io/experience/2017/10/17/java-serialize.html
802 | > 자바 직렬화란 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)을 아울러서 이야기합니다.
803 | 시스템적으로 이야기하자면 JVM(Java Virtual Machine 이하 JVM)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 같이 이야기합니다.
804 |
805 | - 클래스 직렬화를 원한다면 해당 클래스가 Serializable 인터페이스를 구현하면 된다.
806 | ~~~java
807 | public class A implements Serializable {
808 |
809 | }
810 | ~~~
811 |
812 | - 보안 상의 문제나 기타 이유로 멤버변수의 일부를 제외하고 싶다면 transient를 통해 지정할 수 있다.
813 |
814 | ~~~java
815 | public class User implements Serializable {
816 | private String id;
817 | private transient String password;
818 | private String email;
819 | }
820 | ~~~
821 |
822 | - 클래스에서 다른 클래스를 의존하는 경우 의존 클래스도 Serializable 인터페이스를 구현해야 직렬화할 수 있다.
823 |
824 | - JVM의 메모리에서만 상주되어있는 객체 데이터를 그대로 **영속화(Persistence)** 가 필요할 때 사용된다.
825 |
826 | - CSV, JSON 등으로도 직렬화가 가능하다
827 |
828 | - CSV, JSON, 프로토콜 버퍼 등은 시스템의 고유 특성과 상관없는 대부분의 시스템에서의 데이터 교환 시 많이 사용됩니다.
829 |
830 | - **자바 직렬화 형태** 는 자바 시스템 간의 데이터 교환을 위해서 존재한다
831 |
832 | - 자바 직렬화의 장점
833 | > 자바 직렬화는 자바 시스템에서 개발에 최적화되어 있습니다. 복잡한 데이터 구조의 클래스의 객체라도 직렬화 기본 조건만 지키면 큰 작업 없이 바로 직렬화 가능하다
834 |
835 | - 역직렬화시 데이터 타입이 자동으로 맞춰지기 때문에 편리
836 | - 역직렬화가 되면 기존 객체처럼 바로 사용할 수 있음
837 |
838 | - 주의점
839 |
840 | - 역직렬화가 되지 않을 때와 같은 예외처리는 필수
841 | - 용량이 크기 때문에 새롭게 스타트하는 서비스 같은 경우에는 생산성을 위해서 자바 직렬화를 그대로 이용한다고 해도 트래픽이 지속적으로 증가할 때에는 JSON 형태 또는 다른 형태의 직렬화로 바꿔주는 것 고려
--------------------------------------------------------------------------------
/java/libraries.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 |
3 | ## Libraries
4 | 1. swagger2
5 | [확인하기](https://lng1982.tistory.com/314)
6 | > API 문서화 / 테스팅 라이브러리
7 |
8 | 2. logback
9 | [확인하기](https://taetaetae.github.io/2017/02/19/logback/)
10 | > 로깅 라이브러리, 성능 좋음, 스프링부트에서 기본 제공중
11 | lombok의 @Slf4j 어노테이션 사용가능
12 |
13 | ~~~java
14 | import com.example.demo.domain.User;
15 | import com.example.demo.repository.UserRepository;
16 | import lombok.AllArgsConstructor;
17 | import lombok.extern.slf4j.Slf4j;
18 | import org.springframework.web.bind.annotation.GetMapping;
19 | import org.springframework.web.bind.annotation.PostMapping;
20 | import org.springframework.web.bind.annotation.RequestMapping;
21 | import org.springframework.web.bind.annotation.RestController;
22 |
23 | @AllArgsConstructor
24 | @RestController
25 | @Slf4j
26 | @RequestMapping("/api/users")
27 | public class ApiUserController {
28 | private final UserRepository userRepository;
29 |
30 | @GetMapping("")
31 | public String getAllUsers(){
32 | return "200 success";
33 | }
34 |
35 | @PostMapping
36 | public User create(String name, String info){
37 | User user = new User(name, info);
38 | try {
39 | return userRepository.save(user);
40 | }catch (RuntimeException ex) {
41 | log.warn(ex.getCause().getMessage());
42 | return user;
43 | }
44 | }
45 | }
46 | ~~~
47 | 3. freemarker
48 | > 템플릿 엔진
49 | 아래는 application.properties 관련 설정
50 | ~~~
51 | spring.freemarker.template-loader-path=classpath:/templates
52 | spring.freemarker.suffix=.ftl
53 | ~~~
54 | pom.xml
55 | ~~~xml
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-starter-freemarker
60 | 2.1.3.RELEASE
61 |
62 |
63 | ~~~
--------------------------------------------------------------------------------
/js/js.md:
--------------------------------------------------------------------------------
1 | ## JavaScript 기본
2 | https://opentutorials.org/course/743/4650
3 |
4 | > 자바스크립트는 본래 웹 페이지를 동적으로 제어하기 위해 만들어진 언어
5 |
6 | ### 1. ECMAScript
7 | 자바스크립트 표준안, ESX 로 표현된다.
8 |
9 | ### 2. Features / Grammar
10 | 1. == 와 ===
11 | - == 은 값이 같은지 비교
12 | - === 은 값, 타입 등이 같은지 모두 비교
13 | - == 은 java 의 equals, === 은 java 의 == 이라고 볼 수 있음
14 |
15 | 2. if / while / for 등 일반적인 조건문 / 반복문 다 있음
16 |
17 | ### 3. Hoisting
18 | > 끌어올리기, 호이스트는 변수의 정의가 범위에 따라 선언과 할당으로 분리되는 것을 말한다.
19 | 함수 내에서 변수가 정의되었다면, 선언이 함수의 최상위로
20 | 함수 밖 전역에서 변수가 정의되었다면, 선언이 전역 context 의 최상위로 변경된다.
21 |
22 | 1. 변수 호이스팅
23 |
24 | **코드로 보자**
25 | ~~~js
26 | // 1)
27 | // 아래의 함수는 에러가 나지 않는다.
28 | function() {
29 | console.log(x);
30 | var x = 100;
31 | }
32 |
33 | // 2)
34 | // 아래와 같이 선언과 할당이 분리되어
35 | // 선언이 최상위 맥락으로 올라가는 것인 Hoist
36 | function() {
37 | var x;
38 | console.log(x);
39 | x = 100;
40 | }
41 | ~~~
42 |
43 | 1번 함수에서는 오류가 나지 않는다 (선언을 자바스크립트 엔진이 가장 최우선으로 해석)
44 | 그러나 값은 100이 아니라 undefined 로 출력된다 (할당은 런타임에 되기 때문)
45 |
46 | 2. 함수 호이스팅
47 | > 함수 선언이 함수 실행보다 뒤에 있더라도 자바스크립트 엔진이 함수 선언을 끌어올린다.
48 | 아래와 같은 상황에서 "foooooo" 는 정상적으로 출력된다.
49 | ~~~js
50 | foo();
51 | function foo() {
52 | console.log("foooooo");
53 | }
54 | // > foooooo
55 | ~~~
56 |
57 | > 그러나 할당의 경우에는 Hoisting 이 안된다는 것을 기억하지
58 | ~~~js
59 | foo();
60 | var foo = function(){
61 | console.log("foooooo");
62 | }
63 | // > Syntax Error!
64 | ~~~
65 |
66 | ### 4. 익명함수와 IIFE (immediately-invoked function expression)
67 |
68 | #### 익명함수
69 | > 이름이 없는 함수, 자바스크립트에서는 이름 없는 함수 리터럴을 변수에도 할당이 가능하다.
70 | ~~~js
71 | const add = function (a, b) { return a + b };
72 | ~~~
73 |
74 | 그러나 아래와 같은 선언은 불가하다.
75 | 선언부가 없으면 이를 사용할 맥락이나 이를 할당해줄 변수가 무조건 필요하다.
76 | *(Hoisting을 할건지, 아니면 지금 바로 쓸껀지)*
77 | ~~~js
78 | function (a, b) { return a + b }
79 | // Uncaught SyntaxError: Unexpected token (
80 | ~~~
81 |
82 | 그래서 익명 함수를 쓰려면 아래 두가지 경우로 쓸 수 있다.
83 | ~~~js
84 | // 1. 변수에 함수 리터럴 할당하기
85 | const add = function (a, b) { return a + b };
86 |
87 | // 2. 즉시 사용하기 (IIFE - 아래 참조)
88 | (function(a, b) { return a + b })(1, 2);
89 | ~~~
90 |
91 | #### IIFE (immediately-invoked function expression)
92 | > 정의와 동시에 즉시 실행되는 함수
93 |
94 | 함수를 즉시 실행시킨다.
95 | IIFE 의 일반적인 형태는 아래와 같다. (함수 리터럴을 괄호로 감싼 형태)
96 | ~~~js
97 | function() {console.log("donsdev")}; // 함수 리터럴
98 | (function() {console.log("donsdev")})(); // IIFE
99 | ~~~
100 |
101 | ### 5. 클로저 (Closure)
102 |
103 | > 이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수를 클로져라고 한다
104 |
105 | 먼저 **일급 함수** 에 대한 이해가 필요하다.
106 | 자바스크립트는 일급 함수를 지원하므로 함수를 변수에 저장하거나, 파라미터를 함수로 넘기고, 함수에서 함수를 반환하는 것이 가능하다.
107 |
108 | 아래를 참고하자
109 |
110 | ~~~js
111 | var global_name = "홍길동";
112 |
113 | function makePrinter() {
114 | var outer_name = "김철수";
115 |
116 | function printName() {
117 | var inner_name = "김영희";
118 | console.log(global_name);
119 | console.log(outer_name);
120 | console.log(inner_name);
121 | }
122 |
123 | return printName;
124 | }
125 |
126 | var print = makePrinter();
127 | print();
128 | ~~~
129 |
130 | 결과
131 | ~~~
132 | 홍길동
133 | 김철수
134 | 김영희
135 | ~~~
136 |
137 | 아래 부분에서 print 변수에 할당된 것이 **클로저** 이다.
138 | ~~~js
139 | var print = makePrinter();
140 | ~~~
141 |
142 | 여기서 포인트는 print() 실행시, outer_name 을 그대로 가지고 출력한다는 것이다.
143 | 따라서 함수 안에 있는 함수인 클로저는 자신을 포함하고 있는 맥락(외부함수)의 인자, 지역변수를 기억하고 있다 라는 것이다. (makePrinter() 를 했는데도 살아있다)
144 | 이러한 변수들을 **자유 변수** 라고 한다.
145 |
146 | 클로저가 생성될 시점, 그 맥락의 지역 변수들을 자유 변수로 만드는 것을 (뭔가 그 상태 그대로 급냉하는 느낌) **캡쳐(capture)** 라고 한다. 이러한 자유변수들은 외부 접근에 의해 참조할 수 없으며, 오직 해당 closure을 이용해서만 접근할 수 있다. 객체 지향의 private 멤버 변수 같은 느낌을 가진다.
147 |
148 | From MDN :
149 | > 클로저는 독립적인 (자유) 변수를 가리키는 함수이다. 또는, 클로저 안에 정의된 함수는 만들어진 환경(Scope)을 ‘기억한다’
150 |
151 | **또 다른 예**
152 |
153 | ~~~js
154 | function getClosure() {
155 | var text = 'variable 1';
156 | return function() {
157 | return text;
158 | };
159 | }
160 |
161 | var closure = getClosure();
162 | console.log(closure()); // 'variable 1'
163 | ~~~
164 |
165 | getClosure 함수는 함수를 반환한다. 그리고 **반환된 함수**는 getClosure 의 스코프에서 선언된 변수를 참조하고 있다. 또한 참조된 변수는 함수 실행이 끝나고 반환되었다고 해서 사라지지 않았고 아래 함수의 사용에서 제대로 된 값을 반환하고 있다.
166 |
167 | 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근 할 수 있다. 이러한 메커니즘을 클로저라고 한다.
168 |
169 | 여기서 반환된 함수가 **클로저** 이다.
170 |
171 | ### 6. var, let, const
172 |
173 | #### 1. var
174 | - function-scoped
175 | > 함수 안까지만 확장되는 스코프
176 | ~~~js
177 | // var 변수가 호이스팅 되어 정상적으로 j가 출력된다.
178 | for(var j=0; j<10; j++) {
179 | console.log('j', j)
180 | }
181 | console.log('after loop j is ', j)
182 | // after loop j is 10
183 |
184 |
185 | // 아래의 경우에는 function 스코프까지만 확장되어
186 | // 함수 밖에서 i 값을 참조할 수 없다.
187 | function counter () {
188 | for(var i=0; i<10; i++) {
189 | console.log('i', i)
190 | }
191 | }
192 | counter()
193 | console.log('after loop i is', i)
194 | // ReferenceError: i is not defined
195 | ~~~
196 |
197 | var은 변수 재선언이 되고, 호이스팅 때문에 아래와 같은 문제가 있었다.
198 | ~~~js
199 | // 이미 만들어진 변수이름으로 재선언했는데 아무런 문제가 발생하지 않는다.
200 | var a = 'test'
201 | var a = 'test2'
202 |
203 | // hoisting으로 인해 ReferenceError에러가 안난다.
204 | c = 'test'
205 | var c
206 | ~~~
207 |
208 | 따라서 생긴것이 let 과 const 이다.
209 | #### 2. let / const
210 | - let 은 변수 재선언이 불가하고, 재할당은 가능하다.
211 | - const 는 재선언 및 재할당 둘다 불가하다.
212 |
213 | let, const가 hoisting이 아예 발생하지 않는것은 아니다.
214 | var이 function-scoped로 hoisting 이 되었다면,
215 | let, const는 block-scoped 단위로 hoisting이 일어난다.
216 |
217 | ~~~js
218 | c = 'test' // ReferenceError: c is not defined
219 | let c
220 | ~~~
221 | 위에 코드에서 ReferenceError가 발생한 이유는 호이스팅이 발생하지 않은 것이 아니라 **tdz(temporal dead zone)** 때문이다.
222 | 또한 const 는 선언과 동시 할당이 필수이다.
223 |
224 | ### 7. ES6 에서 추가된 기능
225 | https://jsdev.kr/t/es6/2944
226 |
227 | ES6 에서 추가된 주요 기능
228 | 1. Arrows (화살표 함수)
229 | ~~~js
230 | var evens = [2, 4, 6, 8,];
231 |
232 | // Expression bodies (표현식의 결과가 반환됨)
233 | var odds = evens.map(v => v + 1); // [3, 5, 7, 9]
234 | var nums = evens.map((v, i) => v + i); // [2, 5, 8, 11]
235 | var pairs = evens.map(v => ({even: v, odd: v + 1})); // [{even: 2, odd: 3}, ...]
236 |
237 | // Statement bodies (블럭 내부를 실행만 함, 반환을 위해선 return을 명시)
238 | nums.forEach(v => {
239 | if (v % 5 === 0)
240 | fives.push(v);
241 | });
242 | ~~~
243 |
244 | 2. Classes
245 | ES6 클래스는 기존 프로토타입 기반 객체지향 패턴을 더 쉽게 사옹할 수 있도록 함
246 |
247 | ~~~js
248 | class SkinnedMesh extends THREE.Mesh {
249 | constructor(geometry, materials) {
250 | super(geometry, materials);
251 |
252 | this.idMatrix = SkinnedMesh.defaultMatrix();
253 | this.bones = [];
254 | this.boneMatrices = [];
255 | //...
256 | }
257 | update(camera) {
258 | //...
259 | super.update();
260 | }
261 | get boneCount() {
262 | return this.bones.length;
263 | }
264 | set matrixType(matrixType) {
265 | this.idMatrix = SkinnedMesh[matrixType]();
266 | }
267 | static defaultMatrix() {
268 | return new THREE.Matrix4();
269 | }
270 | }
271 | ~~~
272 |
273 | 3. Let, Const
274 | - var의 스코프는 전체 외부 함수까지이다.
275 | - let은 변수를 선언한 블록과 그 내부 블록들에서 유효
276 |
277 | 4. Iterator / Generator
278 | https://infoscis.github.io/2018/01/31/ecmascript-6-iterators-and-generators/
279 |
280 | > 많은 프로그래밍 언어는 컬렉션에서 위치를 추적하기 위해 변수가 필요한 for 루프를 사용하여 데이터를 반복하는 것에서 컬렉션의 다음 항목을 반환하는 Iterator 객체를 사용하는 방식으로 전환했다.
281 | Iterator를 사용하면 데이터 컬렉션을 쉽게 처리할 수 있어 ES6 에서는 Iterator를 JavaScript에 추가했습니다.
282 | Iterator는 새로운 Array 메서드 및 새로운 타입의 컬렉션 (Set 및 Map)과 결합하여 데이터를 효율적으로 처리할수 있는 핵심 요소이며, 이러한 부분은 JavaScript의 여러곳에서 찾아볼 수 있다.
283 | 또한 Iterator와 함께 작동하는 새로운 for-of 루프가 있으며, Spread (...) 연산자에서도 Iterator를 사용할 수 있다.
284 | 그리고 Iterator는 비동기 프로그래밍을 더 쉽게 만들수 있게 한다.
285 |
286 |
287 |
288 | 5. Proxy
289 | > Spring AOP 처럼 사용 가능
290 | ~~~js
291 | // Proxying a function object
292 | var target = function () { return 'I am the target'; };
293 | var handler = {
294 | apply: function (receiver, ...args) {
295 | return 'I am the proxy';
296 | }
297 | };
298 |
299 | var p = new Proxy(target, handler);
300 | p() // 'I am the proxy';
301 | ~~~
302 |
303 | 6. Promises
304 | > Promise는 미래에 생성되는 값을 나타내는 일급 객체이다.
305 |
306 | 7. Reflect API
307 | ~~~js
308 | class Greeting {
309 | constructor(name) {
310 | this.name = name;
311 | }
312 |
313 | greet() {
314 | return `Hello ${name}`;
315 | }
316 | }
317 |
318 | function greetingFactory(name) {
319 | return Reflect.construct(Greeting, [name], Greeting);
320 | }
321 |
322 | greetingFactory('a'); // Greeting {name: "a"}
323 | ~~~
--------------------------------------------------------------------------------
/network/network.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 |
3 | ## 1. OSI7 계층
4 | https://kwongyo.tistory.com/7
5 | > 컴퓨터 네트워크 통신과 프로토콜을 계층으로 나누어 설명한 것
6 |
7 | 
8 |
9 | - 각 계층은 하위 계층의 기능만을 이용하고, 상위 계층에게 기능을 제공한다.
10 | - 일반적으로 하위 계층들은 하드웨어로, 상위 계층들은 소프트웨어로 구현된다.
11 | - 네트워크 관리자는 어떤 문제의 원인이 어디에 있는지 범위를 좁힐 수 있다
12 | - 언제나 그렇듯 역할과 책임의 분리 (추상화)
13 | - 각 계층의 전달 단위는 프레임, 패킷, 세그먼트지만 데이터는 같고 헤더 정보만 다르다 (MAC, IP, PORT 등)
14 | - 아레 계층으로 가면서 헤더가 붙는다, application header -> TCP header -> IP header -> Ethernet header ..
15 |
16 | 1. 물리 계층 (Physical Layer)
17 | - 장치와 전송 매체 간에 인터페이스의 특성을 규정한다.
18 | - 비트 스트림으로 상대방에게 송신한다.
19 | - 네트워크 케이블, 주파수 등 연결과 관련된 HW 적인 Feature 이다.
20 | - 전송 단위는 Bit 이다
21 |
22 | 2. 데이터 링크 계층 (Data-link Layer)
23 | - **동일 네트워크 내** 의 노드간 데이터 전송을 나타낸다.
24 | - CRC 기반의 오류, 흐름 제어가 들어간다. (약하게)
25 | - 2계층의 흐름 제이는 두 노드 간 속도만 고려한다.
26 | - 오류 제어는 트레일러를 이용함
27 | - 네트워크 내의 노드 간 구분 주소는 MAC
28 | - Ethernet 헤더에 MAC 주소가 있다.
29 | - 대표적인 데이터링크 계층 프로토콜은 Ethernet
30 | - 저비용 / 비 연결성, 비 신뢰성
31 | - IEEE 802.11 은 이더넷의 단점을 보완 (로컬 site 간의 연결)
32 | - LTE는 재전송도 보장해 준다.
33 | - 데이터 전송 단위는 Frame (Bit -> Frame, Frame -> Bit)
34 |
35 | 3. 네트워크 계층 (Network Layers)
36 | - MAC 주소 가지고는 인터넷 통신불가, **네트워크 간 통신** 이 필요
37 | - 여러개의 노드를 거칠때마다 경로를 찾아주는 역할을 하는 계층 (Routing)
38 | - 라우팅, 흐름 제어, 세그멘테이션(segmentation/desegmentation), 오류 제어, 인터네트워킹(Internetworking)
39 | - 논리적인 주소 구조(IP), 곧 네트워크 관리자가 직접 주소를 할당하는 구조를 가짐
40 | - 데이터 전송 단위는 Datagram(Packet) 이다.
41 |
42 | 4. 전송 계층 (Transport Layer)
43 | - 가장 중요한 특성은 **신뢰성 보장**, 흐름 / 혼잡 / 오류 제어가 가능하다.
44 | - 오류제어는 세그먼트를 재전송 한다.
45 | - 흐름 제어의 경우, 2계층과는 다르게 통신하는 모든 hop을 고려한다.
46 | - 데이터 전송 단위는 Segment 인데, 순서 번호가 포함되어 있어 수신 측에서 조립이 가능하다 (UDP는 안됨)
47 | - TCP Header 에 포트 정보 (프로세스) 가 들어간다.
48 | - 연결은 비연결형 일 수 있고, 연결형 일 수도 있다.
49 | - 가장 잘 알려진 전송 계층의 예는 TCP이다.
50 |
51 | 5. 세션 계층 (Session Layer)
52 | - 사용자 위주의 추상화된 연결서비스 제공
53 | - 연결을 유지하기 위해서는 세션이 필요하다.
54 | - 응용 프로그램간의 대화(세션)을 유지하고 관리
55 | - 전송 모드 결정 (Half-Duplex, Full-Duplex emd)
56 | - 물리적 연결이 아닌 어플리케이션간의 세션을 구축하고 관리한다.
57 |
58 | 6. 표현 계층 (Presentation Layer)
59 | - 응용 계층의 다양한 데이터 형식을 전송형태의 구문으로 변환
60 | - JPEG, TIFF, GIF(그래픽 포맷), MPEG, QUICKTIME(동영상 포맷), MIDI(음악 포맷), RTF, ASCII, EBCDIC(텍스트 포맷)등을 받아들이고 공통 형식으로 반환
61 | - 데이터 암호화 / 데이터 압축 담당
62 |
63 | 7. 응용 계층 (Application Layer)
64 | - 사용자에게 서비스를 제공하며, 하위 계층에 정보나 명령을 전달한다.
65 | - 사용자가 직접 눈으로 보고 실제로 작업을 하는 계층이다.
66 | - telnet, HTTP, FTP, WWW, SMTP, POP
67 |
68 | ## 2. TCP / UDP
69 | > 네트워크 계층 중 전송(Transport) 계층에서 사용하는 프로토콜
70 |
71 | ### 1. TCP
72 | **신뢰성** 보장이 아주 중요한 키워드이다.
73 |
74 |
75 |
76 | - 인터넷 상에서 세그먼트를 보내기 위해 IP와 함께 사용하는 프로토콜이다.
77 | - TCP와 IP를 함께 사용하는데, IP가 주소를 찾아주면 TCP는 흐름 제어, 혼잡 제어 등 신뢰성을 보장한다.
78 | - 흐름제어 (**Host to Host** / 송신측이 수신측보다 과하게 빠른 문제 해결)
79 | - 데이터를 송신하는 곳과 수신하는 곳의 데이터 처리 속도를 조절하여 수신자의 버퍼 오버플로우를 방지하는 것
80 | - 송신하는 곳에서 감당이 안되게 많은 데이터를 빠르게 보내 수신하는 곳에서 문제가 일어나는 것을 막는다.
81 | - 혼잡제어 (**Host to Network** / **네트워크**의 과부하 조절)
82 | - 네트워크 내의 패킷 수가 넘치게 증가하지 않도록 방지하는 것
83 | - 정보의 소통량이 과다하면 패킷을 조금만 전송하여 혼잡 붕괴 현상이 일어나는 것을 막는다
84 | - **연결형 서비스이다**
85 | - 3-way handshaking과정을 통해 연결을 설정하고, 4-way handshaking을 통해 연결을 해제한다.
86 | - https://github.com/WeareSoft/tech-interview/blob/master/contents/network.md#tcp%EC%9D%98-3-way-handshake%EC%99%80-4-way-handshake
87 | - 전이중(Full-Duplex), 점대점(Point to Point) 방식이다.
88 | - 전이중
89 | - 전송이 양방향으로 동시에 일어날 수 있다.
90 | - 점대점
91 | - 각 연결이 정확히 2개의 종단점을 가지고 있다.
92 | - UDP보다 속도가 느리다.
93 |
94 | #### 흐름제어와 혼잡제어 방법
95 |
96 | 1. 흐름제어
97 |
98 | 1. Stop And Wait
99 |
100 | > 매번 전송한 패킷에 대해 확인응답을 받아야 다음 패킷 전송
101 |
102 | 2. Sliding Window
103 |
104 | > 수신측 응답에 따라 윈도우 (버퍼) 를 이용하여 흐름을 제어한다.
105 |
106 |
107 | ### 2. UDP
108 | **비연결형 프로토콜** 이라는 점에 주목
109 |
110 |
111 |
112 | - 4계층 프로토콜이긴 한데 IP만 보고 움직임
113 | - 패킷 단위로 전송
114 | - TCP 처럼 연결형이 아니라, 데이터 순서 보장 X (지맘대로 감)
115 | - 그대신 빠름 (스트리밍에 적합)
116 | - UDP헤더의 CheckSum 필드를 통해 최소한의 오류만 검출한다.
117 | - 흐름제어(flow control)가 없어서 패킷이 제대로 전송되었는지, 오류가 없는지 확인할 수 없다. (성능 중시)
118 |
119 | ## 3. 3-way handshake / 4-way handshake
120 | ### 1. 3-way handshake (연결 시작)
121 |
122 | 
123 |
124 | 1. A : SYN (포트 열어라 새끼야)
125 | 2. B : ACK (알겠어), SYN (근데 너도 포트 열어)
126 | 3. A : ACK (OK 나도 열었어)
127 |
128 | ### 2. 4-way handshake (연결 종료)
129 |
130 | 
131 |
132 | 1. A : FIN (얀결 끊자)
133 | 2. B : ACK (OK, 끊자는 메시지 받았어) ... 일 처리하던거 마무리
134 | 3. A : ... 대기중
135 | 4. B " FIN (나 연결 끊었어)
136 | 5. A : ACK (OK 나도 좀만 기다리다 끊을게)
137 | 6. A : TIME WAIT
138 |
139 | ## 4. HTTP
140 | > HTTP => Hyper Text Transfer Protocol
141 | 인터넷에서 데이터를 주고받을 수 있는 프로토콜,
142 | 웹 서버와 클라이언트 간의 통신을 하기 위한 통신 규약
143 |
144 | ### 1. 주요 특징
145 | - HTTP 는 웹에서만 사용하는 프로토콜이며, TCP/IP 기반이다.
146 | - HTTP는 비연결성 프로토콜이다
147 | - 비연결성의 단점보완을 위해 Cookie와 Session 등장
148 | - 응답은 html 뿐 아니라 json, xml 등으로도 받을 수 있다.
149 |
150 | ### 2. HTTP Method
151 | 1. GET
152 | - 데이터가 URL에 노출된다.
153 | ~~~
154 | www.urladdress.xyz?name1=value1&name2=value2
155 | ~~~
156 | - **무언가를 가져오는 요청 (select), 상태변화 X**
157 | - HTTP 패킷의 Body는 비어 있는 상태로 전송한다.
158 | 즉, Body의 데이터 타입을 표현하는 'Content-Type' 필드도 HTTP Request Header에 들어가지 않는다.
159 | - 브라우저 캐싱을 지원하여 빠르다
160 |
161 | 2. POST
162 | - 요청 정보를 HTTP 패킷의 Body 안에 숨겨서 서버로 전송한다.
163 | - **서버의 값이나 상태를 바꾸기 위한** 용도의 메서드
164 | - Insert, Update, Delete
165 | - Request Header의 Content-Type에 해당 데이터 타입이 표현됨
166 | application/octet-stream , text/plain, multipart/form-data 등
167 |
168 | 3. HEAD
169 | - Get Response 헤더 정보만 받아오겠다.
170 | - 특정 리소스를 GET 으로 요청하는 경우에 어떤 헤더들이 반환되는지를 요청
171 | - 예를 들어, 큰 용량의 리소스를 다운로드 받을지 말지 결정하기 위해서 사전 요청하는 용도로 사용할 수 있습니다.
172 |
173 | 4. PUT
174 | - 요청된 자원을 수정(UPDATE) 및 생성(CREATE) 한다
175 | - 정확히는 멱등함수와 비슷하게, 지정 위치에 덮어쓰는 느낌이다. (없으면 삽임한다)
176 | - 자원내 모든 필드영역 업데이트 (DB 1 ROW 전체 수정)
177 | - 만약 일부만 전달할 경우, 그외의 필드 모두 null or 초기값 처리
178 | - 따라서 PUT 잘못쓰면 골로간다
179 | - 보안 위협
180 |
181 | 5. PATCH
182 | - PUT과 유사하게 요청된 자원을 수정(UPDATE)할 때 사용한다.
183 | - PUT의 경우 자원 전체를 갱신하는 의미지만, PATCH는 해당자원의 일부를 교체하는 의미로 사용.
184 |
185 | 6. DELETE
186 | - 자원 삭제
187 | - 보안 위협
188 |
189 | 7. OPTIONS
190 | - 요청한 URL이 어떤 http 메서드를 지원 하는지 체크할 때 사용한다
191 | - response 헤더에 Allow 에 가능한 메서드가 적혀온다
192 | - 보안 위협
193 |
194 | 8. TRACE
195 | - 받은 메시지를 다시 돌려보낸다.
196 |
197 | 9. CONNECT
198 | - 프록시에 사용하기 위해 예약된 메서드이다
199 | - 프록시 서버의 기본적인 동작은 클라이언트로부터 전달받은 리퀘스트를 서버로 전달하고, 서버에서 받은 응답을 클라이언트에 전달하는 역할을 한다.
200 | - 프록시의 사용 목적은 네트워크 캐싱, 조직내의 특정 웹사이트 액세스 방지, 액세스 로그 획득 등이 있다.
201 |
202 | ### 3. HTTP Request / Response 헤더
203 | > 요청의 경우 일단 헤더 앞에는 `GET / HTTP/1.1` 이런식으로 적혀있다.
204 | 응답의 경우 헤더 앞에는 `HTTP/1.1 200 OK` 라고 적혀있음
205 | - HTTP 헤더 - 일반 헤더 (General Header)
206 | - 요청 및 응답 메시지 모두에서 사용 가능한 일반 목적의(기본적인) 헤더 항목
207 | - 주요 항목
208 | - **Date**: HTTP 메시지를 생성한 일시
209 | - `Date: Sat, 2 Oct 2018 02:00:12 GMT`
210 | - **Connection**: 클라이언트와 서버 간 연결에 대한 옵션 설정
211 | - `Connection: close` => 현재 HTTP 메시지 직후에 TCP 접속을 끊는다는 것을 알림
212 | - `Connection: Keep-Alive` => 현재 TCP 커넥션을 유지
213 | - **Cache-Control**
214 | - `Cache-Control: no-store` => 캐시 안쓴다
215 | - `Cache-Control: no-cache` => 모든 캐시를 쓰기 전에 서버에 이 캐시 진짜 써도 되냐 물어보라는 뜻
216 | ... 이 외에도 몇가지 있음
217 | - **Pragma**
218 | - http 1.0 레거시, 캐시 컨트롤이랑 같음
219 | - **Trailer**
220 | - http 헤더 뒤에 임의 추가 가능
221 | ~~~
222 | HTTP/1.1 200 OK
223 | Content-Type: text/plain
224 | Transfer-Encoding: chunked
225 | Trailer: Expires
226 | 7\r\n
227 | Mozilla\r\n
228 | 9\r\n
229 | Developer\r\n
230 | 7\r\n
231 | Network\r\n
232 | 0\r\n
233 | Expires: Wed, 21 Oct 2015 07:28:00 GMT\r\n
234 | \r\n
235 | ~~~
236 | - HTTP 헤더 - 엔터티 헤더 (Entity Header)
237 | - 요청 및 응답 메시지 모두에서 사용 가능한 Entity(콘텐츠, 본문, 리소스 등)에 대한 설명 헤더
238 | - 주요 항목들
239 | - **Content-Type**: 해당 개체에 포함되는 미디어 타입 정보
240 | - 컨텐츠의 타입(MIME 미디어 타입) 및 문자 인코딩 방식(EUC-KR,UTF-8 등)을 지정
241 | - 타입 및 서브타입(type/subtype)으로 구성
242 | - `Content-Type: text/html; charset-latin-1` => 해당 개체가 html으로 표현된 텍스트 문서이고, iso-latin-1 문자 인코딩 방식으로 표현됨
243 | - **Content-Language**: 해당 개체와 가장 잘 어울리는 사용자 언어(자연언어)
244 | - **Content-Encoding**: 해당 개체 데이터의 압축 방식
245 | - `Content-Encoding: gzip, deflate`
246 | - 만일 압축이 시행되었다면, Content-Encoding 및 Content-Length 2개 항목을 토대로 압축 해제 가능
247 | - **Content-Length**: 전달되는 해당 개체의 바이트 길이 또는 크기(10진수)
248 | - **Content-Location**: 해당 개체가 실제 어디에 위치하는가를 알려줌
249 | - **Content-Disposition**: 응답 Body를 브라우저가 어떻게 표시해야 할지 알려주는 헤더
250 | - inline인 경우 웹페이지 화면에 표시되고, attachment인 경우 다운로드
251 | - `Content-Disposition: inline`
252 | - `Content-Disposition: attachment; filename='filename.csv'`
253 | - **Content-Security-Policy**: 다른 외부 파일들을 불러오는 경우, 차단할 소스와 불러올 소스를 명시
254 | - *XSS 공격*에 대한 방어 가능 (허용한 외부 소스만 지정 가능)
255 | - `Content-Security-Policy: default-src https:` => https를 통해서만 파일을 가져옴
256 | - `Content-Security-Policy: default-src 'self'` => 자신의 도메인의 파일들만 가져옴
257 | - `Content-Security-Policy: default-src 'none'` => 파일을 가져올 수 없음
258 | - **Location**: 리소스가 리다이렉트(redirect)된 때에 이동된 주소, 또는 새로 생성된 리소스 주소
259 | - 300번대 응답이나 201 Created 응답일 때 어느 페이지로 이동할지를 알려주는 헤더
260 | - 새로 생성된 경우에 HTTP 상태 코드 `201 Created`가 반환됨
261 | - `HTTP/1.1 302 Found Location: /`
262 | - 이런 응답이 왔다면 브라우저는 / 주소로 redirect한다.
263 | - **Last-Modified**: 리소스를 마지막으로 갱신한 일시
264 | - HTTP 헤더 내 요청 헤더 (Request Header) 항목
265 | - 요청 헤더는 HTTP 요청 메시지 내에서만 나타나며 가장 방대하다.
266 | - 주요 항목들
267 | - **Host**: 요청하는 호스트에 대한 호스트명 및 포트번호 (***필수***)
268 | - Host 필드에 도메인명 및 호스트명 모두를 포함한 전체 URI(FQDN) 지정 필요
269 | - 이에 따라 동일 IP 주소를 갖는 단일 서버에 여러 사이트가 구축 가능
270 | - **User-Agent**: 클라이언트 소프트웨어(브라우저, OS) 명칭 및 버전 정보
271 | - **From**: 클라이언트 사용자 메일 주소
272 | - 주로 검색엔진 웹 로봇의 연락처 메일 주소를 나타냄
273 | - 때로는, 이 연락처 메일 주소를 User-Agent 항목에 두는 경우도 있음
274 | - **Cookie**: 서버에 의해 Set-Cookie로 클라이언트에게 설정된 쿠키 정보
275 | - **Referer**: 바로 직전에 머물었던 웹 링크 주소
276 | - **If-Modified-Since**: 제시한 일시 이후로만 변경된 리소스를 취득 요청
277 | - **Authorization**: 인증 토큰(JWT/Bearer 토큰)을 서버로 보낼 때 사용하는 헤더
278 | - 토큰의 종류(Basic, Bearer 등) + 실제 토큰 문자를 전송
279 | - **Origin**
280 | - POST 요청 주소
281 | - 여기서 요청을 보낸 주소와 받는 주소가 다르면 **CORS 에러** 가 발생
282 | - 응답 헤더의 **Access-Control-Allow-Origin**와 관련
283 | - 다음 4개는 주로 HTTP 메세지 Body의 속성 또는 내용 협상용 항목들
284 | - **Accept**: 클라이언트 자신이 원하는 미디어 타입 및 우선순위를 알림
285 | - `Accept: */*` => 어떤 미디어 타입도 가능
286 | - `Accept: image/*` => 모든 이미지 유형
287 | - **Accept-Charset**: 클라이언트 자신이 원하는 문자 집합
288 | - **Accept-Encoding**: 클라이언트 자신이 원하는 문자 인코딩 방식
289 | - **Accept-Language**: 클라이언트 자신이 원하는 가능한 언어
290 | - 각각이 HTTP Entity Header 항목 중에 `Content-Type, Content-Type charset-xxx, Content-Encoding, Content-Language`과 일대일로 대응됨
291 | - HTTP 헤더 내 응답 헤더 (Response Header) 항목
292 | - 특정 유형의 HTTP 요청이나 특정 HTTP 헤더를 수신했을 때, 이에 응답한다.
293 | - 주요 항목들
294 | - **Server**: 서버 소프트웨어 정보
295 | - **Accept-Range**
296 | - **Set-Cookie**: 서버측에서 클라이언트에게 세션 쿠키 정보를 설정 (RFC 2965에서 규정)
297 | - **Expires**: 리소스가 지정된 일시까지 캐시로써 유효함
298 | - **Age**: 캐시 응답. max-age 시간 내에서 얼마나 흘렀는지 알려줌(초 단위)
299 | - **ETag**: HTTP 컨텐츠가 바뀌었는지를 검사할 수 있는 태그
300 | - **Proxy-authenticate**
301 | - **Allow**: 해당 엔터티에 대해 서버 측에서 지원 가능한 HTTP 메소드 리스트
302 | - 때론, HTTP 요청 메세지의 HTTP 메소드 OPTIONS에 대한 응답용 항목
303 | - OPTIONS: 웹서버측 제공 HTTP 메소드에 대한 질의
304 | - `Allow: GET,HEAD` => 웹 서버측이 제공 가능한 HTTP 메서드는 GET,HEAD 뿐임을 알림 (405 Method Not Allowed 에러와 함께)
305 | - **Access-Control-Allow-Origin**: 요청을 보내는 프론트 주소와 받는 백엔드 주소가 다르면 *CORS 에러*가 발생
306 | * 서버에서 이 헤더에 프론트 주소를 적어주어야 에러가 나지 않는다.
307 | * `Access-Control-Allow-Origin: www.zerocho.com`
308 | * 프로토콜, 서브도메인, 도메인, 포트 중 하나만 달라도 CORS 에러가 난다.
309 | * `Access-Control-Allow-Origin: *`
310 | * 보안 박살
311 | * 유사한 헤더로 `Access-Control-Request-Method, Access-Control-Request-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Headers` 등이 있다.
312 | ### 4. HTTP Keep-Alive
313 | HTTP 는 비연결 방식으로 연결을 매번 만들고 끊는 구조이다.
314 | 이는 많은 비용이 드므로, HTTP 1.1 부터는 Keep-Alive (연결 유지) 를 제공한다.
315 |
316 | - HTTP/1.1부터 지원하는 기능으로 TCP 연결을 재사용하는 기능이다.
317 | - Handshake 과정이 생략되므로 성능 향상을 기대 할 수 있다 (TCP 소켓 세션 유지)
318 | - 모든 TCP 세션을 무한정 유지할 수는 없으므로 Timeout 및 Max 설정을 통해 관리되어야 한다.
319 | - 연결된 Socket에 IO 의 Access가 마지막으로 종료된 시점부터
320 | 정의된 시간까지 Access가 없더라도 세션을 유지하는 구조이다.
321 | - 정의된 시간내에 Access가 이루어진다면 계속 연결된 상태를 유지할 수 있게 된다.
322 |
323 | ### 5. HTTP Status Code
324 |
325 | #### 100 - 199 : 정보성 상태 코드
326 |
327 | - 100 : 요청의 시작 부분 일부가 받아들여졌으며, 클라이언트는 나머지를 계속 이어서 보내야 함을 의미함
328 |
329 | - 101 : 요청자가 서버에 프로토콜 전환을 요청했으며, 서버에서 이를 승인하는 중을 의미함
330 |
331 | #### 200 - 299 : 성공 상태 코드
332 | 클라이언트가 요청을 보내면, 요청은 대게 성공함. 서버는 대응하는 성공을 의미하는 각각의 요청에 대응한다.
333 |
334 | - 200 : 요청은 정상이고, 본문은 요청된 리소스를 포함하고 있다. (OK)
335 |
336 | - 201 : 어떠한 생성 작업을 요청받았으며, 생성 작업을 성공하였다. (CREATED)
337 |
338 | - 202 : 요청은 받아들여졌으나, 아직 동작을 수행하지 않은 상태로 요청이 적절함을 의미함
339 |
340 | - 203 : 요청을 성공하였지만, 요청에 대한 검증이 되지 않은 상태를 의미함
341 |
342 | - 204 : 요청을 성공하였지만, 제공할 내용이 없음을 의미
343 |
344 | - 205 : 204와 동일하지만 새로고침등을 통해 새로운 내용등을 확인할것을 추가로 의미
345 |
346 | - 206 : 요청의 일부분만 성공하였음을 의미
347 |
348 | #### 300 - 399 : 리다이렉션 상태 코드
349 | 클라이언트에 요청에 대해 적절한 다른 위치를 제공하거나, 대안의 응답을 제공한다.
350 |
351 | - 300 : 클라이언트가 동시에 여러 응답을 가리키는 URL을 요청한 경우 응답 목록과 함께 반환된다.(ex] 어떠한 HTML에 문서에 대한 영문페이지와 불어페이지를 요청)
352 |
353 | - 301 : 요청한 URL이 옮겨졌을 때 사용. 옮겨진 URL에 대한 정보와 함께 응답되어야 한다.
354 |
355 | - 302 : 301과 동일하나, 클라이언트는 여전히 옮겨지기전 URL로 요청할것을 의미
356 |
357 | - 303 : 요청받은 행동 수행을 위해서는 다른 URL로 요청 해야함을 의미
358 |
359 | - 304 : 이전의 동일한 요청과 비교하여 변화가 없음을 의미 (단시간에 반복된 동일 요청에 대한 대응 코드)
360 |
361 | - 305 : 직접적인 요청이 아니라 반드시 프락시(우회경로)를 통해 요청되어야 함을 의미
362 |
363 | - 307 : 302와 동일하며, HTTP Method도 변경없이 요청하여야 함을 의미
364 |
365 | #### 400 - 499 : 클라이언트 에러 상태 코드
366 | 클라이언트의 잘못된 요청에 대한 대응 코드
367 |
368 | - 400 : 클라이언트가 올바르지 못한 요청을 보내고 있음을 의미 (BAD REQUEST)
369 |
370 | - 401 : 요청을 위해서는 권한 인증등을 요구함을 의미 (NOT AUTHORIZED)
371 |
372 | - 403 : 요청이 서버에 의해 거부 되었음을 의미 (FORBIDDEN)
373 |
374 | - 404 : 요청한 URL을 찾을 수 없음을 의미 (NOT FOUND)
375 |
376 | - 405 : 요청한 URL이 Method를 지원하지 않음을 의미 (ex] POST요청에 대한 응답을 하는 URL에 GET으로 요청) (NOT ALLOWED)
377 |
378 | #### 500 - 599 : 서버 에러 상태 코드
379 | 올바른 클라이언트 요청에 대해 서버의 문제로 응답 할 수 없음을 의미
380 |
381 | - 500 : 서버에 오류가 발생하여 응답 할 수 없음을 의미
382 |
383 | - 501 : 클라이언트 요청에 대한 서버의 응답 수행 기능이 없음을 의미
384 | (ex : 서버가 지원하지 않는 새로운 Method를 사용하여 요청 - GET2, POST2...)
385 |
386 | - 502 : 프락시나 게이트웨이등의 서버에서 응답하며, 서버의 모(엄마)서버에서 오류가 발생하였음을 의미
387 |
388 | - 503 : 현재 서버가 유지보수 등의 이유로 일시적인 사용 불가함을 의미
389 |
390 | - 504 : 서버에서 다른 서버로 요청을 보냈으나, 응답 지연이 발생하여 처리가 불가함을 의미
391 |
392 | - 505 : 서버가 지원할 수 없거나 올바르지 못한 프로토콜로 요청을 받았음을 의미
393 |
394 | ### 6. CORS란 (Cross Origin Resource Sharing)
395 | > 웹 서버에게 보안 cross-domain 데이터 전송을 활성화하는 cross-domain 접근 제어권을 부여한다.
396 | - 배경
397 | - 처음 전송되는 리소스의 도메인과 다른 도메인으로부터 리소스가 요청될 경우 해당 리소스는 cross-origin HTTP 요청에 의해 요청된다.
398 | - 보안 상의 이유로, 브라우저들은 스크립트 내에서 초기화되는 cross-origin HTTP 요청을 제한한다.
399 | - 예를 들면, XMLHttpRequest는 same-origin 정책을 따르기에 XMLHttpRequest을 사용하는 웹 애플리케이션은 자신과 동일한 도메인으로 HTTP 요청을 보내는 것만 가능했다.
400 | - 웹 애플리케이션을 개선시키기 위해, 개발자들은 브라우저 벤더사들에게 XMLHttpRequest가 cross-domain 요청을 할 수 있도록 요청했고 이에 따라 CORS가 생겼다.
401 | - 과정
402 | - CORS 요청 시에는 미리 OPTIONS 주소로 서버가 CORS를 허용하는지 물어본다.
403 | - 이때 Access-Control-Request-Method로 실제로 보내고자 하는 메서드를 알리고,
404 | - Access-Control-Request-Headers로 실제로 보내고자 하는 헤더들을 알린다.
405 | - Allow 항목들은 Request에 대응되는 것으로, 서버가 허용하는 메서드와 헤더를 응답하는데 사용된다. (preflight)
406 | - Request Header 의 Origin과 Allow가 일치하면 CORS 요청이 이루어진다.
407 |
408 | > - [https://zamezzz.tistory.com/137](https://zamezzz.tistory.com/137)
409 |
410 | ### 7. HTTPS / HTTP2
411 | #### 1. HTTPS
412 | > HyperText Transfer Protocol over Secure Socket Layer
413 |
414 | - HTTPS는 소켓 통신에서 일반 텍스트를 이용하는 대신에, 웹 상에서 정보를 암호화하는 SSL이나 TLS 프로토콜을 통해 세션 데이터를 암호화한다.
415 |
416 | - HTTPS의 원리
417 | - 공개키 알고리즘 (공개키는 암호화에, private 키는 복호화에)
418 | 1. 사용자의 데이터를 공개키로 암호화 (공개키를 얻은 인증된 사용자)
419 | 2. 서버로 전송 (데이터를 가로채도 개인키가 없으므로 복호화할 수 없음)
420 | 3. 서버의 개인키를 통해 복호화하여 요청 처리
421 |
422 | - 사용자 인증 방법
423 | - 클라이언트가 서버에 접속한 직후에, 서버는 클라이언트에게 이 인증서 정보를 전달한다. 클라이언트는 이 인증서 정보가 신뢰할 수 있는 것인지를 검증 한 후에 다음 절차를 수행하게 된다 (SSL 인증서에 공개키 포함)
424 | - 그리고 SSL 인증서 안에는 CA (인증서 발급 조직) 가 있는데, 브라우저가 미리 CA 리스트를 파악하고 있고, 여기에 있는 것이 공인된 CA 다.
425 |
426 | #### 2. HTTP2
427 | > 웹 페이지 로드 시 리소스가 예전에 비해 많이 커지면서 이에대한 부분을 더 효율적으로 만들어주는데 초점을 맞춤
428 |
429 | 1. Binary Framework
430 |
431 |
432 |
433 | - 기존 text 기반 Header 와 Body 대신 HTTP/2 는 전송에 필요한 메시지들을 Binary 단위로 구성하여 더 작은 프레임으로 쪼개서 관리하고 송신한다.
434 |
435 | 기존에 텍스트 기반으로 Header 와 Data 가 연결되고 있던 1.1 이하 버전과 다르게 HTTP/2 는 전송에 필요한 메시지들을 Binary 프레임 단위로 구성하며 필요 정보를 더 작은 프레임으로 쪼개서 관리한다.
436 |
437 | 2. Multiplexing 개선
438 | - 멀티플렉싱이란 한 connection 에서 여러개의 요청을 동시에 송/수신 할 수 있도록 하는 것
439 | - 기존 HTTP/1.x 에서는 순차 전송하거나 병렬 요청 응답을 위해서는 여러 연결이 필요했음
440 |
441 |
442 |
443 | VS
444 |
445 |
446 |
447 | 이것이 가능한 이유는 HTTP2 는 패킷을 Frame 단위로 세분화하여 순서에 상관없이 받는쪽에서 ***조립*** 하도록 설계하였기 때문이다
448 |
449 | 3. Header Compression
450 | 헤더 압축 지원
451 |
452 | 4. Server Push
453 |
454 |
455 |
456 | - HTTP/1.1에서 클라이언트는 요청한 HTML 문서를 수신한 후 HTML 문서를 해석하면서 필요한 리소스를 재 요청한다.
457 |
458 | - 그러나 HTTP/2에선 Server Push기법을 통해서 클라이언트가 요청하지도 않은 (HTML문서에 포함된 리소스) 리소스를 서버가 직접 Push 해주는 방법으로 클라이언트의 요청을 최소화 해서 성능 향상을 이끌어 낸다. **이벤트 기반**으로 동작한다.
459 |
460 |
461 | ### 5. HTTP **VS** Socket
462 | #### HTTP
463 | - Half Duplex
464 | - 서버 - 클라이언트간 상태를 유지하지 않는다.
465 | - 따라서 서버 요청 처리후 다시 TCP Connection 을 맺어주어야 함
466 | - 요청 - 응답 - close (keep alive 가능)
467 |
468 | #### TCP Socket
469 | - 요청 - 응답 - 요청 - 응답 - 강제종료
470 |
471 | ## 5. 쿠키와 세션
472 | - HTTP 프로토콜에서 상태를 유지하기 위한 기술로 쿠키와 세션이 있다.
473 | ### 쿠키 (Cookie)
474 | - 클라이언트에 저장되는 Key, Value
475 | - 이름, 값, 유호 시간, 경로 등을 포함하고 있다.
476 | - 클라이언트의 상태 정보를 브라우저에 저장하여 참조한다.
477 |
478 | #### 구성 요소
479 | - 쿠키의 이름(name)
480 | - 쿠키의 값(value)
481 | - 쿠키의 만료시간(Expires)
482 | - 쿠키를 전송할 도메인 이름(Domain)
483 | - 쿠키를 전송할 경로(Path)
484 | - 보안 연결 여부(Secure)
485 | - HttpOnly 여부(HttpOnly)
486 |
487 |
488 |
489 | ### 세션 (Session)
490 | 1. 웹브라우저가 서버에 Request
491 | 2. 서버가 해당 웹브라우저(클라이언트)에 유일한 ID(Session ID)를 부여함
492 | 3. 서버가 응답할 때 HTTP 헤더(Set-Cookie)에 Session ID를 포함해서 전송
493 | 4. 쿠키에 Session ID를 JSESSIONID 라는 이름으로 저장
494 | `Set−Cookie: JSESSIONID=xslei13f`
495 | 5. 웹브라우저는 웹브라우저를 닫기까지 다음 요청 때 부여된 Session ID가 담겨있는 쿠키를 HTTP 헤더에 넣어서 전송
496 | `Cookie: JSESSIONID=xslei13f`
497 | 6. 서버는 세션 ID 기반으로 응답
498 |
499 | ### 쿠키와 세션의 차이점
500 | #### 1. 저장 위치
501 | 쿠키 : 클라이언트
502 | 세션 : 서버
503 | #### 2. 보안
504 | 쿠키 : 클라이언트에 저장되므로 보안에 취약하다.
505 | 세션 : 쿠키를 이용해 Session ID 만 저장하고 이 값으로 구분해서 서버에서 처리하므로 비교적 보안성이 좋다.
506 | #### 3. 라이프사이클
507 | 쿠키 : 만료시간에 따라 브라우저를 종료해도 계속해서 남아 있을 수 있다.
508 | 세션 : TimeOut 도 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제된다.
509 | #### 4. 속도
510 | 쿠키 : 클라이언트에 저장되어서 서버에 요청 시 빠르다.
511 | 세션 : 실제 저장된 정보가 서버에 있으므로 서버의 처리가 필요해 쿠키보다 느리다.
512 |
513 | ## 6. 주소창에 URL 입력 시 일어나는 일들
514 | 1. 브라우저의 url 파싱
515 | ~~~java
516 | http: // 통신 규약
517 | www.example.com =//주소
518 | :80 // 포트, 입력 x 시 표준 HTTP 포트 [http 80, https 443] 사용
519 | /path/to/myfile.html // 웹 서버에서 자원에 대한 경로 (라우팅)
520 | ?key1=value1&key2=value2 (파라미터)
521 | ~~~
522 |
523 | 2. DNS 서버 검색
524 | 1. 브라우저 캐시에 남아 있으면, 바로 해당되는 서버 IP를 반환하고
525 | 2. ISP의 DNS 해석기에게 주소를 해석하여 IP로 반환시킨다
526 |
527 | 3. ARP Request (2계층 Data-Link)
528 | 1. IP 주소로는 해당 지역 라우터까지 접근 가능
529 | **라우터** 에서는 IP 주소에 해당하는 컴퓨터가 누군지 알아내기 위해 MAC 주소가 필요
530 | 2. 클라이언트는 가장 먼저 ARP 캐시에 확인
531 | 3. 캐시 (ARP 테이블) 에 없다면 ARP요청 패킷을 해당 IP 라우터에 브로드캐스트로 전송
532 | 4. 해당되는 수신자만 자신의 논리주소와 물리주소를 넣어 응답 패킷을 유니캐스트로 전송
533 |
534 | 4. TCP Connection (Client -> Server)
535 | - 네트워크 4계층 (Transport, ip와 port 기반 TCP 소켓 연결)
536 |
537 | - 소켓은 통신을 원하는 프로세스에 할당되는 자원이며 서로다른 site의 두 프로세스가 네트워크를 통해 서로 통신할 수 있는 통신 접속점 (포트 기반)
538 | - 아래는 TCP/IP 4계층
539 |
540 |
541 | 1. 3 way handshake (연결)
542 | 2. 4 way handshake (해제)
543 |
544 | 5. http Request 송신
545 | - http 메시지 송신 (GET, POST 등 메서드 / 수신자 / 요청 자원 등 포함)
546 |
547 | 6. 서버 처리 (웹 서버, 웹 어플리케이션 서버)
548 | - Tomcat 같은 서블릿 컨테이너가 받아서 동적 처리
549 | - 서블릿 doGet doPost .. 디스패쳐서블릿 .. 페이지 컨트롤러 - 비즈로직 - 뷰리졸버
550 | 7. TCP Connection (Server -> Client)
551 |
552 | 8. 서버 측 http Response 송신
553 |
554 | 9. 클라이언트는 http Response 를 받아서 사용자에게 노출
555 |
556 | ## 7. REST
557 | https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
558 |
559 | **Representational State Transfer**
560 | > **URI(Uniform Resource Identifier)** 를 통해 **자원(Resource)** 을 명시하고, HTTP Method (POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 **행위(CRUD operation)** 을 명시하고 표현(html, json ...) 하는 것
561 |
562 | **무언가를 지우는 일**
563 | ~~~
564 | post/delete/1
565 | ~~~
566 | 이렇게 쓰는것이 아니라 헤더에 method 를 명시하고
567 | ~~~
568 | post/1
569 | ~~~
570 | 이렇게 지우는 행위를 표현하는 것이 RESTful
571 |
572 |
573 | ## 8. 소켓 / 전문 통신
574 |
575 | ### 1. 소켓
576 | > 두 프로세스간 네트워크를 통해 통신을 수행할 수 있도록 양쪽에 생성되는 링크의 단자
577 | 네트워크 4계층 (Transport)의 TCP/IP와 관련되어 있음 (연결형 서비스)
578 | - TCP : 패킷 전달 규약 (전달받은 패킷 재조립, 손상 시 재전송 받음 - 흐름제어)
579 | - IP : TCP는 경로에 대한 규약은 아니기 때문에 라우팅 관련 IP와 같이 사용됨
580 | - 통신을 위해서는 즉, 라우팅을 위한 IP와 프로세스간 구분을 위한 PORT가 필요함
581 |
582 | ### 2. 전문
583 | > Fixed Length Format
584 | https://downman.tistory.com/153?category=669234
585 | - Parsing은 안해도 됨 / 바이너리 데이터로 송수신
586 | - fixed length format 이란 전문을 구성하는 field 들의 길이가 입력받을 수 있는 최대사이즈로 고정시키는 방식
587 | > ex) 이름은 최대 32byte 까지, 주소는 100byte 까지 항목의 길이를 fix 시키는 것
588 | **자바에서는 Fixed Length 를 구현하는것이 다소 까다로움 C언어 같은 struct 자료구조를 제공하지 않기 때문에, 아래와 같은 방식으로 진행해야 한다.**
589 | https://cofs.tistory.com/282
590 | 1. 수신한 바이너리 데이터를 byte 배열로 할당
591 | 2. 미리 정의된 프로토콜에 따라 데이터의 위치를 찾아서 원하는 부분에 활용
592 |
593 | ### 3. 스프링에서의 소켓통신 구현
594 | #### 클라이언트
595 | ~~~java
596 | public void clientSocket(byte[] data) {
597 | try {
598 | //IP주소와 포트번호를 입력하여 Socket 통신을 시작합니다.
599 | Socket sock = new Socket("127.0.0.1", 8200);
600 |
601 | //Socket으로부터 outputStream을 얻습니다.
602 | OutputStream os = sock.getOutputStream();
603 |
604 | //등록한 OutputStream을 DataOutputStream 방식으로 사용
605 | DataOutputStream dos = new DataOutputStream(os);
606 |
607 | //byte[] 파일을 object 방식으로 통째로 전송합니다.
608 | oos.write(data);
609 |
610 | // 스트림과 소켓은 잘 닫아준다.
611 | oos.close();
612 | os.close();
613 | sock.close();
614 |
615 | } catch (SocketTimeoutException e){
616 |
617 | // 타임아웃 되었을때
618 | timeoutErrorHandler(e);
619 |
620 | } catch (IOException e) {
621 |
622 | // IOException 처리는 강제한다.
623 | e.printStackTrace();
624 | }
625 |
626 | }
627 |
628 | ~~~
629 |
630 | #### 서버
631 | ~~~java
632 | public static void serverSocketListener (){
633 | int port = 8200;
634 | //Server측에서 사용할 포트번호를 설정한 후 Socket 서버 개방
635 | ServerSocket sock = new ServerSocket(port);
636 |
637 | //Client로부터 소켓 신호를 기다림
638 | Socket socket = sock.accept();
639 |
640 | //Socket로부터 InputStream을 등록
641 | InputStream is = socket.getInputStream();
642 |
643 | //등록한 InputStream을 DataInputStream방식으로 사용
644 | DataInputStream dis = new DataInputStream(is);
645 |
646 | //미리 데이터를 수신할 버퍼 생성
647 | byte[] buffer = new byte[1156];
648 |
649 | //미리 지정해 놓은 버퍼에 전송된 byte[] 데이터를 수신
650 | dis.readFully(buffer);
651 |
652 | dis.close();
653 | is.close();
654 | socket.close();
655 | sock.close();
656 | }
657 |
658 | ~~~
659 |
660 |
661 | - **DataInputStream / DataOutputStream**
662 | https://docs.oracle.com/javase/6/docs/api/java/io/DataInputStream.html
663 |
664 | 1. 외부 라이브러리가 아니라 자바의 스탠다드 라이브러리다
665 |
666 | 2. DataInputStream 을 사용하면 애플리케이션이 기계에 독립적인 방법으로 기본 입력 스트림에서 원시 Java 데이터 유형을 읽을 수 있다. (8가지 다양한 자료형으로 읽고 쓸 수 있음)
667 |
668 | 3. 두 클래스는 각각 생성자에서 InputStream과 OutputStream을 받아들임 (API 확인)
669 | 생성자의 arguments 값으로 InputStream, OutputStream을 받아들인다는 의미는 그 하위 클래스들을 받아들인다는 뜻
670 |
671 | 4. JAVA9 이라면 위 클래스 쓰지 않아도 아래와 같은 코드도 가능
672 | ~~~java
673 | InputStream is;
674 | byte[] array = is.readAllBytes();
675 | ~~~
676 | - **java.io의 주요 클래스**
677 | 2-1) InputStream :
678 | 바이트 단위로 데이터를 읽는다
679 | 2-2) OutputStream :
680 | 외부로 데이터를 전송한다
681 |
682 | ### 3. BufferedInputStream / BufferedOutputStream
683 | > BufferedInputStream / BufferedOutputStream을 사용하면 편리하고 효율적인 입출력을 할 수 있다.
684 |
685 | BufferedInputStream을 통하여 원하는 자료를 1바이트 단위로 읽는 read() 메소드를 수행하면 시스템 내부적으로 버퍼를 준비하고 이 버퍼를 이용하여 지정된 파일로부터 버퍼의 크기만큼 한꺼번에 많은 데이터를 가져온다.
686 |
687 | 이렇게 채워진 버퍼로부터 1 바이트씩 읽어들여 프로그램으로 전달하게 된다.
688 | 이때, 1 바이트씩 읽어들이는 작업은 파일로부터 읽어오는 것이 아닌 준비된 시스템 버퍼에서 읽어오게 되므로, 파일 입력으로 인한 성능 저하를 최소화 할 수 있다.
689 |
690 | BufferedOutputStream 역시 마찬가지로 데이터를 1 바이트씩 출력하면 파일이 아닌 준비된 시스템 버퍼에 출력을 쌓는다.
691 | 버퍼가 모두 채워지거나 close(), flush() 명령을 만나면 버퍼의 모든 내용을 하드 디스크 파일에 출력한다.
692 |
693 | 따라서, BufferedOutputStream 역시 하드 디스크 파일에 대한 출력을 최소화 하여 효율을 향상 시킬 수 있다.
694 |
695 | 결론적으로 사용자가 BufferedInputStream과 BufferedOutputStream을 이용하여 프로그램을 작성하면 1 바이트씩 읽고 쓰는 모든 작업이 하드 디스크 파일이 아닌 내부적인 버퍼를 대상으로 발생하며, 필요에 따라 버퍼와 하드 디스크 파일간에 입출력이 간헐적으로 발생하므로 전체적인 입출력 성능이 동적으로 향상될 수 있다.
696 |
697 |
698 |
699 | ### 4. String 으로 바이트 데이터 만들기
700 | > 보통 은행이나 기타 금융쪽 시스템은 C / C++ 기반인 경우가 많음
701 | 따라서 정해진 buffer로 적절히 끊어서 전송해야 하기 때문에, byte[] 형식으로 변환한 후 socket에 실어서 전송해야 한다.
702 | ~~~java
703 | byte[] res = text.getBytes(StandardCharsets.UTF_8);
704 | ~~~
705 | 1. **getBytes()** 메소드는 소켓통신 등 특정 상황에서 스트링을 바이트 배열로 만드는 메소드이고, 수신 측에서는 이를 바이트 배열로 읽고 디코딩하면 원본 String을 얻을 수 있다.
706 |
707 | ### 4.1. Byte - String / String - byte
708 | ~~~java
709 | String str1 = “Hello World!”;
710 |
711 | // 변수 str1의 바이트 값
712 |
713 | // 72101108108111328711111410810033
714 |
715 | bytes[] buffers = str1.getBytes();
716 |
717 | …
718 |
719 | // 바이트 배열 자체의 문자열 값
720 |
721 | // [B@ca0b6
722 |
723 | String buffersArrayString = buffers.toString();
724 |
725 | …
726 |
727 | // 바이트 배열을 문자열로 변환한 값
728 |
729 | // Hello World!
730 |
731 | String str2 = new String(buffers);
732 |
733 | ~~~
--------------------------------------------------------------------------------
/oop/oop.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 |
3 | ## 1. 객체 지향 프로그래밍
4 |
5 | ### 1-1) 객체 지향의 4갸지 원칙
6 | 1. **추상화 (Abstraction)**
7 | 필요로 하는 속성이나 행동을 추출하여 추상화 시키는 것
8 | ex) Class / Instance
9 |
10 | 2. **캡슐화 (Encapsulation)**
11 | > Message-passing의 한 부분이다, 접근 지정자의 형태로 나타남 (private, protected)
12 | 객체들간 메시지를 통해 소통하고 상대방의 디테일은 알 필요가 없다는 객체지향 원칙이다.
13 |
14 | 캡슐화의 장점
15 | 1. 낮은 결합도
16 | 객체간 소통시 세부사항 알 필요 없음
17 |
18 | 2. 정보 은닉
19 | 정보 손상 가능성 낮춤 (public -> private)
20 |
21 | 3. **상속 (Encapsulation)**
22 | > Generalization / Specialization
23 |
24 | - 재사용의 관점 + 캡슐화의 일종
25 | - 슈퍼클래스로 자식 클래스를 외부로 부터 은닉하는 것이다.
26 | - in Kind of 관계가 성립되지 않으면 불필요한 속성이나 연산을 물려받게 된다.
27 |
28 | 4. **다형성**
29 | 이름은 같으나 시그니쳐가 다르오
30 | > 하나의 메소드나 클래스가 여러 가지 형태로 사용될 수 있는 것
31 | **자바** 에서는 한 타입(Super Class / Interface) 의 참조변수로
32 | 여러 타입의 객체 (Sub Class, 구현체) 를 참조할 수 있도록 함
33 |
34 | - 오버로딩 / 오버라이딩
35 | - 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함 (인터페이스, 상속)
36 |
37 | **다형성을 쓰는 이유**
38 | - 전략 패턴과 같이 유연한 프로그래밍이 가능하다.
39 | - 추상화를 지켜며, 유지보수의 측면에서 좋다
40 |
41 | 출처: https://arabiannight.tistory.com/entry/302 [아라비안나이트]
42 |
43 | ~~~java
44 | // 부모 클래스
45 | public abstract class Pet {
46 | public abstract void talk();
47 | }
48 | // 자식 클래스
49 | public class Cat extends Pet {
50 | public void talk(){ System.out.println("야옹"); }
51 | }
52 | public class Dog extends Pet {
53 | public void talk(){ System.out.println("멍멍"); }
54 | }
55 | public class Parrot extends Pet {
56 | public void talk(){ System.out.println("안녕"); }
57 | }
58 | ~~~
59 |
60 | 4-1) 오버라이딩 (Overriding)
61 | - 슈퍼클래스에서 정의한 함수를 자식 클래스에서 덮어씌우는 것
62 | - 자바의 abstract 함수가 그 예
63 | - 즉 클래스 외적인 개념
64 |
65 | 4-2) 오버로딩
66 | - 같은 클래스 내에서, 메소드 이름은 같지만 시그니처 (파라미터 유형 갯수 등) 이 다름
67 |
68 |
69 | ## 2. 디자인 패턴
70 | > 바퀴를 다시 발명하지 마라,
71 | 각기 다른 SW가 서로간의 공통되는 설계 문제가 존재하며 이를 해결하는 방법론
72 |
73 | ### GoF (Gang of Fouts) 디자인 패턴의 분류
74 | 1. 생성 (Creational Pattern) 패턴
75 | - 객체 생성에 관련된 패턴
76 | - 객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을 제공한다.
77 | - 싱글턴이 생성 패턴에 포함
78 |
79 | 2. 구조 (Structural) 패턴
80 | - 클래스나 객체를 조합해 더 큰 구조를 만듬
81 |
82 | 3. 행위 (Behavior) 패턴
83 | - 객체나 클래스 사이의 책임 분배와 관련된 패턴
84 | - 한 객체가 혼자 수행할 수 없는 작업을 여러개의 객체로 어떻게 분배하는지. 그렇게 하면서도 객체간 결합도는 최소화 한다.
85 | - Strategy(전략패턴) 가 여기에 포함
86 |
87 | ### 싱글턴 패턴 (Singleton)
88 | - 전역 변수를 쓰지 않고, 객체를 하나만 생성하게 한다.
89 | - getInstance 형태로 프로그램 어디에서나 끌어쓸 수 있다.
90 | - 스레드 상황에서 문제가 발생할 수 있는데 이는 static 변수로 바로 멤버변수에 할당하면 된다.
91 |
92 | ~~~java
93 | public class Printer {
94 | // static 변수에 외부에 제공할 자기 자신의 인스턴스를 만들어 초기화
95 | private static Printer printer = new Printer();
96 | private Printer() { }
97 | // 자기 자신의 인스턴스를 외부에 제공
98 | public static Printer getPrinter(){
99 | return printer;
100 | }
101 | public void print(String str) {
102 | System.out.println(str);
103 | }
104 | }
105 | ~~~
106 |
107 | ### 전략 패턴 (Strategy)
108 | - 상황에 따라, 비슷하면서도 조금씩 다른 행위을 주고 싶을때 사용한다.
109 | - 인터페이스는 하나요, 인터페이스 생성될떄 그 구현체를 선택하는 형태이다.
110 | - 인터페이스를 전략 인터페이스라고 부르고,
111 | - 구현체들을 전략 클래스라고 부른다.
112 | - 구현체들은 같은 이름의 함수를 가지고 있고 액션은 다르다.
113 |
114 | 먼저 전략 인터페이스는 아래와 같이 구현체의 공통 메솓드로!
115 | ~~~java
116 | public interface Strategy {
117 | void runStrategy();
118 | }
119 | ~~~
120 |
121 | 전략 인터페이스를 구현한 클래스는 아래와 같다.
122 | ~~~java
123 | public class StrategyGun implements Strategy{
124 | @Override
125 | public void runStrategy() {
126 | // TODO Auto-generated method stub
127 | System.out.println("탕! 타탕! 탕탕!");
128 | }
129 | }
130 | ~~~
131 |
132 | 전략을 사용할 컨텍스트가 필요하고
133 | ~~~java
134 | public class Solider {
135 | void runContext(Strategy strategy) {
136 | System.out.println("배틀 그라운드 시작");
137 | strategy.runStrategy();
138 | System.out.println("배틀 종료");
139 | }
140 |
141 | }
142 | ~~~
143 | 그리고 전략을 생성하고 컨텍스트에 주입니다.
144 | ~~~java
145 | public class Client {
146 | public static void main(String[] args) {
147 | Strategy strategy = null;
148 | Solider rambo = new Solider();
149 | // 인터페이스에 생명력 부여
150 | strategy = new StrategyGun();
151 |
152 | rambo.runContext(strategy);
153 |
154 | System.out.println("\n");
155 | strategy = new StrategyGrenade();
156 |
157 | rambo.runContext(strategy);
158 | }
159 | }
160 | ~~~
161 |
162 | ### 팩토리 메서드 패턴
163 | > 객체의 생성 코드를 별도의 클래스/메서드로 분리하는 패턴
164 |
165 | #### 팩토리 메서드 패턴의 개념과 적용 방법
166 |
167 | 1. 객체 생성을 전담하는 별도의 Factory 클래스 이용
168 | 스트래티지 패턴과 싱글턴 패턴을 이용한다.
169 | - 생성 Factory 클래스는 파라미터를 받아서 상황에 맞는 객체를 얻어온다.
170 | 2. 상속 이용:
171 | 하위 클래스에서 적합한 클래스의 객체를 생성
172 | 스트래티지 패턴, 싱글턴 패턴과 템플릿 메서드 패턴을 이용한다.
173 |
174 | ## 3. 객체 지향의 5대 원칙 (SOLID)
175 | > High Cohesion - Loose Coupling 원칙을 객체 지향애 도입한 것, 재사용은 극대화 시키되 수정은 최소화 하는것이 목표 ㄴ
176 |
177 | ### 1. 객체지향 5원칙
178 | 1. SRP (Single Responsibility Principle) 단일 책임 원칙
179 | 2. OCP (Open Closed Principle) 개방 폐쇄 원칙
180 | 3. LSP (Liskov Substitution Principle) 리스코프 치환 원칙
181 | 4. ISP (Interface Segregation Principle) 인터페이스 분리 원칙
182 | 5. DIP (Dependency Inversion Principle) 의존 역전 원칙
183 |
184 | ### 1.1 객체지향 5원칙 상세
185 | #### 1. SRP (Single Responsibility Principle)
186 | **단일 책임 원칙**
187 | > 클래스의 역할과 책임을 명확하게 하고, 추상화의 정도를 지켜야 한다.
188 |
189 | #### 2, OCP (Open Closed Principle)
190 | **개방 폐쇄 원칙**
191 | > 소프트웨어는 확장에는 열려있고, 주변의 변화에 대해서는 닫혀 있어야 한다.
192 |
193 | 기존 제휴사와의 서비스에서 비슷하게 다른 제휴사의 서비스를 추가할 때, 기존 코드의 수정은 불가피하지만, 최대한 프로그램의 수정은 줄이되 확장은 용이하도록 설계해야 한다.
194 | 이와 관련하여 적절한 예는, **인터페이스** 이다.
195 |
196 | 
197 |
198 | 인터페이스나 상위 클래스 (상속) 은 세부 구현과 다른 모듈의 의존성을 약화시키는 완충장치이다.
199 |
200 | #### 3. LSP (Liskov Substitution Principle)
201 | **리스코프 치환 원칙**
202 | > 서브 타입은 언제나 자신의 기반 타입(base type)으로 교체할 수 있어야 한다.
203 | (의미론적으로 sub type ISA base type 이 되어야 한다는 뜻)
204 |
205 | LSP(리스코프 치환 원칙)은 인터페이스와 클래스 관계, 상위 클래스와 하위 클래스 관계를 얼마나 잘 논리적으로 설계 했느냐가 관건이다. (상속을 제대로 구현했는지)
206 | 그리고 **상속 == 확장** 이라는 것을 기억하자.
207 |
208 | #### 4. ISP (Interface Segregation Principle)
209 | **인터페이스 분리 원칙**
210 |
211 | > 클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안된다.
212 | (상황과 관련있는 메서드만 지원해야 한다.)
213 |
214 | ISP(인터페이스 분리 원칙)은 SRP(단일 책임 원칙)과 다른 해결책을 제시하는 것이다.
215 |
216 | SRP(단일 책임 원칙) => 클래스를 쪼개서 기능별로 클래스 자체를 분리
217 |
218 | ISP(인터페이스 분리 원칙) => 인터페이스 정제 및 최소화
219 |
220 |
221 |
222 | #### 5. DIP (Dependency Inversion Principle)
223 | **의존 역전 원칙**
224 |
225 | "고차원 모듈은 저차원 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화 된 것에 의존해야 한다."
226 | "추상화 된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화 된 것에 의존해야 한다."
227 | "자주 변경되는 구체(Concrete) 클래스에 의존하지 마라" - 로버트 C. 마틴
228 |
229 | > 자신보다 변하기 쉬운 것에 의존하지 마라.
230 |
231 | 구체적으로 추상클래스 또는 상위클래스는 구체적인 구현클래스 또는 하위클래스에게 의존적이면 안된다. 구체 클래스는 자주 변경되기 때문에 이에 의존하게 되면 의존하는 고차원 클래스들을 모두 수정해야 한다. 지양하자
232 |
--------------------------------------------------------------------------------
/os/os.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 |
3 | ## Unix File System
4 |
5 | > 부트블록, 슈퍼블록, i-node, 데이터블록 영역을 가지며, 운영 체제에서 보조 기억 장치와 그 안에 저장되는 파일을 관리하는 시스템의 통칭. 보조 기억 장치에 저장된 각 파일과 그 구조 Unix의 모든 파일은 파일명과 하나의 유일한 *inode* 를 가짐
6 |
7 | ### 1. 유닉스 파일 시스템의 구성
8 |
9 | http://www.jidum.com/jidums/view.do?jidumId=481
10 |
11 | #### 계층구조
12 |
13 | 1. Boot Block
14 |
15 | 운영체제 부트, 초기화와 관련된 Bootstrap 프로시저를 저장
16 |
17 | 2. Super Block
18 |
19 | 전체적인 파일 시스템의 상태에 대한 meta-data
20 | (크기, 상태, metadata structure 에 관한 포인터 등)
21 |
22 | 3. Bitmap Block
23 |
24 | i-node 와 data-block 의 할당 현황 표시
25 |
26 | 4. i-node
27 |
28 | 파일과 디렉토리 각각에 대한 속성 정보 영역
29 |
30 | 5. Data Block
31 |
32 | 파일과 디렉토리의 실제 데이터를 저장하는 영역
33 |
34 | #### 유닉스 파일 시스템 유형
35 |
36 | 1. 일반파일
37 |
38 | 사용자가 정의한 실행가능한 파일 (텍스트, 바이너리)
39 |
40 | 2. 디렉토리 파일
41 |
42 | 디렉토리에 포함되어 있는 여러가지 파일들, 디렉토리에 관련한 정보 등을 저장하는 논리적 영역
43 |
44 | 3. 특수파일
45 |
46 | 주변 장치, 파이프와 소켓 같은 프로세스간의 상호 통신 및 표준입출력 시스템 호출
47 |
48 | 4. i-node
49 |
50 | 각 파일에 대한 정보를 기억하는 **구조체**
51 |
52 | #### i-node 의 개념과 구성요소
53 |
54 |
55 |
56 | 위의 그림처럼 흔히 말하는 심링크는 inode 를 두번 걸쳐서 (첫번째 inode 는 원본 파일에 대한 포인터를 가지고 있음) 원본 파일 데이터를 메모리에 사상하는 것이고, 하드 링크 파일은 원본과 직접 연결되는 inode 룰 통해 원본을 바로 자려올 수 있다.
57 |
58 | ## OS / Kernel
59 |
60 | ### 운영체제란?
61 |
62 | > 각 유저 프로세스에 가상의 컴퓨터들을 적절히 제공하며,
63 | 사용자와 하드웨어 간의 인터페이스 소프트웨어라고 할 수 있다.
64 |
65 | 주요한 특징은 아래와 같다.
66 |
67 | (1) Resource Manager (자원관리)
68 |
69 | - HW Resources : 말그대로 하드웨어 자원 (메모리, CPU, IO장치 등)
70 |
71 | - SW Resources : File Management (파일 시스템을 관리한다)
72 |
73 | (2) API (Application Programing Interface)
74 |
75 | 응용 프로그램 등등을 위한 여러가지 서비스를 지원한다.
76 |
77 | ### Kernel 이란?
78 |
79 | > OS의 API 기능을 담당하는 부분이다.
80 | 운영체제의 다른 모든 부분에 필요한 서비스를 제공한다.
81 |
82 | 흔히 말하는 System Call 이 Kernel 서비스에 대한 인터페이스이고,
83 | 운영체제 위의 많은 Application 들은 System Call 을 이용하여 Kernel 이 제공하는 서비스들을 받을 수 있다.
84 |
85 | - 하드웨어 자원을 프로세스에 적절히 분배
86 |
87 | - 메모리 제어
88 |
89 | - System Call 처리
90 |
91 | ### System Call?
92 |
93 | > OS가 제공하는 서비스를 어플리케이션에 제공하는 인터페이스
94 |
95 | #### 1. 시스템콜 종류
96 |
97 | 1. 프로세스 제어 (생성, 종료, 시그널)
98 |
99 | 2. 파일 및 IO 관리
100 |
101 | - 생성 / 종료
102 | - 열기 / 닫기
103 | - read / write
104 |
105 | 3. 통신
106 |
107 | 4. 프로세스간 통신 (IPC)
108 |
109 | ## Thread / Process
110 |
111 | ### Program
112 |
113 | > 어떤 작업을 위해 실행할 수 있는 파일
114 |
115 | ### Process
116 |
117 | > 프로그램의 인스턴스 (실행된 프로그램 / 운영체제로 부터 자원을 할당받는)
118 | ref) 자원 : CPU시간, 주소공간, 메모리
119 |
120 | - 각 프로세스는 별도의 주소 공간에서 실행되며 영향을 주지 않는다
121 | - 프로세스간 통신을 하려면 IPC (파이프, 소켓 등)를 사용해야 한다.
122 | - 최소 1개의 스레드는 있어야 한다.
123 |
124 | ### Thread
125 |
126 | 
127 |
128 | - 스택만 따로 할당받고 코드 / 데이터 / 힙 공간은 공유한다.
129 | - **프로세스 내** 의 여러 흐름 (분산처리)
130 | - 스택과 레지스터는 별도로
131 |
132 | ### Java Thread
133 |
134 | - 일반 쓰레드와 비슷하지만, 주체가 OS가 아니라 JVM이다.
135 | - 자바 스레드는 JVM에 의해 스케줄되는 **실행 단위 코드 블록**이다.
136 | - 스레드 코드를 작성하고, JVM에게 요청하면 된다.
137 | - Runnable 인터페이스 구현 or Thread 상속
138 | - 즉, 개발자는 자바 스레드로 작동할 스레드 코드를 작성하고, 스레드 코드가 생명을 가지고 실행을 시작하도록 JVM에 요청하는 일 뿐이다.
139 |
140 | ### Java ThreadLocal
141 |
142 | - 자바 ThreadLocal 클래스는 오직 한 Thread 에 의해 읽고 쓰여질 수 있는 변수를 생성할 수 있도록 한다.
143 |
144 | - 때문에 만일 두 쓰레드가 같은 코드를 실행하고 이 코드가 하나의 ThreadLocal 변수를 참조하더라도, 이 두 쓰레드는 서로의 ThreadLocal 변수를 볼 수 없다. 글자 그대로 쓰레드의 지역변수이다. (Thread Block 의 지역변순)
145 |
146 | ## 멀티프로세서 vs 멀티스레드
147 |
148 | > 멀티스레드가 더 좋겠지..
149 |
150 | ### 1. 좋은 이유
151 |
152 | 1. 자원의 효율성 증대
153 |
154 | - 프로세스 간의 Context Switching시 단순히 CPU 레지스터 교체 뿐만 아니라 RAM과 CPU 사이의 캐시 메모리에 대한 데이터까지 초기화되므로 오버헤드가 크기 때문
155 | - 스레드는 프로세스 내 메모리 공유하기 때문에 간단하고, 자원도 덜 든다.
156 |
157 | 2. 처리비용 감소 / 응답시간 단축
158 |
159 | - IPC 필요 없으니 통신 오버헤드 줄어듬
160 | - 스레드 Context Switching 은 Stack 만 갈아치우면 되니 훨씬 빠름
161 | - 스레드는 PCB에 프로세스에 비해 적게 저장 (스택 및 간단한 정보만 저장)
162 | - 따라서 PCB 관련 오버헤드도 적음
163 |
164 | ### 2. PCB (Process Control Block)
165 |
166 | 프로세스 제어 블록(Process Control Block, 줄여서 PCB)은 특정한 프로세스를 관리할 필요가 있는 정보를 포함하는, 커널의 자료구조이다. PCB는 운영 체제가 **프로세스** 를 표현한 것이라 할 수 있습니다.
167 |
168 | #### PCB 내 표현되는 정보
169 |
170 | 1) 프로세스 식별자(Process ID)
171 |
172 | 2) 프로세스 상태(Process State) :
173 | 생성(create), 준비(ready), 실행 (running), 대기(waiting), 완료(terminated)
174 |
175 | 3) 프로그램 계수기(Program Counter) :
176 | 프로그램 계수기는 이 프로세스가 **다음에 실행할 명령어** 의 주소를 가리킵니다.
177 |
178 | 4) CPU 레지스터 및 일반 레지스터
179 |
180 | 5) CPU 스케줄링 정보 : 우선 순위, 최종 실행시각, CPU 점유시간 등
181 |
182 | 6) 메모리 관리 정보 : 해당 프로세스의 주소 공간 등
183 |
184 | 7) 프로세스 계정 정보 : 페이지 테이블, 스케줄링 큐 포인터, 소유자, 부모 등
185 |
186 | 8) 입출력 상태 정보 : 프로세스에 할당된 입출력장치 목록, 열린 파일 목록 등
187 |
188 | 9) 포인터 : 부모프로세스에 대한 포인터, 자식 프로세스에 대한 포인터, 프로세스가 위치한 메모리 주소에 대한 포인터, 할당된 자원에 대한 포인터 정보 등.
189 |
190 |
191 | ### 3. Context Switching
192 |
193 | > 현재 진행하고 있는 Task(Process, Thread)의 상태를 저장하고 다음 진행할 Task의 상태 값을 읽어 적용하는 과정을 말합니다. 참고로 프로세스 마다 PCB가 있습니다.
194 |
195 |
196 |
197 | 1. Context Switching이 발생하게 되면 많은 Cost가 소요된다.
198 |
199 | - Cache 초기화
200 | - Memory Mapping 초기화
201 | - Kernel은 메모리 접근을 위해 항상 실행되어야 함
202 |
203 | 2. 작동 방식
204 |
205 | - Task의 대부분 정보는 Register에 저장되고 PCB(Process Control Block)로 관리되고 있습니다.
206 | - 현재 실행하고 있는 Task의 PCB 정보를 저장하게 됩니다. (Process Stack, Ready Queue)
207 | - 다음 실행할 Task의 PCB 정보를 읽어 Register에 적재하고 CPU가 이전에 진행했던 과정을 연속적으로 수행을 할 수 있습니다.
208 | - PCB를 저장하고 가져올때는 CPU가 아무런 일도 하지 못하게 된다. (오버헤드)
209 | - 컨텍스트 스위칭을 하는 주체는 스케줄러이다.
210 |
211 | 3. 컨텍스트 스위칭이 일어나는 상황
212 |
213 | - I/O interrupt
214 | - CPU 사용시간 만료
215 | - 자식 프로세스 Fork
216 |
217 |
218 | ## Thread Safe
219 |
220 | > 멀티스레드 환경에서 여러 스레드가 동시에 하나의 객체 및 변수(공유 자원)에 접근할 때, 의도한 대로 동작하는 것을 말한다.
221 |
222 | - 공유자원에 접근하는 임계영역을 동기화 기법으로 제어해야 함 (상호배제)
223 | - 동기화 기법은 Mutex, Semaphore 등이 있다.
224 | - 재 진입성 (동시에 어떤 스레드가 와도 같은 결과 보장) 을 보장해야 한다.
225 | - 뮤텍스, 세마포어는 운영체제 커널의 동기화 방법이다.
226 | - 커널모드 변경하면 성능이 저하된다.
227 |
228 | ## 뮤텍스와 세마포어
229 |
230 | https://worthpreading.tistory.com/90
231 |
232 | ### 뮤텍스
233 |
234 | - 임계 영역을 가진 스레드들의 러닝타임이 겹치지 않도록 처리 (동시사용 불가)
235 | - 프로세스나 스레드가 뮤텍스 객체를 한번에 하나만 소유가능
236 |
237 | ### 세마포어
238 |
239 | - 세마포어는 OS내부 커널의 한 저장장치 값 (바이너리 일 수도 있고, 아닐수도 있음)
240 | - 이 값을 통해 자원이 사용중인지 알 수 있다.
241 | - 자원을 사용하고 있다면 기다리고, 없다면 드루간다.
242 | - 세마포어를 사용하는 프로세스는 세마포어 값을 확인하고, 자원을 사용하는 동안에는 그 값을 변경함으로써 다른 세마포어 사용자들이 기다리도록 해야함
243 | - 현재 공유자원에 접근할 수 있는 쓰레드, 프로세스의 수를 나타내는 값을 두어 상호배제를 달성하는 기법
244 |
245 | ### 세마포어와 뮤텍스의 차이
246 |
247 | - 세마포어는 뮤텍스가 될수 있지만, 뮤텍스는 세마포어가 될 수 없다
248 | - 간단히 보자면 뮤텍스는 boolean(상태), 세마포어는 int(카운터)
249 | - 뮤텍스는 항상 열쇠 1개이고, 세마포어는 여러개 가질 수 있기 때문에
250 | 세마포어의 열쇠가 1개라면 뮤텍스와 같습니다.
251 | - 세마포어는 파일시스템 상 파일형태 (값) 로 존재, 뮤텍스는 프로세스 범위
252 | - 즉, 프로세스가 사라질 때 뮤텍스는 clean up 됩니다.
253 | - 세마포어는 소유할 수 없는 반면, 뮤텍스는 소유할 수 있습니다.
254 |
255 | ### 모니터
256 |
257 | - 상호배제를 구현한 프로그램, java 가 이 방식을 사용
258 | - 모니터에는 한 프로세스 만이 접근 가능함
259 | - 무조건 모니터를 통해 자원을 할당받고 사용할 수 있음
260 |
261 | #### wait / notify
262 |
263 | 1. wait
264 |
265 | - 현재 thread 야, 가지고 있던 Lock 을 풀고 대기해라
266 |
267 | 2. notify
268 |
269 | - wait 하고 있는 thread 를 깨운다
270 |
271 | ### Critical Section
272 |
273 | 임계 구역으로 프로세스 또는 스레드들이 공통 변수들에 접근, 및 수정하고 테이블을 갱신하며, 파일의 읽기, 쓰기 작업들을 수행하는 영역을 말한다. 즉 race condition이 발생하는 영역을 뜻한다. 이미 한 스레드가 Critical Section에 들어갔을 때 다른 스레드들은 이 곳으로의 접근을 막아야한다.
274 |
275 | 한 프로세스 혹은 한 스레드가 메모리의 어떤 부분을 접근하고 있을 때 다른 프로세스 혹은 스레드가 그 부분을 접근하여 값을 변경하면 안된다. 따라서 그 부분을 막기 위해 우리는 동기화를 해야한다는 개념이 나오는 것이다.
276 |
277 | ## 가상 메모리
278 |
279 | http://www.jidum.com/jidums/view.do?jidumId=473
280 |
281 | > 가상 메모리란 어떤 프로세스를 실행할때, 프로세스 전체가 메모리에 다 적재되지 않고도 실행이 가능하도록 하는 기법이다. 부분부분 올려서 쓰는것.
282 | CPU - RAM 관계에서 Cache 같은 역할 수행
283 |
284 | - 효과적인 멀티 프로그래밍 가능
285 |
286 | - 물리적 공간보다 더 큰 프로세스의 실행이 가능
287 |
288 | - 시스템의 다중 프로그래밍 수준 향상 -> 많은 프로그램 동시 수행 - > 이용률, 처리율 상승
289 |
290 | - 기억공간의 제약 감쇠 -> 물리적 기억장치의 효율적인 사용
291 |
292 | ### 1. 메모리 단편화
293 |
294 | https://jeong-pro.tistory.com/91
295 |
296 | > 메모리를 효율적으로 사용하지 못하는 상황을 나타낸다.
297 |
298 | 1. 내부 단편화
299 |
300 | 어떠한 프로세스가 사용해야 하는 메모리는 1kb인데, 실제 할당된 메모리 블럭은 4kb일 경우 사실상 3kb 의 메모리가 낭비되는 것이다.
301 |
302 | 2. 외부 단편화
303 |
304 | 어떠한 프로세스가 메모리 블럭을 사용하고 반납 했을때, 해당 공간이 작게 작게 비어서 큰 놈이 한번에 들어가지 못하는 것이다. (연속으로 비어있지 않아서 발생하는 문제)
305 |
306 | ### 2. 단편화 해결방안
307 |
308 | 1. Paging
309 |
310 | 물리 메모리를 사용할 때, 페이지를 고정크기의 프레임 단위로 나눕니다.
311 | 가상 메모리도 같은 프레임단위인 페이지로 나누어 프레임과 페이지를 페이지 테이블을 통해 맵핑하여,
312 | **연속적인 물리메모리** 가 아니더라도 원하는 크기의 프레임을 사용할 수 있도록 하는 기능이다.
313 |
314 | 따라서 외부 단편화 문제는 해결되겠지만, 여전히 페이지 단위에 따라 메모리 공간이 낭비되는 내부 단편화 문제가 발생한다.
315 | 페이지를 더 작은 단위로 쪼개면 내부 단편화 문제가 해결될 수 도 있지만, 그만큼 Page Mapping 이 자주 발생하기 떄문에 주의해야 한다.
316 |
317 | 2. Segmentation
318 |
319 | 세그멘테이션 기법 같은 경우는 같은 페이지 사이즈로 가상 메모리 영역을 나누는 것이 아니라, 각각 다른 사이즈인 **세그멘트** 로 나누게 된다. 사용 시 마다 다른 단위로 메모리를 할당해야 하므로 미리 메모리 영역을 나누어 놓을 수 없다.
320 |
321 | 따라서 내부 단편화 문제는 해결되었지만 (수요에 따라 메모리 공간 효율적으로 세팅) 미리 얼마나 뜯어갈 지 예측할 수 없으므로, 메모리 사용 후 반납 시 외부 단편화 문제로 중간에 메모리 공간들이 뻥뻥 뚤려 있을 수 있다.
322 |
323 | ### 3. 페이지 폴트
324 |
325 | > 프로세스가 필요한 페이지가 있는데, 지금 가상메모리에서 프레임에 매핑이 아직 되지 않는 상태에서 페이지 폴트가 난다.
326 |
327 | #### 대응
328 |
329 | 1. CPU는 물리 메모리에서 찾는 페이지가 없으면, TRAP 을 발생시켜 커널 모드로 진입한다.
330 |
331 | 2. 커널은 CPU 동작을 잠깐 멈춘다.
332 |
333 | 3. 페이지 테이블을 확인하여, 해당되는 페이지가 스왑파일 어디에 위치하는지 확인하고 혹시 없다면 프로세스를 중지한다.
334 |
335 | 4. 페이지 테이블에 엔트리가 있다면, 물리 메모리에 빈 프레임이 있는지 확인한다.
336 | - 의문점 : 빈 프레임이 없다면? (아래에서 답변)
337 |
338 | 5. 비어있는 프레임에 가상 메모리의 페이지를 맵핑하고, 페이지 테이블을 최신화 한다.
339 |
340 | 6. 중단되었던 CPU를 다시 시작한다.
341 |
342 | #### Q. 빈 프레임이 없다면 ?
343 |
344 | 페이지 교체 알고리즘을 써서 대응한다!
345 | 여기서 나오는 방식이 FIFO, LRU, LRU Approximation 등이 있다.
346 |
347 | 1. First In First Out (FIFO)
348 |
349 | 가장 먼저 들어간 놈을 교체시킨다
350 |
351 | 2. Least Recently Used (LRU)
352 |
353 | 사용된지 오래된 놈 교체
354 |
355 | **쓴지 오래된놈은** 뒤로 보내서 꽉 차면 교체되게 만들고
356 | **방금 쓰인애는** 앞으로 보내서 프레임에서 교체되는 것을 방지한다.
357 |
358 | 3. LRU Approximation
359 |
360 | LRU 와 교체의 기준은 같지만, 대신 bit 를 하나 사용하여 기회를 한번 더 주는것이다.
361 | 교체 후보로 선정되면 1이였던 Bit 을 0으로 바꾸고,
362 | 한번더 선정되면 얄짤없이 교체하는 방식이다.
363 |
364 | ## 지역성 (Locality) 에 대하여
365 |
366 | ### 지역성의 이해
367 |
368 | > 프로세스가 메모리를 참조할 때, 이리저리 균일하게 참조하는 것이 아니라 한 순간에 물리적으로 메모리의 한 부분을 집중적으로 참조하는 성질이다.
369 |
370 | 이것은 Cache Hit 이나, Page Fault 에 모두 관련되어 있는 이야기이다.
371 | 복잡하게 생각하기 보다는, 그냥 프로세스가 메인 메모리 까지 안가고 캐시에서 원하는 정보를 찾으면 좋은 것이고, 또 가상 메모리까지 안가도 메인 메모리에서 끝내면 좋은 것을 말하는 것이다.
372 |
373 | ### 지역성의 종류
374 |
375 | 1. 시간적 지역성
376 |
377 | 최근에 참조된 메모리 주소가, 조만간 또 참조될 가능성이 높다는 것
378 | (LRU 등)
379 |
380 | 2. 공간적 지역성
381 |
382 | 최근에 참조된 메모리 근처 (실제 물리적으로 근접) 에서 또 참조될 가능성이 높다는 것
383 | (배열 등)
384 |
385 | 3. 순차 지역성
386 |
387 | 데이터가 순차적으로 액세스되는 경향 (공간 지역성의 일부로 설명되기도 함)
388 |
389 | ## DMA (Direct Memory Access, Cycle Stealing)
390 |
391 | http://www.jidum.com/jidums/view.do?jidumId=470
392 |
393 | > 메모리 버퍼, 포인터, 카운터를 사용하여 장치 제어기가 CPU의 도움 없이 DMA컨트롤러를 이용하여 데이터를 직접 메모리로 전송하는 입출력 방식 (IO 장치 작업을 CPU 도움 없이 한다)
394 |
395 | ## 데드락 (DeadLock)
396 |
397 | - 첫 번째 스레드는 두 번째 스레드가 들고 있는 객체의 락이 풀리기를 기다리고 있고, 두 번째 스레드 역시 첫 번째 스레드가 들고 있는 객체의 락이 풀리기를 기다리는 상황을 일컷는다.
398 |
399 | - 모든 스레드가 락이 풀리기를 기다리고 있기 때문에, 무한 대기 상태에 빠지게 된다. 이런 스레드를 교착상태에 빠졌다고 한다.
400 |
401 | ### 교착상태의 4가지 조건
402 |
403 | 1. 상호 배제(mutual exclusion)
404 | 한 번에 한 프로세스만 공유 자원을 사용할 수 있다.
405 | 좀 더 정확하게는, 공유 자원에 대한 접근 권한이 제한된다. 자원의 양이 제한되어 있더라도 교착상태는 발생할 수 있다.
406 |
407 | 2. 들고 기다리기(hold and wait) = 점유대기
408 | 프로세스가 자기한테 할당된 자원을 가진 상태에서 다른 자원 요구 및 대기 가능 (욕심쟁이)
409 |
410 | 3. 선취(preemption) 불가능 = 비선점
411 | 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다.
412 |
413 | 4. 대기 상태의 사이클(circular wait) = 순환대기
414 | 두 개 이상의 프로세스가 자원 접근을 기다리는데, 그 관계에 사이클이 존재한다.
415 |
416 | ### 교착상태 방지
417 |
418 | > 4가지 조건들 가운데 하나를 제거하면 된다.
419 |
420 | - 공유 자원 중 많은 경우가 한 번에 한 프로세스만 사용할 수 있기 때문에(예를 들어, 프린트) 1번 조건은 제거하기 어렵다.
421 |
422 | - 대부분의 교착상태 방지 알고리즘은 4번 조건, 즉 대기 상태의 사이클이 발생하는 일을 막는 데 초점이 맞춰져 있다.
423 |
424 |
--------------------------------------------------------------------------------
/os/os_med_test.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 |
3 | ## 운영체제 과제
4 |
5 | ### Chapter 8 **DeadLocks**
6 |
7 | #### 8.4
8 |
9 | 데드락을 방지하는 가능한 방법은 우선순위가 높은 단일의 요청을 그렇지 않은 요청들 보다 무조건 먼저 처리하는 것이다. 예를 들어, 만약 다수의 스레드들이 동기화 되어야 하는 오브젝트들 (A..E) 에 한꺼번에 접근을 시도한다면, 데드락에 걸릴 수 있다. (동기화 방식은 뮤텍스, 세마포어, 조건 변수 등등을 포함한다) 우리는 A..E 이외의 6번째 오브젝트인 F를 추가함으로서 데드락을 예방할 수 있다. 한 스레드가 A..E 의 어떠한 오브젝트의 lock 을 획득하고 싶다면, 첫째로 F에 대한 lock 을 획득해야 한다. 이러한 해결 방식은 *봉쇄* 방식이라고 불리는데 봉쇄 방식은 F에 lock이 걸려있다면, A..E의 lock 이 봉쇄되는 방식이다.
10 | 이러한 계획을 환형 대기와 비교하라
11 |
12 | **A)** 이러한 방식은 효울적인 방식이 아니다. 이는 너무 많은 오브젝트들이 대기해야 한다.
13 |
14 | #### 8.6
15 |
16 | 컴퓨터 시스템이 한 달에 5000개의 작업을 실행하는데 데드락 예방이나 데드락 회피 계획이 없다고 가정해 보자. 데드락은 한달에 두번씩 일어나고, 작업자가 직접 데드락당 10개의 작업들을 종료하고 재 실행 시켜야 한다. 각 작업은 2달러의 가치를 가지고 있고, 종료된 작업들은 중단 되었을때 절반정도 완료되는 경향을 가지고 있다.
17 |
18 | 시스템 프로그래머는 시스템에 설치되어 있는 데드락 회피 알고리즘 사용시 소요되는 실행 시간이 작업 당 평균 실행 시간보다 10% 높다는 것을 발견했다. 해당 컴퓨터는 30% 의 여유 시간을 가지고 있기 때문에 turnaround time 이 평균 20% 정도 증가하지만, 여전히 매달 5,000개의 작업을 처리할 수 있다.
19 |
20 | a) 데드락 회피 알고리즘을 설치한다면, 그 이유는 무엇인가?
21 |
22 | **A)** 데드락 회피는 어떠한 데드락 상황이든 회피 가능을 보장한다. 또한 해당 컴퓨터는 데드락 회피 알고리즘 설치 후에도 작업 부하 처리가 가능하기 때문에 설치할 수 있다.
23 |
24 | b) 데드락 회피 알고리즘 설치를 반대한다면, 그 이유는 무엇인가?
25 |
26 | **A)** 한달에 두 건정도 데드락이 발생하고 하나당 적은 비용이 발생하므로, 굳이 알고리즘을 설치 할 필요는 없다.
27 |
28 | #### 8.11
29 |
30 | 단 하나의 스레드가 존재하는데, 데드락이 발생할 수 있는가?
31 |
32 | **A)** 절대 발생할 수 없다. 교착 상태의 필요조건인 상호 배제, 점유대기, 비선점, 환형대기 모두 2개 이상의 스레드가 존재해야 성립 가능한 조건이다.
33 |
--------------------------------------------------------------------------------
/rails/tip.md:
--------------------------------------------------------------------------------
1 | ### 레일즈 앱에 마크다운 업로드 기능 추가하기
2 |
3 | 예전부터 마크다운을 여기 데브로그에 추가하려고 마음을 엄청 먹고 있었는데, 바빠서 미루다가 이제서야 마크다운 에디터를 추가해 버렸다. 지금 쓰고 있는 이 글도 마크다운으로 작성중이다. 원래는 마크다운이 위지윅보다 글 쓸때는 약간 불편하다고 생각했지만, 마크다운으로 쓰다 버릇 하니 마크다운이 너무 편하고 포맷팅도 깔끔한 것이 느껴진다.
4 |
5 | #### 1. 마크다운 파싱해 주는 젬 설치하기
6 |
7 | 알아보니 Redcarpet 이라는 젬도 있지만, 둘 다 읽어보니 사용법은 대략 비슷한거 같고 나는 깃헙 지킬에서 쓰는 Kramdown 이라는 모듈을 사용해 보기로 했다.
8 |
9 | https://github.com/gettalong/kramdown
10 |
11 | 언제나 그렇듯이 Gemfile에 아래 문장을 추가한다.
12 | ~~~ruby
13 | gem 'kramdown'
14 | ~~~
15 |
16 | 그리고 언제나 그렇듯 `bundle install`
17 |
18 | #### 2. 사용법은 초간단
19 |
20 | 그냥 아래와 같이 쓰면 된다..ㅋㅋㅋㅋㅋ 진짜 레일즈는 너무 사용자 친화적이다
21 |
22 | ~~~ruby
23 | require 'kramdown'
24 |
25 | Kramdown::Document.new(text).to_html
26 | ~~~
27 |
28 | 여기 데브로그에서 쓴 코드를 인용하자면, 아래와 같다.
29 | 나는 데브로그 show 액션에서 사용했고 아래의 `markdown_text` 는 데브로그 테이블의 칼럼이자, 마크다운 텍스트 내용이다.
30 | 아걸 그냥 `Kramdown::Document` 클래스 생성자에 넣고, 생성된 객체를 to_html 메서드로 변환하여 주면 끝이다.
31 |
32 | ~~~ruby
33 | def show
34 | @post = Devlog.find_by(id: params[:id])
35 | if @post.markdown_text.present?
36 | @markdown = Kramdown::Document.new(@post.markdown_text).to_html
37 | end
38 | end
39 | ~~~
40 |
41 | 아무튼 변수에 담긴 html 텍스트를 화면에 뿌려주면 잘 나올 것이다.
42 |
43 | #### 3. 스타일링
44 |
45 | 근데 이대로 화면에 뿌려보면, 무언가 깃허브 마크다운만큼 안이쁘다.
46 | 그러면 이쁘게 꾸미면 된다. 아래에 깃허브 마크다운 css 파일이 있다.
47 |
48 | https://github.com/sindresorhus/github-markdown-css
49 |
50 | 위 링크 디렉토리에 있는 css 파일을 잘 긁어서 적절한 곳에 잘 붙여넣고,
51 | 마크다운 텍스트가 들어갈 구역의 클래스에 `.markdown-body` 클래스를 이쁘게 박아주면 된다.
52 |
53 | 아래를 참고하도록 하자
54 |
55 | ~~~html
56 |
57 | <%= @markdown.html.safe %>
58 |
59 | ~~~
60 |
61 | 끝! 깃허브 처럼 이쁘게 나온다.
--------------------------------------------------------------------------------
/spring/spring.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 |
3 | ## 1. Why SpringBoot?
4 |
5 | ### 스프링부트의 특징
6 | - Embedded Tomcat (WAS, Servlet Container) 제공
7 | - 사실 AutoConfiguration 맥락에, 톰캣 객체 생성 및 연결 준비 등도 들어감
8 | - DispatcherServlet 도 자동설정 됨
9 | - 즉 서블릿 컨테이너 만들고 서블릿 넣어주는일을 자동으로 해준다는 말
10 | - 의존성 관리
11 | - Maven pom.xml 에서 의존 라이브러리의 버전을 일일이 지정하지 않아도 된다.
12 | (등록된 라이브러리에 한해 스프링 부트가 *권장 버전* 을 관리한다)
13 | - @SpringBootApplication 어노테이션으로 xml 설정 대체
14 | - @SpringBootApplication 는 @ComponentScan 과 @EnableAutoConfiguration 을 포함하고 있다.
15 | - @ComponentScan 은 프로젝트 패키지에 있는 Bean을 찾아서 등록한다.
16 | - @EnableAutoConfiguration 로 클래스패스 내 의존성 관련 자동 설정
17 | - 스프링부트는 Bean 을 두단계로 등록한다.
18 | 1. @ComponentScan
19 | 2. @EnableAutoConfiguration
20 | - ContextLoaderListener / DispatcherServlet / CharacterEncodingFilter 설정은 Spring Boot 에서는 추가하지 않아도 된다.
21 |
22 | - 독립실행 가능한 어플리케이션 지향 (JAR도 독립실행 가능)
23 | - mvn package를 하면 실행 가능한 JAR 파일 “하나가" 생성 됨.
24 | - 이는 spring-maven-plugin이 해주는 일 (패키징)
25 | - 스프링 부트는 JAR 파일들을 읽어들이는 로더를 제공한다.
26 | - JAR 런쳐를 사용해서 main 함수가 있는 JAR 파일을 실행한다.
27 |
28 | ### 핵심 장점
29 | 1. 의존성 관리
30 |
31 | 2. 임베디드 톰캣 (독립 실행 가능한 어플리케이션)
32 | - 톰캣 위에 war 를 얹지 않아도, 스프링부트는 jar를 읽을 수 있도록 기능을 제공한다.
33 | - 내장 톰캣도 제공하면서, jar 도 실행가능 하도록 하므로 독립실행이 가능하다.
34 |
35 | 3. Auto Configuration (@EnableAutoConfiguration)
36 | > Spring Boot Auto Configuration 은 추가된 jar 의존성을 기반으로 Spring application을 자동적으로 설정하는 것을 시도한다. 예를 들어 HSQLDB 가 클래스패스에 있다면 어떤 데이터베이스 연결 빈을 정의하지 않아도 자동적으로 in-memory 데이터베이스에 접근할 것이다.
37 | - @SpringBootApplication 에 @EnableAutoConfiguration 이 포함되어 있다.
38 | - AutoConfiguration 을 담당하는 결국은 @Configuration 기반이다
39 | - spring.factories 에 명시되어 있는 클래스들에 한해 자동설정을 적용한다.
40 | - 알아서 조건에 따라 설정 Bean 을 생성하고 적용한다.
41 |
42 | 4. 어노테이션 기반 Component Scan (@Component)
43 | > 현재 패키지 이하에서, @Component 어노테이션이 붙은 클래스들을 찾아 Bean 으로 등록한다. (제외도 가능)
44 | - 예를 들어 @Controller 어노테이션도 내부를 까보면 @Component 가 들어있다.
45 |
46 | ## 2. Servlet 과 JSP
47 | ### 1. 서블릿 (Servlet)
48 | > 자바를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 Spec
49 | 자바 서블릿은 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종이다.
50 | 자바로 구현된 [CGI](https://ko.wikipedia.org/wiki/%EA%B3%B5%EC%9A%A9_%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%9B%A8%EC%9D%B4_%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4) 라고 말할 수 있다.
51 |
52 | #### 1.1 서블릿의 특징
53 |
54 | - HTML 을 사용하여 요청에 응답한다.
55 | - **Java Thread** 를 이용하여 동작한다.
56 | - MVC 패턴에서 Controller로 이용된다.
57 | - HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.
58 | - HTML 변경 시 Servlet을 재컴파일해야 하는 단점이 있다.
59 |
60 | #### 1.2 서블릿 동작 방식
61 |
62 |
63 | 1. 클라이언트가 HTTP 요청시 이를 Servlet Container (WAS) 로 전송
64 |
65 | 2. 이를 전송받은 Servlet Container 는 ***HttpServletRequest, HttpServletResponse*** 의 객체들을 생성한다.
66 |
67 | 3. **web.xml** 은 사용자가 요청한 URL을 분석하여 어느 서블릿에 대해 요청을 한 것인지 찾습니다. (한개의 서블릿 당 한개의 컨트롤러 사상)
68 |
69 | 4. 해당 서블릿 스레드 (객체 아님) 에서 service 메소드를 호출한 후 요청의 POST, GET 여부에 따라 doGet() 또는 doPost()를 호출
70 |
71 | 5. doGet() or doPost() 메소드는 동적 페이지를 생성한 후 HttpServletResponse 객체로 응답.
72 |
73 | 6. 응답이 끝나면 HttpServletRequest, HttpServletResponse 소멸
74 |
75 |
76 | ### 2. 서블릿 컨테이너 (aka WAS)
77 | > 서블릿 컨테이너는 서블릿을 관리하며 네크워크 통신, 서블릿의 생명주기 관리, 스레드 기반의 병렬처리를 대행한다. 가장 대표적인 것으로는 아파치 톰캣(Tomcat)이 있다.
78 |
79 | ### 3. WS vs WAS (Apache VS Tomcat)
80 |
81 | **웹서버** 는 클라이언트의 요청을 기다리고 요청에 대한 데이터를 만들어서 응답하는 역할을 한다. 이때 데이터는 정적인 데이터(html, css, 이미지등)로 한정된다. 말그대로 미리 정해진 자원들을 응답해 주는 것이다.
82 |
83 | **WAS** 클라이언트의 요청이 있을 때 ***내부 프로그램을 통해 결과를 만들어내고*** 이것을 다시 클라이언트에게 돌려주는 역할을 한다.
84 | 이는 WS의 기능 일부와 웹 컨테이너의 결합으로 다양한 기능을 컨테이너에 구현하여 다양한 역할을 수행한다.
85 |
86 | 예전에는 static file 은 웹서버를 통해 제공하고, 동적인 기능들만 WAS 를 쓰는것이 효율적이라는 말이 있었는데, 톰캣은 5.5부터 **Httpd** 의 native모듈을 사용해서 스태틱파일을 처리하는 기능을 제공한다.
87 |
88 | 이 경우 아파치와 톰캣이 같은 모듈을 사용하는 셈이니 성능에서 차이가 날 이유가 없다. 실제 테스트 한 결과를 봐도 톰캣에서 아파치 Native 모듈을 사용하는 것이 순수하게 아파치 Httpd만 사용하는 것과 비교해서 성능이 전혀 떨어지지 않는다.
89 |
90 | ### 4. JSP (Java Server Page)
91 | > 이는 웹 서버 어플리케이션의 발전속에 응답의 표현을 위해 자연스럽게 등장했다.
92 |
93 | 기존 서블릿 같은 경우 HttpServletResponse 객체에게 응답 html을 주려면 아래와 같이 상당히 귀찮은 작업이 필요했다.
94 | ~~~ java
95 | public class HelloServlet extends HttpServlet {
96 |
97 | public void doGet(HttpServletRequest req,
98 | HttpServletResponse res)
99 | throws ServletException,IOException {
100 |
101 |
102 |
103 | res.setContentType("text/html;
104 | charset=UTF-8");
105 |
106 | PrintWriter out = res.getWriter();
107 |
108 | out.println("");
109 | out.println("");
110 | out.println("Hello World!!");
111 | out.println("");
112 | out.println("");
113 | out.close();
114 |
115 | }
116 |
117 | }
118 | ~~~
119 |
120 | 그래서 등장한 도구가 JSP (루비의 ERB 같은 느낌이라고 보면 된다)
121 | ~~~jsp
122 | <% @page import="java.util.Calendar" %>
123 | <% @page contentType="text/html; charset=UTF-8"%>
124 | <% String str = String.format("%tF",Calendar.getInstance()); %>
125 |
126 |
127 |
129 | Insert title here
130 |
131 |
132 | 오늘은 <%= str %>
한시간만 참으면 점심....
133 |
134 |
135 | ~~~
136 |
137 | 아무튼 이렇게 기존 방식보다 html 작성이 훨씬 빠르게 되었다.
138 | 내부적으로는 JSP 파일은 Tomcat이 Servlet으로 바꾸어서 돌린다고 한다.
139 |
140 | ## 3. 컨테이너 그리고 IOC / DI
141 | #### 3.1 스프링 컨테이너 란?
142 | 컨테이너는 보통 인스턴스의 생명주기를 관리하며,
143 | 생성된 인스턴스들에게 추가적인 기능을 제공하도록 하는 것이다.
144 | 컨테이너는 개발자가 작성한 코드의 처리과정을 위임받은 존재이다.
145 | 예를들어 서블릿 컨테이너는 서블릿을 생성하고 스레드를 이용해 사용자의 요청을 처리한다.
146 |
147 | 이와 마찬가지로, 스프링에도 의존성 주입을 이용하여 어플리케이션 컴포넌트들을 관리하는 컨테이너가 있다. 이것이 바로 Spring Container 이다.
148 |
149 | #### 3.2 IOC / DI
150 | 그리고 컨테이너는 아래와 같은 특징을 가진다
151 |
152 | 1. **IOC (Inversion Of Control - 제어의 역전)**
153 |
154 | 개발자는 보통 객체지향 프로그래밍을 하면 New 연산자, 인터페이스 호출, 팩토리 호출방식으로 객체를 생성하고 소멸시킨다.
155 | IOC란 이렇게 원래 개발자의 의무인 인스턴스의 생성부터 소멸까지의 객체 생명주기 관리를 컨테이너가 해 주는것을 말한다.
156 |
157 | 2. **DI (Dependency Injection - 의존성 주입)**
158 |
159 | IoC를 실제로 구현하는 방법으로서 의존성있는 컴포넌트들 간의 관계를 개발자가 직접 코드로 명시하지 않고 컨테이너인 Spring이 런타임에 찾아서(getBean) 의존성을 주입해 주는 것이다.
160 |
161 | - 인터페이스에 알맞는 Bean 을 주입하는 방법을 많이 사용한다.
162 | - 생성자 주입이 권장된다 (final 선언으로 immutable / 과한 책임의 가시성)
163 |
164 |
165 | #### 3.2 스프링 컨테이너의 종류
166 | 1. **BeanFactory**
167 |
168 | DI의 기본사항을 제공하는 가장 단순한 컨테이너이다.
169 | BeanFactory 는 빈을 생성하고 분배하는 책임을 지는 클래스
170 | 빈 자체가 필요하게 되기 전까지는 인스턴스화를 하지 않는다 (lazy loading)
171 |
172 | 2. **ApplicationContext**
173 |
174 | 빈팩토리와 유사한 기능을 제공하지만 좀 더 많은 기능을 제공한다.
175 |
176 | - 국제화가 지원되는 텍스트 메시지를 관리해 준다.
177 |
178 | - 이미지같은 파일 자원을 로드 할 수 있는 포괄적인 방법을 제공해준다.
179 |
180 | - 리스너로 등록된 빈에게 이벤트 발생을 알려준다.
181 |
182 | - Lazy Loading이 아니라 컨텍스트 초기화 시점에 모든 싱글톤 빈을 미리 로드한다.
183 |
184 | ## 4. AOP 와 Proxy
185 |
186 | https://minwan1.github.io/2017/10/29/2017-10-29-Spring-AOP-Proxy/
187 | > 모듈을 쉽게 사용할 수 있도록 해주는 것이라고 보는것이 편함
188 | 특정 로직이 수평으로 흐른다면, 수직으로 원하는 흐름을 꽂아주는 방식이다.
189 | 핵심로직을 구현한 코드를 컴파일하거나, 컴파일된 클래스를 로딩하거나, 또는 로딩한 클래스의 객체를 생성할 때, Proxy 객체를 통해 호출할 때 AOP가 적용됨
190 |
191 | ### AOP 기본
192 | #### 1. AOP 용어
193 | 1. **Advice**
194 | 언제 공통 관심 기능을 비즈니스 로직에 적용할 지 정의
195 | *예를들어,* '메서드를 호출 하기전에 트랜잭션 시작' 기능을 적용한다는 것을 정의하고 있는 것
196 |
197 | 2. **Joinpoint**
198 | Advice 를 적용 가능한 지점을 의미.
199 | 메소드 호출, 필드값 변경 등이 Joinpoint에 해당
200 |
201 | 3. **Pointcut**
202 | Joinpoint의 부분집합으로서 실제로 Advice가 적용되는 Joinpoint를 나타냄
203 | 스프링에서는 정규 표현식이나 AspectJ의 문법을 이용하여 Poincut을 재정의 할 수 있습니다.
204 |
205 | 4. **Weaving**
206 | Advice를 비즈니스 로직에 적용하는 행위
207 |
208 | 5. **Aspect**
209 | 여러 객체에 공통으로 적용되는 기능
210 | 트랜잭션, 보안 등이 Aspect의 좋은 예
211 |
212 | #### 2. Weaving 방식
213 |
214 | 1. 컴파일시에 Weaving하기
215 | 2. 클래스 로딩 시에 Weaving하기
216 | 3. 런타임시에 Weaving하기
217 |
218 | > 1,2 번 같은 경우는 AspectJ라이브러리를 추가하여 구현할때 사용됨.
219 | 런타임시 위빙같은 경우는 Spring-AOP 에서 사용하는 방식으로, 소스코드나 클래스 자체를 변경하는 것이 아니라 **프록시 객체** 를 사용하여 모듈을 Weaving 하고 비즈니스 로직을 실행한다.
220 |
221 | ***Proxy 를 이용한 런타임 위빙***
222 |
223 | 
224 |
225 | #### 3. Spring-AOP
226 | > 스프링은 자체적으로 프록시 기반의 런타임 AOP를 지원하고 있다.
227 | 따라서 11-2 에서 살짝 설명한 것과 같이,
228 | Spring-AOP는 ***메서드 호출*** Joinpoint 만을 지원함.
229 | 만약에 ***필드값 변경*** 과 같은 Joinpoint 를 사용하고 싶다면, AspectJ와 같이 다양한 Joinpoint를 지원하는 AOP프레임워크를 사용해야 한다.
230 |
231 | 또한 스프링은 3가지 방식으로 AOP를 제공한다.
232 |
233 | - XML 스키마 기반의 POJO클래스를 이용한 AOP구현
234 | - AspectJ에서 정의한 @Aspect 애노테이션 기반의 AOP구현
235 | - 스프링 API를 이용한 AOP구현
236 |
237 | **어떠한 방식을 사용하더라도 Proxy를 통한 메서드 호출만 AOP가 적용된다는것을 알아두자**
238 |
239 | #### 4. 프록시를 생성하는 방식
240 | > 어쨌든 실행해야 하는 비즈니스 로직이 있는 클래스에 대해 무조건 Bean 객체가 생성되는데, 스프링 컨테이너가 지정한 Bean 객체에 대한 프록시 객체를 생성하고, 원본 Bean 객체 대신에 Proxy 객체를 사용하게 된다. 이때 프록시 객체를 생성하는 방식은 인터페이스 여부에 따라 두가지 방식으로 나뉜다.
241 |
242 | 1. JDK Dynamic Proxy
243 | - 이는 인터페이스 기반으로 프록시 객체를 생성하기 때문에, 인터페이스에 정의되어있지 않은 메서드에는 AOP가 적용되지 않는 점을 주의해야 한다.
244 |
245 | 2. CGLIB
246 | - 인터페이스를 따로 구현하고 있지 않는 클래스는 CGLIB 방식으로 프록시를 생성한다.
247 | 이는 대상 클래스를 상속 받아 프록시를 구현하게 된다. 따라서 클래스가 final 인 경우는 프록시를 생성할 수 없고 private method 같은 경우에는 AOP 의 혜택을 받을 수 없다.
248 |
249 |
250 | ### Spring @Transactional 이 적용되지 않는 사례들
251 | > 스프링의 @Transactional annotation 은 Proxy Mode 와 AspectJ 모드로 동작한다.
252 | 일반적으로 많이 사용되는 것은 Proxy Mode 인데, 아무래도 Bean 이 아니라 프록시 객체를 이용하는 방법이다 보니, 의도치 않게 @Transactional 어노테이션이 동작하지 않는 사례들이 있다.
253 |
254 | 1. **private method에 @Transactional 달았을때**
255 |
256 | Service Bean 에서 메서드를 호출하는 것이 아니라, Proxy 객체가 메서드를 호출하게 되므로 당연히 @Transactional 어노테이션이 적용되지 않는다.
257 | 이 부분은 SonarLint 같은 정적 코드분석기도 알려주는 부분이라 발견하기 쉽다.
258 |
259 | 2. **메서드 안에서 내부 메서드 call**
260 |
261 | self call 에 관한 부분이다.
262 | 내부 클래스에서의 동일 메소드를 호출 할 때에는 Proxy 객체가 아닌 this 를 이용해 메소드를 호출하기 때문이다. 프록시로 특정 메서드를 불러냈어도 그 메서드 흐름 안의 internal method 는 Bean 이 호출한다.
263 | 따라서 프록시 객체에 의해 동작하는 Spring-AOP는 내부 method를 호출하는지 까지는 관심이 없다. 처음 프록시로 불러낸 메서드까지가 Proxy 관할 구역임
264 |
265 | *아래와 같은 코드는 무용지물이다.
266 | 프록시는 자신이 호출한 메서드 그 하나만 인식하는 것이다.*
267 |
268 | ~~~java
269 | @Transactional
270 | public void cancel(String orgFlwNo) {
271 | cancelTransaction(orgFlwNo);
272 | }
273 |
274 | public void cancelTransaction(String orgFlwNo) {
275 | TradeRepository.cancelTrade(orgFlwNo);
276 | userPointRepository.savePoint(CURRENT_USER_ID)
277 | }
278 | ~~~
279 |
280 | *당연히 아래와 같은 코드도 무용지물이다.
281 | 어차피 프록시가 호출하지 않을 메서드이기 때문 (태어날때부터 self call이 예견되어 있다.)*
282 | ~~~java
283 | public void cancel(String orgFlwNo) {
284 | cancelTransaction(orgFlwNo);
285 | }
286 |
287 | @Transactional
288 | public void cancelTransaction(String orgFlwNo) {
289 | TradeRepository.cancelTrade(orgFlwNo);
290 | userPointRepository.savePoint(CURRENT_USER_ID)
291 | }
292 | ~~~
293 |
294 |
295 | 헷깔릴 수도 있는데, 프록시는 메서드를 불러주는 대리인이다.
296 | 대리인은 말그대로 다른 클래스에서 호출하는 것과 마찬가지다.
297 |
298 | 위 코드에서 cancel 메서드는 외부에서 부르게 되는 시나리오의 메서드이고, 아래 cancelTransaction은 cancel 내부에서 호출하고 실행해야 의미가 있는 내부 메서드이다.
299 | *(위의 예제는 임시로 12.1 의 이유로 public scope로 되어 있음)*
300 |
301 | 따라서 proxy 입장에서 내부에서 호출해야만 하는 메서드에 아무리 @Transactional 을 달아봐야 외부인인 proxy 는 내부 메서드 cancelTransaction 의 흐름을 가로챌 기회가 없는 것이다.
302 |
303 | 3. **Try Catch 구문 안에서 사용할때**
304 |
305 | @Transactional 어노테이션은 비즈니스 로직 실행 뒤 Exception을 인식하고 처리한다.
306 | 따라서 로직 안에서 try - catch 를 해버리면 @Transactional이 예외를 인식하기도 전에 메서드 내부에서 예외를 catch 하게 되어 예외시 ROLLBACK이 불가능하다.
307 |
308 | ## 5. Spring MVC 동작 원리
309 |
310 | 
311 |
312 | 1. 웹 어플리케이션이 실행되면 Tomcat(WAS) 에 의해 배포서술자 `web.xml` 로딩
313 |
314 | 2. WAS 는 `web.xml` 에 등록되어 있는 ContextLoaderListener 생성
315 | - 자동으로 IoC container (ApplicationContext) 초기화
316 | - Servlet 을 사용하는 시점에 ServletContext 에 ApplicationContext 등록
317 | - Servlet 이 종료되는 시점에 ApplicationContext 삭제
318 |
319 | 3. 위에서 생성된 ContextLoaderListener는 `root-context.xml` 을 로딩
320 | - `root-context.xml` 은 Service , Repository 와 같은 bean 을 설정함
321 |
322 | 4. Root Spring Container 구동
323 | - ContextLoaderListener 가 `root-context.xml` 의 설정 기반으로 Root Spring Container 구동
324 |
325 | 4. 사용자 요청 받음
326 | - 최초의 클라이언트 요청이라면 DispatcherServlet 객체 생성
327 |
328 | 5. 두번째 Spring Container 구동 (By DispatcherServlet)
329 | - 두번째 스프링 컨테이너에는 컨트롤러 Bean 들이 들어 있고, 기존 root container 클래스를 상속받는다.
330 | - DispatcherServlet 객체는 `WEB-INF/config` 폴더에 있는
331 | servlet-context.xml` 파일을 로딩하여 두번째 스프링 컨테이너를 구동
332 | - servlet-context.xml을 보면 어노테이션을 스캔하여 bean 객체로 등록함을 볼 수 있음 (@Controller)
333 | - DispatcherServlet 이 **두번쨰 스프링 컨테이너** 를 구동 한다는 사실 기억할 것
334 |
335 | 6. DispatcherServlet 의 `doService()` 호출
336 | 1. `doService()` 에는 사용자의 요청을 처리하기 위한, Handler 과 Adapter 을 찾아 호출하기 위해 `doDispatch()` 호출
337 | 2. `doDispatch()` 에서는 HandlerMapping 을 통해서 요청에 맞는 Controller 의 HandlerMethod 를 찾고, HandlerMethod 를 호출할 수 있는 HandlerAdapter 찾음
338 | 3. HandlerAdapter 가 HandlerMethod 호출
339 |
340 | 7. Controller 요청 처리 후, Controller 는 ModelAndView , View 리턴
341 |
342 | 8. 리턴받은 View 는 ViewResolver가 먼저 받아 해당 view가 존재하는지 검색
343 |
344 | 9. DispatcherServlet은 ViewResolver 로 부터 JSP 등 최종 표시 결과를 받아서 최종 결과를 사용자에게 전송
345 |
346 | ## 6. JPA vs MyBatis
347 |
348 | ### 6-1) 영속성 (Persistence)
349 |
350 | - 데이터를 생성한 프로그램의 생명이 다하더라도, 데이터는 남아 있는 것
351 | - 따라서 우리는 데이터베이스(DISK) 를 통해 영속성을 부여한다.
352 | - Persistence Layer 는 데이터에 영속성을 부여해 주는 계층이다.
353 | - 여기서 JDBC 없이 영속성을 갖게 해 주는 도구가, Persistence Framework
354 |
355 | 
356 |
357 | ### 6-2) SQL Mapper 과 ORM
358 | Persistence Framework 는 두가지가 있다.
359 | #### 1. SQL Mapper
360 | - SQL **<- mapping ->** Object 필드
361 | - 대표적인 예로는 Mybatis 이고, 실제 SQL을 명시해 주어야 한다.
362 | - 직접 SQL을 많이 만져야 하는 쿼리가 있는 경우에 좋다.
363 | - XML 파일에 쿼리 쓰고 @Autowired 하는 방식
364 | > SQL Mapper의 Query는 xml로 관리되어지기 때문에 유지보수 과정에서 문제가 발생했습니다. 빌드 과정에서 오류를 발생시키지 않기 때문에 최악에는 SQL Query과 관련된 모든 Controller/Business/DAO Layer를 찾아서 유지보수 해야했습니다.
365 |
366 |
367 | #### 2. ORM (Object - Relation Mapping)
368 | - 객체와 RDB 테이블의 데이터를 자동으로 매핑해 주는 도구
369 | - SQL Query 대신 직관적인 method 로 트랜잭션 할 수 있다.
370 | - SQL을 자동으로 생성한다.
371 | - Persistence API 라고 할 수 있다.
372 | - Hibernate 는 JPA 의 구현체이다.
373 |
374 | #### 2-1) JPA 그리고 Hibernate
375 |
376 |
377 | - JPA 는 자바 어플리케이션에서 데이터베이스를 사용하는 방식을 정의한 인터페이스이다.
378 | - Hibernate 는 JPA를 구현한 구현체이다.
379 |
380 | #### 3. ORM의 장점과 단점
381 | #### 장점 :
382 | - 객체지향적인 코드로 직관적이고, 비즈니스 로직에 더 집중할 수 있다.
383 | - DBMS 에 종속적이지 않다.
384 | - 재사용 및 유지보수의 편리성이 증가한다.
385 | - JPA 경우 @Query 어노테이션을 사용하여 SQL을 직접 쓸 수 있으나, 복잡한 것 뺴고는 JPQL 이용하도록 함
386 |
387 | #### 단점 :
388 | - JPA의 내장 메소드로 해결되지 않는 쿼리가 많다.
389 | - 자주 사용되는 대형 쿼리는 별도의 튜닝이 필요한 경우가 있다.
390 | - 최적화된 SQL 쿼리를 사용할때는 MyBatis 가 낫다. (배우기 어렵)
391 | - 아래 링크 참조
392 | https://gmlwjd9405.github.io/2018/12/25/difference-jdbc-jpa-mybatis.html
393 | - ORM에 대한 개발자들의 생각
394 | https://okky.kr/article/286812
395 |
396 | ## 7. JAR vs WAR
397 | > class < jar < war < ear
398 |
399 | ### 5-1) JAR (Java Application Archive)
400 | - java class 파일 및 리소스파일(이미지, 텍스트 등)의 컨테이너이다.
401 | - jar 파일이 독립실행 되려면, 클래스 중 하나가 기본 클래스로 정의된다.
402 | - 실행 가능한 jar 파일은 아래 명령어로 실행된다. (spring 지원)
403 | ~~~
404 | java -jar foo.jar
405 | ~~~
406 |
407 | ### 5-2) WAR(Web Application aRchive)
408 | - 웹 어플리케이션을 저장하고 압축해 놓은 파일
409 | - html, JSP, 서블릿 소스 등이 컴파일 되어 저장되어 있다.
410 | - war는 WAS 위에서 돌아갈 수 있다.
411 | - Tomcat 위에 얹어서 디플로이한다.
412 |
413 | ## 7. 외장 톰캣 vs 내장 톰캣
414 | - 웹 서버 위에서 다른 WAS 과 함께 운영해야 한다면 외장 톰캣
415 | - 아니면 기존 레거시가 있거나 ..
416 | - 그럴필요 없다면 내장 톰캣을 써도 좋다.
417 | - D2 Naver 의 동영상 플랫폼 개발 팀도 embed 톰캣을 쓰더라
418 | https://d2.naver.com/helloworld/5626759
419 | https://zepinos.tistory.com/51
420 | ## 8. 스프링 Log
421 | - 스프링은 LogBack, Log4j 등 여러 로그 라이브러리를 지원한다.
422 | - Logback 이 Log4j 보다 10배이상 빠르고 메모리 효율성도 좋단다.
423 |
424 | ### Log Level (강한 로그 순서대로)
425 | 1) FATAL : 가장 크리티컬한 에러
426 | 2) ERROR : 에러
427 | 3) WARN : 에러는 아니지만 주의할 것
428 | 4) INFO : 일반 정보
429 | 5) DEBUG : 일반 정보를 좀 더 상세히 (옵션을 켜야 보임)
430 | 6) TRACE : 에러 시 경로 추적 (스택 트레이스 같은 것)
431 |
432 | ## 9. Maven vs Gradle
433 |
434 | - 둘다 빌드 툴이다.
435 | - 라이브러리 Dependency 를 관리한다.
436 | > Gradle 이 더 좋아보임 (출시 시기도 늦고 ANT, MAVEN 장점만을 모았다고 함)
437 |
438 | ### GRADLE
439 | - XML 기반의 Maven 빌드 설정보다 Gradle의 빌드 설정의 가독성이 더 좋다.
440 | - Gradle의 빌드 성능이 Maven의 빌드 성능보다 더 뛰어나다
441 | - **Groovy 기반의 DSL(domain-specific language)로 Gradle의 빌드 스크립트를 직접 작성할 수 있다.**
442 |
443 | ## 10. Spring TEST
444 |
445 | - 레일즈는 RSpec, Capybara 등 라이브러리 존재
446 | - 카피바라로는 패스트원 할떄 로그인, 메뉴진입 등 기본적인 View 기반 테스트 진행
447 |
448 | > 스프링부트는 처음 빌드 설정파일에 spring-boot-starter-test 넣으면 다 설치됨.
449 | 아래와 같은 것들이 포함된다고 한다.
450 |
451 | - JUnit — 자바 표준 단위 테스트 프레임워크
452 | - Spring Test — 스프링 부트 애플리케이션 테스트 지원을 위한 유틸리티
453 | - AssertJ — 어셜선 라이브러리
454 | - Hamcrest — 유용한 매처를 지원하는 객체 라이브러리
455 | - Mockito — 자바 모킹 프레임워크
456 | - JSONassert — JSON 어셜션 라이브러리
457 | - JsonPath — JSON 구조를 탐색할 때 유용한 라이브러리
458 |
459 | ## 11. JpaRepository save vs saveAll
460 | - save는 트랜잭션 하나에 한개 insert
461 | - saveAll은 트랜잭션 하나에 여러개 insert
462 | -> 트랜잭션 절약
463 | - saveAll 은 Batch 개수 설정도 가능
464 | spring.jpa.properties.hibernate.jdbc.batch_size=4
465 |
466 | ## 12. 스프링 배치
467 | - 일괄처리라는 뜻을 가지고 있음
468 | - WAS에서 대용량 처리로 인한 과부하 방지
469 | - 단발성 대용량 처리에 용이 (특정 시간 대용량 데이터 처리)
470 | - SpringQaurtz 등 스케줄러와 같이 쓰는 경우가 많음
471 |
472 | ### 스프링배치 어플리케이션의 조건
473 | - 대용량 데이터 - 배치 어플리케이션은 대량의 데이터를 가져오거나, 전달하거나, 계산하는 등의 처리를 할 수 있어야 합니다.
474 | - 자동화 - 배치 어플리케이션은 심각한 문제 해결을 제외하고는 사용자 개입 없이 실행되어야 합니다.
475 | - 견고성 - 배치 어플리케이션은 잘못된 데이터를 충돌/중단 없이 처리할 수 있어야 합니다.
476 | - 신뢰성 - 배치 어플리케이션은 무엇이 잘못되었는지를 추적할 수 있어야 합니다. (로깅, 알림)
477 | - 성능 - 배치 어플리케이션은 지정한 시간 안에 처리를 완료하거나 동시에 실행되는 다른 어플리케이션을 방해하지 않도록 수행되어야합니다.
478 |
479 | https://jojoldu.tistory.com/324
480 |
--------------------------------------------------------------------------------
/spring/spring_intermediate.md:
--------------------------------------------------------------------------------
1 | [목록으로](https://github.com/Donsworkout/techInterview/blob/master/README.md)
2 | ## SpringBoot in Project
3 |
4 | ### 1. 스레드 / 스레드 풀
5 | https://postitforhooney.tistory.com/entry/JavaThread-Java-Thread-Pool%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-Thread%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0Thread-Runnable
6 |
7 | 1. 스레드
8 | > 스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다. 이러한 실행 방식을 멀티스레드(multithread)라고 한다.
9 |
10 | 2. implements Runnable **VS** extends Thread
11 | > Runnable 은 자바의 다중상속에 대한 문제를 해결해 준다.
12 |
13 | 3. 스레드 풀
14 | https://limkydev.tistory.com/55
15 |
16 | - 병렬 작업 처리가 많아지면 Thread의 개수가 증가되고 어플리케이션의 성능이 저하됨
17 |
18 | - Thread Pool은 스레드를 미리 만들어 놓음
19 |
20 | - Thread Pool은 작업 처리에 사용되는 Thread를 제한된 개수만큼 정해 놓고 작업 큐(Queue)에 들어오는 작업들을 하나씩 Thread가 맡아 처리함
21 |
22 | \- Thread Pool도 과유불급이다. 너무 많이 만들어 놓으면 메모리 낭비 발생
23 |
24 | ### 2. ThreadPoolTaskExecutor 를 이용한 멀티쓰레드 구현
25 | https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/task/TaskExecutor.html
26 | > TaskExecutor 라는 이름의 인터페이스를 사용하여 Thread의 개수를 자동으로 조절하고 ThreadPoolTaskExecutor 를 추상화하는 execute() 메소드를 사용해 멀티쓰레드로 작업을 처리합니다.
27 |
28 | #### void execute(Runnable task)
29 | *Execute the given task.*
30 | ~~~
31 | The call might return immediately if the implementation uses an asynchronous execution strategy, or might block in the case of synchronous execution.
32 | ~~~
33 |
34 | execute() 함수의 인자로는 Runnable 인터페이스를 구현한 구현체가 들어가게 됨
35 | execute 는 Executor 인터페이스의의 메소드이다.
36 |
37 | ~~~
38 | Interface Executor - Interface TaskExecutor
39 | // 부모 인터페이스 - 자식 인터페이스
40 | ~~~
41 |
42 | ThreadPoolTaskExecutor 는 위의 인터페이스를 구현하는 구현체이다.
43 | 그리고 Interface AsyncListenableTaskExecutor 도 구현하고 있어 비동기 방식으로 작동한다.
44 |
45 | ~~~java
46 | taskExecutor.execute(ctx.getBean(실행할.class));
47 | ~~~
48 | 그리고 위의 코드는 실행할 Bean의 run method 를 자동으로 실행한다.
49 |
50 |
51 | 설정 파일 예시 (/config/ThreadConfig.java)
52 | ~~~java
53 | @Configuration
54 | public class ThreadConfig {
55 | @Primary
56 | @Bean
57 | public TaskExecutor taskExecutor() {
58 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
59 | executor.setCorePoolSize(50);
60 | executor.setMaxPoolSize(100);
61 | executor.setThreadNamePrefix("default_task_executor_thread");
62 | executor.initialize();
63 | return executor;
64 | }
65 | }
66 | ~~~
67 |
68 | ### 3. CompletableFuture
69 |
70 | Java7 부터는 Future 인터페이스를 통해서, 비동기 프로세스를 수행할 수 있었다.
71 | Future 클래스는 비동기 계산이 끝났는지 확인할 수 있는 isDone, 타임아웃 기간을 결정하고 결과를 출력하는 get 메소드 등이 있다.
72 |
73 | JAVA8 에서는 복잡한 비동기처리를 선언형으로 이용할 수 있는 CompleteableFuture 를 제공하며, Stream API 나 Optional 같이 람다표현식과 파이프라인을 사용하여 비동기 작업을 조합할 수 있습니다.
74 |
75 | 일부 상황에서는 굳이 CompletableFuture 를 쓸 필요가 없어보이지만,
76 | 병렬스트림과 달리 이를 이용한 방법은 executor 를 커스터마이징 할 수 있다.
77 |
78 | https://m.blog.naver.com/PostView.nhn?blogId=2feelus&logNo=220714398973&proxyReferer=https%3A%2F%2Fwww.google.com%2F
79 |
80 | #### 장점
81 |
82 | 1) 명시적 쓰레드 선언없이 쓰레드를 사용할수 있다.
83 |
84 | 2) 함수형 프로그래밍방식으로 비동기적으로 동시성/병렬 프로그래밍을 가능하게 함으로서 의도를 명확하게 드러내는 함축적인 프로그래밍을 가능하게 한다.
85 |
86 | 3) 각 테스크마다 순서적 연결을 할수도 있고, 테스크의 예외처리도 가능하다.
87 |
88 | 4) 태스크간 결합이 용이함
89 |
90 |
91 |
92 | ~~~java
93 | Stream.of(PartnerCode.values())
94 | .forEach( partner ->
95 | completableFutures.add(
96 | CompletableFuture.supplyAsync(() ->
97 | getUserInfoForView(userCi, partner))
98 | .exceptionally(e -> {
99 | LOGGER.info(e.toString());
100 | return new UserInfoForView().setPartnerInfo(partner.getPartnerCode());
101 | })));
102 |
103 |
104 | completableFutures.stream()
105 | .forEach(future ->
106 | userInfoList.add(getUserInfoForViewFromFuture(future))
107 | );
108 | ~~~
109 |
110 |
111 | ### 4. Properties -> Yaml
112 | > yml 파일은 계층 구조를 표현할 수 있는 장점이 있고,
113 | config 클래스를 따로 정의했다면, prefix, 필드명을 yml 파일 명세와 잘 일치시키면 자동으로 설정값을 주입할 수 있다. 게다가 List 나 Map 같은 구조로 설정 값을 주입시킬 수 있다.
114 |
115 | 1. pom.xml 파일에 의존성 추가 (spring-boot-configuration-processor)
116 | ~~~xml
117 |
118 | org.springframework.boot
119 | spring-boot-configuration-processor
120 | 2.1.6.RELEASE
121 |
122 | ~~~
123 |
124 | 2. yml 파일 명세
125 | ~~~yml
126 | #Hana
127 | socket:
128 | serverAddress: 127.0.0.1
129 | serverPort: 8082
130 | timeout:
131 | checkRequest: 2000
132 | useRequest: 2000
133 | cancelRequest: 2000
134 | delivery: 2000
135 | checkSave: 2000
136 | ~~~
137 |
138 | 3. 설정 클래스 명세
139 | ~~~java
140 | @Setter
141 | @Getter
142 | @Component
143 | // prefix yaml 파일 명세와 잘 맞출 것
144 | @ConfigurationProperties(prefix="socket")
145 | public class SocketConfig {
146 | private String serverAddress;
147 | private int serverPort;
148 | // timeout의 하위 attr 들을 맵 형태로 매핑할 수 있다.
149 | private Map timeout;
150 | }
151 |
152 | ~~~
153 |
154 | ### 5. 여러 Yaml 설정파일 추가하기
155 | > SpringApplicationBuilder 를 활용해 간단하게 설정할 수 있다.
156 | ~~~java
157 | @SpringBootApplication
158 | public class MyApplication {
159 |
160 | private static final String PROPERTIES =
161 | "spring.config.location="
162 | +"classpath:/application.yml"
163 | +",classpath:/config.yml";
164 |
165 | public static void main(String[] args) {
166 | new SpringApplicationBuilder(MyApplication.class)
167 | .properties(PROPERTIES)
168 | .run(args);
169 | }
170 |
171 | }
172 | ~~~
173 |
174 | ### 6. SpringApplicationBuilder
175 | [SpringApplicationBuilder 공식문서 확인](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/builder/SpringApplicationBuilder.html)
176 |
177 | ***그냥 앱 실행이라면 아래 방법이 제일 편함***
178 | ~~~java
179 | public static void main(String[] args) {
180 | SpringApplication.run(MyApplication.class, args);
181 | }
182 | ~~~
183 |
184 | ***그러나 실행시 Fluent builder API를 사용하기 위해 SpringApplicationBuilder 을 사용한다***
185 | + 체인 방식의 메서드 Call 을 지원한다.
186 | + 계층을 표현할 수 있다
187 |
188 | ~~~java
189 | new SpringApplicationBuilder()
190 | .showBanner(false)
191 | .sources(Parent.class)
192 | .child(Application.class)
193 | .run(args);
194 | ~~~
195 |
196 | ***아무튼 앱을 실행하는데에는 아래와 같은 방법들이 있다.***
197 | ~~~java
198 | @SpringBootApplication
199 | public class Application {
200 | public static void main(String[] args) {
201 | // 방법 1 - static
202 | SpringApplication.run(Application.class);
203 |
204 | // 방법 2 - make instatnce
205 | SpringApplication app = new SpringApplication(Application.class);
206 | app.run(args);
207 |
208 | // 방법 3 - Builder
209 | new SpringApplicationBuilder()
210 | .sources(Application.class)
211 | .run(args);
212 | }
213 | }
214 | ~~~
215 |
216 | ### 7. Spring Retry
217 | https://github.com/spring-projects/spring-retry
218 | https://www.baeldung.com/spring-retry
219 |
220 | > Spring Retry 는 실패한 작업에 대해 재시도 할 수 있도록 도와준다.
221 | 이는 로직 등 개발자의 실수에 의한 에러보다는 일시적인 에러에 적합하다 (네트워크 장애 등)
222 | 장애가 발생할 수 있는 메서드 위에 **@Retryable** 어노테이션을 이용하여, 특정 예외에 맞는 재시도 횟수, 재시도 BackOff 시간 등을 설정할 수 있다.
223 |
224 | 1. pom.xml 의존성 추가
225 | ~~~java
226 |
227 | org.springframework.retry
228 | spring-retry
229 | 1.1.5.RELEASE
230 |
231 | ~~~
232 |
233 | 2. Configuration에 @EnableRetry 어노테이션 추가
234 | ~~~java
235 | @Configuration
236 | @EnableRetry
237 | public class AppConfig { ... }
238 | ~~~
239 |
240 | 3. 일시적 장애가 우려되는 메서드에 @Retryable 어노테이션 추가
241 | ~~~java
242 | @Service
243 | public interface MyService {
244 | @Retryable(
245 | value = { SQLException.class },
246 | maxAttempts = 2,
247 | backoff = @Backoff(delay = 5000))
248 | void retryService(String sql) throws SQLException;
249 | ...
250 | }
251 | ~~~
252 |
253 | 4. 지정된 재시도 횟수만큼 시도했는데 실패했을때 대한 failback 메서드 작성
254 | > 첫번째 인자로 발생한 예외를 넘겨주고, 그 뒤에는 순서대로 원래 메서드의 인자를 적어주면 된다. failback 매서드의 리턴값은 원래 메서드의 리턴값 형식과 같다.
255 | ~~~java
256 | @Service
257 | public interface MyService {
258 | ...
259 | @Recover
260 | void recover(SQLException e, String sql);
261 | }
262 | ~~~
263 |
264 | 5. 테스트 등 필요하면 RetryTemplate 이용한다.
265 | ~~~java
266 | @Configuration
267 | public class AppConfig {
268 | //...
269 | @Bean
270 | public RetryTemplate retryTemplate() {
271 | RetryTemplate retryTemplate = new RetryTemplate();
272 |
273 | FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
274 | fixedBackOffPolicy.setBackOffPeriod(2000l);
275 | retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
276 |
277 | SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
278 | retryPolicy.setMaxAttempts(2);
279 | retryTemplate.setRetryPolicy(retryPolicy);
280 |
281 | return retryTemplate;
282 | }
283 | }
284 |
285 | ~~~
--------------------------------------------------------------------------------