├── API
└── HttpAPI.md
├── AWS
├── EC2.md
├── Route53.md
├── UseEC2.md
└── meterial
│ ├── createInstance.png
│ └── resilientIp.png
├── CS
├── IO-multiplexing.md
├── JIT.md
├── PCB-IPC-ContextSwitching.md
└── interpreter-compile.md
├── DesignPattern
├── DesignPattern.md
├── Singleton.md
└── strategy-pattern.md
├── DevFeed
├── CICD.md
├── CohesionAndCoupling.md
├── GraphQL.md
├── JPQL.md
├── LearningCurve.md
├── Nginx-Apache-compare.md
├── PG.md
├── Parameter,Argument.md
├── PromiseToAwait.md
├── SQLD.md
├── TDD.md
├── URI.md
├── githubLicense.md
├── h2db.md
├── mysql-reset.md
└── on,off-premise.md
├── DevOps
├── HttpsConnect.md
├── IaaS,PaaS,SaaS.md
├── Introducing-Vault.md
├── RDS-fatal-error.md
├── Ubuntu+EC2.md
├── docker.md
├── docker
│ ├── dockercompose.md
│ └── springboot-docker.md
├── notion-targeting.md
├── solve-50x-error.md
├── springbootDocker.md
├── themoment-v1.1.1-issue.md
├── tooManyRedirection.md
└── use-nohup.md
├── Extra
├── nest
│ └── fast-nest-env.md
└── node
│ └── error-solution.md
├── GitHub
└── delPush.md
├── Lecture
├── JAVA
│ ├── CompletableFuture.md
│ ├── DI-impl.md
│ ├── FunctionalInterface.md
│ ├── GC.md
│ ├── HashMap.md
│ ├── IS-A.md
│ ├── Immutable-with-string.md
│ ├── JVM-JRE-JDK.md
│ ├── JVM.md
│ ├── Lambda-expression.md
│ ├── MyAnnotation.md
│ ├── POJO.md
│ ├── Procedure-oriented&object-oriented.md
│ ├── Reference-veriable.md
│ ├── Serialization.md
│ ├── WrapperClass.md
│ ├── async-nonblocking.md
│ ├── builder-pattern.md
│ ├── checked-unchecked-exception.md
│ ├── classLoader.md
│ ├── comparable-compareTo.md
│ ├── constructor.md
│ ├── defualt-const.md
│ ├── distinct-arrayList-item.md
│ ├── generics-harcore.md
│ ├── how-working-DI.md
│ ├── interface-defualt-static.md
│ ├── invent-bytecode.md
│ ├── java-8-defualt-static-method.md
│ ├── java-callable-future.md
│ ├── java-collection.md
│ ├── java-completableFuture-callback.md
│ ├── java-executors.md
│ ├── java-method-reference.md
│ ├── java-runtime-memory.md
│ ├── java-thread.md
│ ├── javaIsCallByValue.md
│ ├── lambda.md
│ ├── multi-thread.md
│ ├── optional.md
│ ├── prac_interview_java.md
│ ├── reflection-1.md
│ ├── shallowcopy-deepcopy.md
│ ├── stream.md
│ ├── tech-interview.md
│ ├── thread.md
│ └── understand-generic.md
├── OOP
│ ├── OCP.md
│ └── singleTon.md
├── algorithm
│ ├── DFS.md
│ ├── bubbleSort.md
│ ├── counting-sort.md
│ ├── insertionSort.md
│ └── selectionSort.md
├── recode
│ └── variousNotation.md
└── 한번에 끝내는
│ └── README.md
├── Network
├── Proxy.md
├── cache.md
└── spring-security.md
├── README.md
├── README_legacy.md
├── Spring
├── Concept
│ ├── Api.md
│ ├── Auditing.md
│ ├── DBMS.md
│ ├── ErrorVsException.md
│ ├── Redis.md
│ ├── SOLID.md
│ ├── SpringAnnotation.md
│ ├── SpringBean.md
│ ├── Swagger.md
│ ├── TDD.md
│ ├── library
│ │ ├── Time-complexity.md
│ │ └── slf4j.md
│ ├── server.md
│ ├── webSpec.md
│ └── whatIsSDK.md
├── JPA
│ ├── JpaEntity.md
│ ├── N+1.md
│ ├── Querydsl.md
│ ├── can'tReturn2Result.md
│ ├── column-mapping-wrapperclass.md
│ ├── ddl-auto.md
│ ├── extendsRelation.md
│ ├── findby.md
│ ├── flush.md
│ ├── improvement-query-perfomance.md
│ ├── jpa-jpql-querydsl.md
│ ├── mad-jpa.md
│ ├── managed-context.md
│ ├── mappedBy.md
│ ├── querydsl-in-maven.md
│ ├── transaction.md
│ └── warn-querydsl.md
└── SpringBoot
│ ├── @BootstrapWith-error.md
│ ├── @Configuration.md
│ ├── @NoArgs.md
│ ├── CORS.md
│ ├── EJB.md
│ ├── JubJubStrcture.md
│ ├── Lombok.md
│ ├── MockMvc-test.md
│ ├── ModelMapperEntity.md
│ ├── PSA.md
│ ├── ThreadPool.md
│ ├── bean-life-cycle.md
│ ├── bean-scope-prototype-scope.md
│ ├── builder-in-inheritance.md
│ ├── dependency-option.md
│ ├── dispatcherServlet.md
│ ├── error-hikari.md
│ ├── getClientIp.md
│ ├── gradle-6-to-7.md
│ ├── jar-html-execute.md
│ ├── java-spring-singleton.md
│ ├── modelmapper-love.md
│ ├── modular-monoliths.md
│ ├── persistence-context-with-transactional.md
│ ├── singleton-container.md
│ ├── singleton-prototype-mixed-error.md
│ ├── solve-with-provider.md
│ ├── spring-bean-cycle-error.md
│ ├── spring-bean-life-cycle.md
│ ├── spring-bean-sigleton.md
│ ├── spring-mvc-lifecycle.md
│ ├── spring-restdocs.md
│ ├── springboot-async.md
│ └── springboot-principle-of-motion.md
├── backend
├── architecture
│ ├── SOA-MSA.md
│ └── restapi.md
├── etc
│ └── sentry-logging.md
└── jwt
│ ├── jwt-dependency-duplicate.md
│ └── jwt-http-header-type.md
├── experience
├── ES.md
└── puppeteer.md
├── http
├── 2xx-success.md
├── 3xx-redirection.md
├── 4xx-client-error.md
├── 5xx-server-error.md
├── DNS.md
├── GET-POST.md
├── HTTP-method.md
├── HTTP-status-code.md
├── Negotiations.md
├── Representation.md
├── TCP-UDP.md
├── URI.md
├── everything-http.md
├── http-header-intro.md
├── http-method-use.md
├── internet-network.md
├── ip.md
├── port.md
├── put-patch-delete.md
├── web-browser-flow.md
└── 재영-질문-1.png
├── img
├── ACM_Certification.png
├── ApplicationLoadBanlancer.png
├── BiFunction-apply-ab-method.png
├── CGLIB-keep-singleton.png
├── DI-interface.png
├── DI-st.jpg
├── ELB-error-solved.png
├── FI-lecture.png
├── Functional-Interface.png
├── GoF-Design.png
├── HttpServlet-동작과정.png
├── Iaas,SaaS,PaaS_구분.png
├── JIT-todo.png
├── JPA-JDBC.png
├── JPA-history.png
├── JVM-Heap.jpeg
├── JVM-JRE.png
├── JVM-structure.jpg
├── Java-memory-management.png
├── JavaEE-servlet.png
├── LB-Create.png
├── LB-setting1.png
├── ModelMapperCode.png
├── ModelMapperRes.png
├── N+1-entity.png
├── NotChangeCode.png
├── OCP-find.png
├── OWASP.png
├── Obejct-hashCode.png
├── PCB-TCB.jpeg
├── PSA-diagram.png
├── RDS-fatal-error.png
├── SOA-concept.png
├── SOF-cbv-cbr-my-think.png
├── Serialization-example.png
├── Spring-rest-docs.png
├── Thread.png
├── TooManyRedirection.png
├── abstract-method-java-docs.png
├── add-source-folders.png
├── answer-uncomfortable-table-diagram.png
├── application-context-structure.png
├── application-context.jpg
├── arr-deep-copy.png
├── arr-foreach-java8.png
├── arrayList-bigO.png
├── async-console.png
├── async-processing.png
├── async_ex.png
├── authentication-jwt.png
├── aws_route53_enter.png
├── base64.png
├── basic-DI-success.png
├── big-O-complexity-chart.png
├── blocking-ex.png
├── blocking-process.png
├── bootstrap-classLoader-why-null.png
├── bubble-sort.png
├── builder-cannot-hide.png
├── cache.png
├── can't return 2 result.png
├── cause-bean-no-qualifying.png
├── class-reflection-options.png
├── classLoader-parent-console.png
├── classLoader-system.png
├── comparable-compareTo.png
├── completable-console-uppercase.png
├── completableFuture-console.png
├── container-magic.png
├── csrf-attack.jpg
├── daangn-company.png
├── db-engines-ranking.png
├── db-예약어-주의.png
├── dispatcher-servlet.png
├── dispatcherServlet-diagram.png
├── docker-compose-cache-clear-search.png
├── docker-resource-limit.png
├── drop-table.png
├── em-1st-chache.png
├── em-find-logic.png
├── empty-console.png
├── error-ddl-auto.png
├── front-controller.png
├── gabege-collector.gif
├── generic-console.png
├── generic-type.png
├── getBeanTypeMoreThanTwo.png
├── getConnection-flow.png
├── getFields.png
├── goodbye.jpeg
├── h2DB_down.png
├── has-a-method-two.png
├── has-a-method.png
├── hashcode-return.png
├── hashicrop-vault.png
├── hate-modelmapper.png
├── hbm2ddl-auto-resolved.png
├── hibernate-nullable.png
├── hikari-error-solution.png
├── http
│ ├── 201-created.png
│ ├── 301-영구-리다이렉션.png
│ ├── 302-리다이렉트의-좋은-예.png
│ ├── 308-영구-리다이렉션.png
│ ├── API-URI-설계-어떻게-구분하지.png
│ ├── DNS의-사용.png
│ ├── F5-야매.png
│ ├── HTML-Form-POST.png
│ ├── HTML-GET-조회.png
│ ├── HTTP-GET-flow.png
│ ├── HTTP-GET.png
│ ├── HTTP-POST.png
│ ├── HTTP-메시지-전송.png
│ ├── HTTP-메시지.png
│ ├── HTTP-응답-메시지.png
│ ├── HTTP-패킷-생성.png
│ ├── IP-주소부여.png
│ ├── PATCH-without-feild.png
│ ├── PUT-HTTP-message.png
│ ├── PUT-method-with-resource.png
│ ├── PUT-method-without-feild.png
│ ├── PUT-method-without-resource.png
│ ├── TCP-3-way-handshake.png
│ ├── TCP-UDP-패킷-정보.png
│ ├── URI.png
│ ├── URL-URN.png
│ ├── accept-lang.png
│ ├── auto-redirection.png
│ ├── content-language.png
│ ├── content-type.png
│ ├── http-attribute.png
│ ├── http-body.png
│ ├── http-header-short.png
│ ├── http-header.png
│ ├── post-정리.png
│ ├── rfc-2616.png
│ ├── rfc-7230-http-body.png
│ ├── socket-TCP.png
│ ├── stackoverflow-ex1.png
│ ├── stateful-server.png
│ ├── stateless-error.png
│ ├── static-data-get.png
│ ├── 구글에게-패킷-전달.png
│ ├── 리다이렉션-실무-권장-사양.png
│ ├── 복잡한-인터넷망.png
│ ├── 서버-패킷-전달.png
│ ├── 아이피는-기억하기-어렵다.png
│ ├── 웹브라우져-url-파싱.png
│ ├── 응답-HTTP-패킷.png
│ ├── 인터넷-통신-궁금증.png
│ ├── 인터넷-프로토콜-계층.png
│ ├── 인터넷-프로토콜-스택-4계층.png
│ ├── 쿼리파라미터사용-동적데이터조회.png
│ ├── 클라이언트-패킷-전달.png
│ ├── 패킷-구조.png
│ └── 한번에-둘-이상-연결해야-하면.png
├── insertion-sort.png
├── interface-member-constraint.png
├── invokeAll-api-docs.png
├── java-checked-unchecked-exceptions-2.png
├── java-checked-unchecked-exceptions.png
├── java-default-functional-interface.png
├── java-runTime-area.png
├── java-runtime-area-st.png
├── jcf-st.png
├── jpa-column-wrapper-console.png
├── jpa-persistence-API.png
├── jvm-st.png
├── jwt-dependency-duplicate.png
├── logtail.jpeg
├── managed-context-life-cycle.png
├── mixed-scope.png
├── modelMapper-result.png
├── monolithic-microservice.png
├── multi-thread.jpg
├── newSingleThreadExecutorEx.png
├── node-tree.png
├── node-update-need.png
├── non-blocking-callback.png
├── non-blocking-process.png
├── not-spring-container-warn.png
├── notLiteral.png
├── oauth-data-flow.png
├── parallelStream-console.png
├── pass-array-pointer-value.png
├── point-thesame-heap-memory.png
├── primitive-reference-type-heap-memory.png
├── project-st.png
├── prototype-bean-life-cycle.png
├── proxy-mode-in-transactional.png
├── puppeteer.png
├── query-per-entity-diagram.png
├── querydsl-file-st.png
├── rds-error-method.png
├── rds-security.png
├── recode_create.png
├── reflection-정리.png
├── route53_nameServer.png
├── routing_setting.png
├── search-reason-why.png
├── security-group-setting.png
├── security-mysql.png
├── selection-sort.png
├── serial-collector.jpeg
├── serialization.png
├── servlet.png
├── should-to-make-interface.png
├── singleton-bean.png
├── singleton.png
├── socar-myResult-console.png
├── sof-ref-is-ref.png
├── solved 1 result return.png
├── sorting-algorithms.png
├── spring-mvc-dispatcherServlet.png
├── spring-mvc-lifecycle-st.png
├── ssl-setting.png
├── static-dynamic-page.png
├── static-method-in-oracle.png
├── strategy-example.png
├── strategy-pattern-structure.png
├── stream-lazy.png
├── stream-worked.png
├── stream-동작방식.png
├── sub-super-class.png
├── submit-cancle.png
├── sync-processing.png
├── sync_ex.png
├── target-adding.png
├── target-sort.png
├── template_pattern.png
├── thread-currentThread.png
├── thread-group.gif
├── thread-native.png
├── thread-runnable.png
├── thread-wake-3seconds-after.png
├── time-complexity.png
├── transactional-based-aop.png
├── tryAdvance.png
├── vault-secret-backends.png
├── vault-storage-backends.png
├── webpack-error-module-not-found.png
├── wrapper-class-boxing.png
├── wrapper-class-st.png
├── wrapper-console-result.png
├── wtf.jpg
├── 결합도.png
├── 결합도가_높다.png
├── 응집도.png
├── 응집도가_높음.png
└── 응집도가_약함.png
├── organization
├── Agile.md
├── AgileCulture.md
└── startup-expression.md
└── tobby
├── interests.md
├── objectDi.md
└── templatePattern.md
/API/HttpAPI.md:
--------------------------------------------------------------------------------
1 | # **HTTP API 설계**
2 |
3 | ## **📄 INDEX**
4 | 1. HTTP API - 컬렉션
5 | * POST 기반 등록
6 | * 예) 회원 관리 API 제공
7 |
8 | 2. HTTP API - 스토어
9 | * PUT 기반 등록
10 | * 예) 정적 컨텐츠 관리, 원격 파일 관리
11 |
12 | 3. HTTP FORM 사용
13 | * 웹 페이지 회원 관리
14 | * GET, POST 만 지원
15 |
16 | ## **API 설계 - POST 기반 등록**
17 | ### 1️⃣ 회원 관리 시스템
18 | * 회원 목록/members -> GET
19 | * 조건이 있다면 쿼리 파라미터에 추가해서 전달하면 된다.
20 |
21 | * 회원 등록/members -> POST
22 | * 회원 조회/members/{id} -> GET
23 | * 회원 수정/members/{id} -> PATCH, PUT, POST
24 | * 보통 게시글 수정의 경우 부분이 바뀌더라도 PUT으로 일괄 변경 처리한다.
25 |
26 | * 회원 삭제/members/{id} -> DELETE
27 |
28 | ### 2️⃣ POST - 신규 자원등록 특징
29 | * 클라이언트는 등록될 리소스의 URL를 모른다.
30 | * 회원등록/members -> POST
31 | * POST/members
32 |
33 | * 요청 메시지를 받은 서버가 새로 등록된 리소스의 URL을 생성해준다.
34 | * HTTP/1.1 201 Created
35 | * Location: /members/100
36 |
37 | * 컬렉션(Collection)
38 | * 서버가 관리하는 리소스 디렉토리
39 | * 서버가 리소스의 URL을 생성하고 관리한다
40 | * 여기서의 컬렉션은 /members
41 |
42 | > POST는 클라이언트가 서버에게 이 리소스를 등록해달라고 요청한다.
43 | > 그러면 서버는 해당 리소스의 URI를 만들어서 돌려준다.
44 |
45 | ## **API 설계 - PUT 기반 등록**
46 | ### **📄 파일 관리 시스템**
47 | * 파일 목록/files -> GET
48 | * 파일 조회/files/{filename} -> GET
49 | * 파일 등록/files/{filename} -> PUT
50 | * 기존 파일이 있어도 덮어쓴다.
51 |
52 | * 파일 삭제/files/{filename} -> DELETE
53 | * 파일 대량 등록/files -> POST
54 | * POST는 상황에 맞게 쓸 수 있다. 이번 경우에는 대량 등록을 위해 사용
55 |
56 | ### **PUT - 신규 자원 등록 특징**
57 | > 등록을 위해 POST 대신 PUT을 사용하고 있다. 어떤 차이점이 있을까?
58 |
59 | * 클라이언트가 리소스 URL를 알고 있어야 한다.
60 | * 파일 등록/files/{filename} -> PUT
61 | * PUT /files/start.png
62 |
63 | * 클라이언트가 직접 리소스의 URL을 지정한다.
64 | * 스토어(store)
65 | * 클라이언트가 관리하는 리소스 저장소
66 | * 클라이언트가 리소스의 URI를 알고 관리한다
67 | * 여기서 스토어는 /files
68 |
69 | > PUT은 클라이언트가 관리하는 리소스의 URL을 지정해서 서버에게 등록해달라고 요청한다.
70 | > 그러면 서버는 해당 리소스를 전달 받은 URI에 등록해준다.
71 |
72 | **"대부분 POST기반의 Collection의 관리 시스템을 사용한다."**
--------------------------------------------------------------------------------
/AWS/EC2.md:
--------------------------------------------------------------------------------
1 | # AWS EC2 란 무엇이며, 기업들이 왜 EC2를 선택할까
2 | ## AWS EC2의 주요 기능과 이점
3 | ### **주요기능**
4 | Amazon EC2는 웹서비스 인터페이를 사용해 다양한 운영 체제로 인스턴스를 시작하고, 이를 사용자 정의 애플리케이션 환경으로 로드하며, 네트워크의 엑세스 권한을 관리하고, 원하는 수의 시스템을 사용해 이미지를 실행 할 수 있는 진정한 가상 컴퓨팅 환경을 제공한다.
5 |
6 | ### **이점**
7 | * 베어 메탈 인스턴스
8 | * AWS EC2 플릿을 사용해 컴퓨팅 성능과 비용을 최적화
9 | * 인스턴스 일시 중지 및 다시 시작
10 | * GPU 컴퓨팅 인스턴스
11 | * GPU 그래픽 인스턴스
12 | * 높은 I/O 인스턴스
13 | * 고밀도 HDD 스토리지 인스턴스
14 | * 최적화된 GPU 구성
15 | * 탄력적 IP 주소
16 | * HPC(고성능 컴퓨터)클러스터
17 | * 다양한 운영체제
18 | * AWS marketplace를 통한 다양한 소프트웨어
19 |
20 | ### **탄력성 있는 웹 스케일 컴퓨팅**
21 | AWS EC2를 사용하면 몇 시간 또는 며칠이 아닌 몇 분 내에 용량을 늘리거나 줄일 수 있습니다.
22 | 한 개, 수백 개 또는 수천 개의 서버 인스턴스를 동시에 지정할 수 있습니다.
23 | 또한 AWS EC2 통해 EC2 플릿의 가용성을 유지하고 필요에 따라 집합을 자동으로 확장 및 축소하여 성능을 극대화하고 비용을 최소화할 수 있습니다.
24 | 여러 서비스의 크기를 조정하려면 AWS Auto Scaling을 사용하면 됩니다.
25 |
26 |
27 | ### **쨋든 이게 EC2 입니다**
--------------------------------------------------------------------------------
/AWS/Route53.md:
--------------------------------------------------------------------------------
1 | # Amazon Routes 53
2 | ## AWS Community Day - Route53 - 서태호
3 |
4 | ### **1. Route 53 이란?**
5 | AWS에서 제공하는 DNS(Domain Name System)이다.
6 | Route 53 = 일반 DNS 기능(네임서버) + 모니터링기능 + L4기능(SLB) + GSLB 기능을 지원한다.
7 |
8 | ### **2. 일반 DNS에 대한 이해**
9 | **DNS 동작과정은 네트워크 통신을 하기위해 IP를 찾아가는 과정이다.**
10 |
11 |
12 | ### **3. 일반 DNS와 차이점**
13 |
14 | **-일반 DNS**
15 | 도메인 등록 시 네임서버를 지정한다.
16 | ```mattzip.com``` 도메인 등록시, 등록 대행기관에 네임서버를 등록한다.
17 |
18 |
19 | **-Route 53**
20 | Route 53 사이트에서 네임서버를 할당받은 후,
21 | 도메인등록 대행기관 사이트에 접속해 정보를 등록한다.
22 |
23 |
24 | > Route 53 에는 레코더 ALIAS(별칭)이 있다.
25 | > 도메인 자체에 ALIAS를 줄 수 있다.
26 |
27 | **ex) ```mattzip.com```을 치면 ```www.mattzip.com``` 과 같이 응답하게 해주는것이 가능하다.**
28 |
29 | > Route 53은 모니터링 기능이 있다.
30 | > Route 53은 L4 기능이 있다.
31 |
32 |
33 |
34 | > Route 53의 GSLB 기능
35 |
36 |
37 |
38 | 이외에도,
39 | Route 53 Failover
40 | ex) If A route is dead, B route Backup
41 |
42 |
43 | Route 53 Act-Act(트래픽 조절)
44 |
45 | 등 등 등 등
--------------------------------------------------------------------------------
/AWS/meterial/createInstance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/AWS/meterial/createInstance.png
--------------------------------------------------------------------------------
/AWS/meterial/resilientIp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/AWS/meterial/resilientIp.png
--------------------------------------------------------------------------------
/CS/IO-multiplexing.md:
--------------------------------------------------------------------------------
1 | # I/O Multiplexing
2 | > 네트워크 프로그램을 아무 생각없이 구현하면..
3 | > I/O blocking이 발생해서 여러개의 다른 클라이언트 접속을 허용하지 않거나 성능 저하를 겪는 경우가 발생한다.
4 |
5 | * Fork: 프로세스를 새로 만드는 방법으로 클라이언트 요청이 있을때마다 프로세스를 복사하여 여러 사용자에게 제공.
6 | * Threads: 프로세스 방법이 아닌 쓰레드를 생성해서 여러 사용자들에게 제공.
7 | * I/O Multiplexing: 여러 소켓에 대해 I/O를 병향적으로 하는 기법 다수 프로세스 혹은 스레드를 만들지 않고 여러 파일을 처리할 수 있다.
8 | * 비동기 I/O: 비동기적으로 처리하는 기법. 시그널이 병행되어 존재함.
9 | * Event Driven I/O: multiplexing을 추상화 함 libev, pyev, libevent 라이브러리가 있음.
10 |
--------------------------------------------------------------------------------
/CS/JIT.md:
--------------------------------------------------------------------------------
1 | ## JustInTime 컴파일
2 | > CS 나 프로그래밍언어에서 사용하는 용어.
3 | > C나 C++에서 하는 것처럼 프로그램을 실행하기 전에 한번 컴파일 하는 대신, 프로그램을 실행하는 시점에서 필요한 부분을 즉석으로 컴파일하는 방식을 말한다.
4 |
5 | 보통 인터프리터 방식의 언어 구현들이 성능 향상을 목적으로 도입하는 경우가 많음.
6 |
7 | JIT 컴파일러는 같은 코드를 매번 해석하는 대신 처음에 실행될 때 인터프리트를 하면서 자주 쓰이는 코드를 캐싱한 뒤, 이후에는 캐싱된 코드를 가져다 쓰기 때문에 인터프리터의 느린 실행 속도를 개선할 수 있다.
8 |
9 | 바이트코드 컴파일을 사용하는 Java도 바이트코드를 기계어로 번역할 때 JIT 컴파일러를 사용한다.
10 |
11 | 단점이라면.. 초기 구동시에는 소스코드를 실행단계에서 컴파일 하는데에 시간과 메모리를 소모하기 때문에 정적 컴파일된 프로그램에 비해 속도면에서 손해를 본다.
12 |
13 | 특히 시간이 매우 짧은 경우에는 애써 컴파일된 코드를 제대로 울궈먹기도 전에 프로그램이 끝나는 배보다 배꼽이 더 큰 상황이 벌어진다.
14 |
15 | ### 컴파일 방식
16 | 1. 메서드 단위로 JIT 컴파일
17 | 2. Tracing JIT 컴파일
18 |
19 | `2 Tracing JIT` 의 경우 실행 시점에만 알 수 있는 정보를 컴파일에 적극적으로 반영하기 때문에 이론적으로는 정적 컴파일 방식보다 컴파일 속도가 더 빨라질 수도 있다.
20 |
21 | 하지만 JIT 컴파일러는 미리 컴파일된 코드를 실행하는 것이 아닌, 런타임에 동적으로 코드를 생성하여 실행한다는 특징 때문에 잠재적으로 많은 보안 문제를 가지고 있다.
22 |
23 | 대표적으로 인텔 CPU 게이트로 유명한 스펙터 보안취약점은 JIT에 의존하는 JS엔진을 가진 브라우저에서만 발생했다. `HotSpot VM` 또한 JIT 컴파일러 버그로 인한 다수의 보안 취약점이 있다.
24 |
25 | 참고로 ios에서는 상기한 보안문제를 이유로 네트워크로 바이너리나 코드를 다운받아 실행하는 것을 금지하고 있다. `ex) dropbox 마크.jar`
26 |
27 | ### JIT 컴파일을 사용하는 플랫폼
28 | 1. LISP
29 | 2. Java HotSpot VM
30 | 3. LLVM
31 | 4. LuaJIT
32 | 5. PHP
33 | 6. PyPy
34 | 7. TraceMonkey
35 | 8. ART
36 | 9. 플래시
37 | 10. Julia
38 | 11. MATLAB
39 | 12. SQL (Prepared Statement 사용 한정)
40 |
41 |
--------------------------------------------------------------------------------
/CS/interpreter-compile.md:
--------------------------------------------------------------------------------
1 | ## 인터프리터 언어와 컴파일 언어의 차이
2 |
3 | ### 인터프리터 언어
4 | * 원시코드를 기계어로 변환하는 과정없이 한줄 한줄 해석하여 바로 명령어를 실행하는 언어를 말한다. R, Python, Ruby와 같은 언어들이 대표적인 인터프리터 언어이다.
5 | * 인터프리터가 직접 한 줄씩 읽고 따로 기계어로 변환하지 않기 때문에 빌드 시간이 없다. Runtime 상황에서는 한 줄씩 실시간으로 읽어서 실행하기 때문에 컴파일 언어에 비해 속도가 느리다.
6 | * 실행속도는 느리지만 변경시 빌드 과정 없이 바로 실행 가능 하다. 루비를 사용해보면 소스코드를 고치고 서버를 다시 시작하지 않아도 변경사항이 저장된 상태로 테스트를 진행할 수 있다.
7 |
8 | ### 컴파일 언어
9 | * 원시코드를 기계어로 변환한 후에 JVM 같은 기계에 넣고 기계어 코드를 실행한다.
10 | * 기계어로 변환하는 시간이 소요된다.
11 | * 하지만 런타임 상황에서는 이미 기계어로 모든 소스코드가 변환되어 있기 때문에 빠르게 실행할 수 있다. 대표적으로 `C, C++`
12 |
13 | ### 빌드 과정이란?
14 | > 빌드는 곧 소스파일을 실행파일로 생성하는 과정 `.class` -> `.jar`
15 | > 즉 고급언어 -> 변환 -> 저급언어 과정을 거쳐서 실행파일로 생성한다.
16 |
17 | 인터프리터 언어는 빌드과정이 없이 바로 고급언어에서 한줄 씩 읽어 실행한다.
18 | 반면에 컴파일러 언어와 같은 C, java는 `.class` 파일 등꽈 같이 변환하여 실행한다.
--------------------------------------------------------------------------------
/DesignPattern/DesignPattern.md:
--------------------------------------------------------------------------------
1 | # [디자인 패턴] Design Pattern
2 | 도움을 주셔서 감사합니다 🙇🏻♂️
3 | > https://gmlwjd9405.github.io/2018/07/06/design-pattern.html
4 |
5 |
6 | ### Index
7 | 1. 디자인 패턴의 개념
8 | 2. 디자인 패턴의 구조
9 | 3. 디자인 패턴의 분류
10 | 4. 디자인 패턴의 종류
11 |
12 |
13 | ### 디자인 패턴이란?
14 | * 소프트웨어를 설계할 때 특정 맥락에서 자주 발생하는 고질적인 문제들이 또 발생했을 때 재사용할 수 있는 훌륭한 해결책
15 | * "바퀴를 다시 발명하지 마라"
16 | * 이미 만들어져서 잘 되는 것을 처음부터 다시 만들 필요가 없다는 의미이다.
17 | * 패턴이란?
18 | * 각기 다른 소프트웨어 모듈이나 기능을 가진 다양한 응용 소프트웨어 개발을 할 때도 서로 간에 공통되는 설계 문제가 존재하며 이를 처리하는 해결책 사이에도 공통점이 있는 것.
19 | * 패턴은 공통의 언어를 만들어주며 팀원 사이의 의사소통을 원활하게 해주는 아주 중요한 역할을 한다.
20 |
21 | ### 디자인 패턴의 구조
22 | 1. Context - 콘텍스트
23 | 1. 문제가 발생하는 여러 상황을 기술한다. 즉, 패턴이 적용될 수 있는 상황을 나타낸다.
24 | 2. 경우에 따라서는 패턴이 유용하지 못한 상황을 나타내기도 한다.
25 | 2. Problem - 문제
26 | 1. 패턴이 적용되어 해결될 필요가 있는 여러 디자인 이슈들을 기술한다.
27 | 2. 이때 여러 제약 사항과 영향력도 문제 해결을 위해 고려해야 한다.
28 | 3. Solution - 해결
29 | 1. 문제를 해결하도록 설계를 구성하는 요소들과 그 요소 사이의 관계, 책임, 협력 관계를 기술한다.
30 | 2. 해결은 반드시 구체적인 구현 방법, 언어에 의존적이지 않으며 다양한 상황에 적용할 수 있는 일종의 템플릿.
31 |
32 |
33 | ### 디자인 패턴의 종류
34 | * GoF 의 디자인 패턴
35 | * GoF(Gang of Fout)라 불리는 사람들
36 | * 에리히 감마, 리차드 헬름, 랄프 존슨, 존블라시디스
37 | * 소프트웨어 개발 영역에서 디자인 패턴을 구체화하고 체계화한 사람들
38 | * 23가지 디자인 패턴을 정리하고 각각의 디자인 패턴을 생성, 구조, 행위 3가지로 분류
39 |
40 | * GoF 디자인 패텅의 분류
41 |
42 |
43 | 1. 생성(Creational)패턴
44 | 1. 객체 생성에 관련된 패턴
45 | 2. 객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 `유연성 제공`
46 | 2. 구조(Structual)패턴
47 | 1. 클래스나 객체를 조합해 더 `큰 구조`를 만드는 패턴
48 | 2. 예를 들어 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스 생성, `객체를 묶어` 새로운 기능을 제공
49 | 3. 행위(Behavioral)
50 | 1. 객체가 클래스 사이의 알고리즘이나 `책임 분배`에 관련된 패턴
51 | 2. 한 객체가 혼자 수행할 수 없는 작업을 여래 개의 객체로 어떻게 `분배`하는지, 또 그렇게 하면서도 객체 사이의 `결합도를 최소화`하는 것에 중점을 둔다.
52 |
53 |
54 |
--------------------------------------------------------------------------------
/DevFeed/CohesionAndCoupling.md:
--------------------------------------------------------------------------------
1 | # 응집도와 결합도
2 |
3 | High Cohesion, Low Coupling `응집도`와 `결합도`라는 설계관련 용어는 프로그래밍을 하면서 자주 등장한다.
4 | 난 처음에 둘 다 같은 의미의 단어 인것 같았다. 사전을 참고해보자.
5 |
6 | 응집도에 대한 내용은 아래와 같다.
7 |
8 |
9 |
10 |
11 |
12 | > "응집도" 자체에 대한 정의는 공식 어학사전에서 찾아보기 힘들지만 프로그래밍 기법에 빗대어 설명한 내용은 위와 같다.
13 |
14 | 결합도에 대한 내용은 아래와 같다.
15 |
16 |
17 |
18 |
19 |
20 |
21 | ## 응집도
22 |
23 |
24 |
25 |
26 |
27 |
28 | 응집도는 모듈에 포함된 내부 요소들이 하나의 책임/목적을 위해 연결 되어있는 연관된 정도이다.
29 |
30 | * 모듈이 하나의 목적을 수행하는 요소들간의 연관성 척도
31 | * 모듈 내부의 기능적인 응집 정도를 나타낸다
32 | * 높을수록 좋다
33 |
34 | > A라는 기능을 만족하기 위해 a 모듈에 A 기능들을 위한 책임과 목적이 **잘 모여 있는(응집도가 강함)** 것과 아닌 경우 수정하기가 어느쪽이 어려울까요?
35 |
36 | A 라는 기능을 수정하기 위해 a 모듈만 손대면 되니깐 수정하기 용이하겠죠 !
37 | 반대로 A 라는 기능의 책임과 목적이 a,b 모듈에 흩어져 있다면 낮은 응집도를 가진다고 할 수 있습니다.
38 |
39 | ## 결합도
40 |
41 |
42 |
43 |
44 |
45 | 결합도는 `다른 모듈과`의 의존성의 정도 입니다. 모듈을 수정하기 위해 다른 모듈의 변경을 요구하는 정도로도 생각해 볼 수 있습니다.
46 |
47 | * 모듈이 `다른 모듈`에 의존하는 정도의 척도
48 | * `모듈과 모듈간`의 상호 결합 정도를 나타냄
49 | * 낮을수록 좋다
50 |
51 | 유지보수를 위해 B라는 기능을 수정하기 위해 B기능이 모여있는 b모듈을 수정하는데 다른 모듈들과 기능들과 연관되어 수정하려면 다른 모듈의 소스도 확인하면서 해야합니다.
52 |
53 | 결합도가 높아 다른 모듈들까지 수정해야한다면 유지보수가 더욱 어려워진다. 수정에 있어서 테스트코드까지 의존하고 있다면 더 힘들어진다 🥲
54 |
55 | ## 높은 응집도와 낮은 결합도를 유지해야한다.
56 |
57 | 응집도는 강함-약함
58 | 결합도는 약함-강함
59 |
60 | 이렇게 기준점을 두고 개발을 해야겠다.
--------------------------------------------------------------------------------
/DevFeed/GraphQL.md:
--------------------------------------------------------------------------------
1 | # GraphQL
2 | ## QraphQL 개념 및 역할
3 |
4 | GraphQL은 쿼리 언어이자 애플리케이션 프로그래밍 인터페이스(API)를 위한 서버측 런타임으로, 클라이언트에게 요청한 만큼의 데이터를 제공하는데 우선 순위를 둡니다.
5 |
6 |
7 |
8 | GraphQL은 API를 더욱 빠르고 유연하며 개발자 친화적으로 만들기 위해 설계됐다.
9 | 또한 REST를 대체할 수 있는 GraphQL은 개발자가 단일 API 호출로 다양한 데이터 소스에서 데이터를 끌어오는 요청을 구성할 수 있도록 지원합니다.
10 |
11 |
12 |
13 | 또한 GraphQL은 API 유지 관리자에게 기존 쿼리에 영향을 미치지 않고 필드를 추가하거나 폐기할 수 있는 유연성을 부여합니다.
14 | 개발자는 자신이 선호하는 방식으로 API를 빌드할 수 있으며, GraphQL 사양은 이러한 API가 예측 가능한 방식으로 작동하도록 보장합니다.
15 |
16 | ## GraphQL 쿼리 언어: 스키마 및 리졸버 개념
17 | API 개발자는 GraphQL을 사용해 클라이언트가 서비스를 통해 쿼리할 가능성이 있는 모든 데이터를 설명하는 스키마를 생성합니다.
18 |
19 |
20 |
21 | GraphQL 스키마는 개체 유형으로 구성되어 어떤 종류의 개체를 요청 할 수 있으며 어떠한 필드가 있는지 정의합니다.
22 |
23 |
24 |
25 | 쿼리가 수신되면 GraphQL은 스키마에 대해 쿼리를 검증한 후 검증된 쿼리를 실행합니다.
26 |
27 |
28 |
29 | API 개발자는 스키마의 각 필드를 리졸버라고 불리는 기능에 첨부합니다.
30 |
31 | ## GraphQL 장점과 단점 비교
32 | GraphQL 장점
33 | * GraphQL 스키마는 GraphQL 애플리케이션에 신뢰할 수 있는 단일 소스를 하나 설정합니다. 조직은 이를 통해 전체 API에 페더레이션할 수 있게 됩니다.
34 | * GraphQL 호출은 단일 왕복으로 처리되며 클라이언트는 오버페칭 없이 요청한 결과만 얻습니다.
35 | * 엄격하게 정의된 데이터 유형은 클라이언트와 서버 간 통신 오류를 줄여줍니다.
36 | * GraphQL은 세부 검사를 수행합니다. 클라이언트는 사용 가능한 데이터 유형 목록을 요청할 수 있습니다. 자동 생성 문서의 경우 이상적인 방식이죠.
37 | * GraphQL은 애플리케이션 API가 기존 쿼리를 중단하지 않고도 진화할 수 있도록 허용합니다.
38 | * REST API로 사용할 수 없는 기능을 제공하기 위해 대부분의 오픈소스 GraphQL 확장 기능을 사용할 수 있습니다.
39 | * GraphQL은 특정 애플리케이션 아키텍처를 지정하지 않으므로 기존 REST API에 추가하여 기존 API 관리 툴과 연동할 수 있습니다.
40 |
41 |
42 |
43 | GraphQL 단점
44 | * REST API에 친숙한 개발자의 경우 GraphQL를 학습하는 데 시간이 필요합니다.
45 | * GraphQL은 데이터 쿼리의 상당 작업을 서버측으로 옮겨 서버 개발자 작업의 복잡성이 커집니다.
46 | * 구현 방식에 따라 GraphQL은 REST API이 아닌 다른 API관리 적략을 필요로 할 수 있습니다.
47 | * 캐싱이 REST보다 훨씬 복잡합니다.
48 | * API 유지관리자의 경우 유지 관리 가능한 GraphQL 스키마를 작성하기 위한 추가 태스크를 수행해야한다.
49 |
50 |
--------------------------------------------------------------------------------
/DevFeed/JPQL.md:
--------------------------------------------------------------------------------
1 | ## JPQL
2 | JPA 를 사용하면 객체를 중심으로 개발
3 | JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
4 | JPQL은 엔티티 객체를 대상으로 쿼리, SQL은 데이터베이스 테이블을 대상으로 쿼리
5 |
6 | ```java
7 | String jpql = "select m From Member m where m.name like '%hello%'";
8 | List result = em.createQuery(jpql, Member.class)
9 | .getResultList();
10 | ```
11 |
12 | ### JPQL 문법
13 | ```java
14 | select m from Member m where m.age > 18
15 | ```
16 | * 엔티티와 속성은 대소문자 구분(Member, username)
17 | * JPQL 키워드는 대소문자 구분 안함(SELECT, FROM, WHERE)
18 | * 엔티티 이름을 사용, 테이블 이름이 아님(Member)
19 | * 별칭은 필수(m)
20 |
21 | ### Named 쿼리 - 정적 쿼리
22 | * 미리 정의해서 이름을 부여해두고 사용하는 JPQL
23 | * 어노테이션, XML에 정의
24 | * 애플리케이션 로딩 시점에 초기화 후 재사용
25 | * 애플리케이션 로딩 시점에 쿼리 검증
26 | * query.getResultList() - 결과가 하나 이상, 리스트 반환
27 | * query.getSingleResult() - 결과가 정확히 하나, 단일 객체 반환(아니면 Exception)
28 |
29 | ```java
30 | @Entity
31 | @NamedQuery(
32 | name = "Member.findByUserName",
33 | query = "select m from m where m.username =: username")
34 | )
35 | public class Member{
36 | }
37 | List resultList =
38 | em.createQuery("Member.findByUserName", member.class)
39 | .getResultList();
40 | ```
--------------------------------------------------------------------------------
/DevFeed/LearningCurve.md:
--------------------------------------------------------------------------------
1 | # 👩🏻🎓 LearningCurve(학습곡선)
2 | ## **LearningCurve의 개념과 이해**
3 | ### ✅ LearningCurve의 개념
4 | > 학습 곡선(learning curve)은 어떤 특정한 대상을 학습하는 데 투입된 시간 대비 학습 성취도를 나타내는 그래프이다.
5 |
6 |
7 |
8 | > ### 가로축은 학습을 시도한 횟수 또는 시간(number of trials or attempts at learning)이고, 세로축은 습득 정도(performance measure)이다.
9 | >
10 | >위 그림과 같은 s자 모양(sigmoid)의 그래프가 가장 일반적이다.
11 | >
12 | > 초반에는 모르는 개념과 용어가 많아 습득 속도가 느리지만(slow beginning), 일정 정도를 넘어서면 습득 속도가 빨라지며(steep acceleration), 어느 단계를 넘어서면 다시 습득 속도가 느려진다(plateau).
13 |
14 | ***
15 | ### **✅ 속도비교**
16 |
17 |
18 | > steep learning curve가 학습이 어려운 대상, shallow learning curve가 학습이 쉬운 대상이다.
19 | > 즉, 초반의 기울기가 가파를수록 진입장벽이 낮은 것이며, 조금만 공부해도 많은 양을 학습할 수 있는 쉬운 대상이라는 의미이다.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/DevFeed/Nginx-Apache-compare.md:
--------------------------------------------------------------------------------
1 | # Nginx, 그리고 Nginx가 Apache 보다 성능이 좋은 이유
2 |
3 | ## 논외
4 | 요즘에 내가 개발하면서 가장 중요시 하는 부분이 있다.
5 | 자신이 사용하는 기술을 왜 사용하는지 논리적으로 설명할 수 있어야 한다고 생각한다.
6 |
7 | 신입 개발자라면.. 현재의 나는 취업 시장에서의 경쟁력이라는 핑계로 기초 CS 지식을 간과하고 개발하지 않나. 스스로 질문해 볼 필요가 있다.
8 | 그저 많은 라이브러리와 API를 사용하는 경험 했다면. 가까운 미래에 운 좋게 취업은 할 수 있을지 모르겠지만. 진짜 자신의 코딩 실력은 늘지 않고, 나중에는 그저 새로운 라이브러리를 공부하는데 허덕이는 자신을 마주할 것이라고 믿는다.
9 |
10 | 오늘 미디엄의 좋은 [포스팅](https://bit.ly/3haCw9e)을 보고 개념을 글로 정리하는 것을 실행에 옮기게 됐다.
11 | 내가 과연 이 기술을 알고 쓰는 걸까 싶은 기술들을 앞으로 CS와 연관 지어서 포스팅해 보려고 한다.
12 |
13 | ## Nginx의 활용
14 |
15 | "springboot 무중단 배포" 라고 구글링 하면 "Nginx를 통한 무중단 배포" 라는 키워드를 보지 않을 수 없다.
16 | [toss](https://toss.im/) `Response Headers` 를 보면 Server가 `nginx` 이다. (front cache server로 생각든다)
17 |
18 | ### Nginx 란?
19 |
20 | Nginx에 대한 굉장히 자세한 내용은 나 포스트보다 [공식문서](https://www.nginx.com/resources/library/infographic-inside-nginx/)를 참고하는게 좋다.
21 |
22 | Nginx 에서는 Nginx에 대해서 아래와 같이 설명한다.
23 |
24 | > 많은 web server와 application server는 단순한 쓰레드, 프로세스 기반 아키텍쳐 이지만 Nginx는 혁신적인 이벤트 중심 아키텍쳐이다.
25 | > 이를 통해 최신 하드웨어에서의 수십만의 동시 접속을 이뤄낸다고 한다.
26 |
27 | ## Nginx의 성능을 이해하려면 동작 방식을 알 필요가 있다.
28 |
29 | Nginx의 동작방식을 이해하는데 필요한 개념
30 |
31 | * [PCB & IPC & Context Switching](../CS/PCB-IPC-ContextSwitching.md)
32 | * [I/O multiplexing](../CS/IO-Multiplexing.md)
33 | * IRQ (Interrupt request lines)
34 |
35 | ## Nginx가 기존의 웹 서버(Apache)와 차이점
36 |
37 | * Nginx가 개선한 것
38 | * 소개에도 강조했던 동시접속 (concurrent connections)
39 | * 이를 위해 개선된 설계
40 | * Event-driven architecture
41 | * 연결 전담 프로세스나 스레드를 두지 않는다.
42 | * worker 프로세스들이 listen socket, connection socket 2개의 이벤트를 다 처리한다.
43 | * non-blocking I/O
44 | * 설계를 구현한 방식
45 | * 고정된 수의 worker 프로세스만을 관리한다.
46 | * 매 connection마다 프로세스나 스레드를 생성하지 않는다.
47 | * 프로세스를 이벤트를 기반으로 non-blocking 하게 동작한다.
48 | * 리소스나 Context Switching도 현저히 줄인다.
49 |
50 |
--------------------------------------------------------------------------------
/DevFeed/PG.md:
--------------------------------------------------------------------------------
1 | # PG(Payment Gateway)
2 | ## Payment Gateway
3 | ### PG란 무엇일까?
4 | > PG(Payment Gateway)사는 인터넷 상에서 금융 기관과 하는 거래를 대행해 주는 서비스. 신용 카드, 계좌 이체, 핸드폰 이용 결제, ARS 결제 등 다양한 소액 결제 서비스를 대신 제공해 주는 회사.
5 |
6 | **"결론적으로 신용카드사, 은행, 통신사 등 결제를 취급하는 회사와 쇼핑몰 사이에서 결제를 대행해주는 결제대행사 이다."**
7 |
8 | ### PG의 구조
9 |
10 |
11 | **OFFLINE 매장에서도 이 구조를 흔히 접할 수 있다.**
12 | > POS를 제공하는 벤더들이 각 카드사와 대신 계약을 맺고 일반 매장에서 여러 카드를 결제할 수 있도록 하는 것과 동일한 구조.
--------------------------------------------------------------------------------
/DevFeed/Parameter,Argument.md:
--------------------------------------------------------------------------------
1 | # **🐤 Difference of Parameter, Argument**
2 |
3 | ## **매개변수(Parameter), 전달인자(Argument)란?**
4 | **Parameter**
5 | > ```
6 | > int sum(int a, int b){
7 | > return a+b;
8 | > }
9 | > ```
10 | > (int a, int b)는 실제 값이 존재하지 않고 형태를 나타내줄 뿐.
11 | > 이것을 "Parameter", 매개변수라고 한다.
12 |
13 | **Argument**
14 | > ```
15 | > sum(10, 20);
16 | > ```
17 | > 위의 sum 함수를 호출 했을 때, ```(10,20)``` 의 변수를 전달인자 라고 한다.
18 | > 전달인자에는 값이 존재한다.
19 |
20 |
--------------------------------------------------------------------------------
/DevFeed/SQLD.md:
--------------------------------------------------------------------------------
1 | # SQLD
2 |
3 | ## 제 1장 데이터 모델링의 이해
4 |
5 | ### 발생시점에 따른 엔티티 분류
6 | * 기본/키엔티티
7 | * 중심엔티티
8 | * 행위엔티티
9 |
10 | ### 모델링의 특징
11 | * 현실세계를 일정한 형식에 맞추어 표현하는 추상화의 의미를 가진다.
12 | * 복잡한 현실을 제한된 언어나 표기법을 통해 이해하기 쉽게 하는 단순화의 의미를 가진다.
13 | * 애매모호함을 배제하고 누구나 이해가 가능하도록 정확하게 현상을 기술하는 정확화의 의미를 가진다.
14 |
15 | ### 데이터 모델링이란
16 | * 정보시스템을 구축하기 위한 데이터 관점의 업무 분석 기법
17 | * 현실세계의 데이터에 대해 약속된 표기법에 의해 표현하는 과정
18 | * 데이터베이스를 구축하기 위한 분석/설계의 과정
19 |
20 | ### 데이터 모델링 유의점
21 | * 중복
22 | * 비유연성 - 사소한 업무변화에도 데이터 모델이 수시로 변경되면 유지보수의 어려움이 있기에
23 | * 비일관성
24 | * 비연계성
25 |
26 | ### 데이터모델링의 개념
27 | * 개념적 데이터 모델링 - 추상화 수준이 높고, 업무중심적이며, 포괄적인 수준의 모델링
28 | * 논리적 데이터 모델링 - 업무에 대해 key, 속성, 관계 등을 정확하게 표현, 재사용성이 높음
29 | * 물리적 데이터 모델링 - 실제로 데이터베이스에 이식할 수 있도록 성능, 저장 등 물리적인 성격을 고려
30 |
31 | ### 데이터베이스 스키마 구조 3단계
32 | * 외부 - 형식, 구조, 배치화면
33 | * 개념 - 전체 관점의 통합적 표현
34 | * 내부 - 실제 데이터베이스의 물리적 저장구조를 정의
35 |
36 | ### ERD 작성 순서
37 | 1. 엔티티를 그린다
38 | 2. 엔티티를 적절하게 배치한다
39 | 3. 엔티티간 관계를 설정한다
40 | 4. 관계명을 기술한다
41 | 5. 관계의 참여도를 기술한다
42 | 6. 관계의 필수여부를 기술한다
43 |
44 | ### 엔티티의 특징
45 | * 반드시 해당 업무에서 필요하고 관리하고자 하는 정보이여야 한다.
46 | * 유일한 식별에 의해 식별이 가능해야 한다.
47 | * 영속적으로 존재하는 (두 개 이상)인스턴스의 집합이어야 한다.
48 | * 엔티티의 업무 프로세스에 의해 이용되어야 한다.
49 | * 엔티티는 반드시 속성이 있어야 한다.
50 | * 엔티티는 다른 엔티티와 최소 한 개 이상의 관계가 있어야 한다.
51 |
52 | ### 엔티티, 인스턴스, 속성, 속성값의 관계
53 | * 한 개의 **엔티티는** 두 개 이상의 인스턴스의 집합이여야 한다. (1:N)
54 | * 한 개의 **엔티티는** 두 개 이상의 속성을 갖는다. (1:N)
55 | * 한 개의 **속성은** 한 개의 속성값을 갖는다. (1:1)
56 |
57 |
58 |
--------------------------------------------------------------------------------
/DevFeed/TDD.md:
--------------------------------------------------------------------------------
1 | # 🧑🏻💻 TDD(TestDrivenDevelopment)
2 | ## **TTD(TestDrivenDevelopment)의 정의와 효과**
3 | ### **1️⃣ TDD 란?**
4 | * TestDrivenDevelopment
5 | * 테스트 주도 개발: 테스트가 개발을 이끌어 나간다.
6 |
7 | ### **2️⃣ 구체적인 행동 레벨에서의 TDD의 개념**
8 | > 테스트를 먼저 만들고 테스트를 통과하기 위한 것을 짜는 것 즉, 만드는 과정에서 우선 테스트를 작성하고 그걸 통과하는 코드를 만들고를 반복하면서 제대로 동작하는지에 대한 피드백을 적극적으로 받는 것이다.
9 | 1. 보통 SW 개발을 할 때 코딩을 다 끝나고 난 후 테스트를 한다.
10 | * 코딩이 끝난 후? 개발자가 코딩을 다 짜고 난 후 완성했다고 생각할 때
11 | * 이것의 순서를 바꾸는 것이 TDD를 적용하는 것이다.
12 |
13 | 2. TDD를 적용한 사례
14 | * 예를 들어, 생년월일(input)을 입력받으면 현재 나이(output)를 출력하는 프로그램
15 | 1. 처음에는 간단한 것으로 목표를 정한다(태어난 해와 올해의 연도를 입력)
16 | * 2015, 2018 -> 만 3살 우선 이것을 만들겠다는 생각을 한다.
17 | 2. 만들기도 전에 만든 후에 무엇을 테스트할지를 설계한다.
18 | * 2015, 2018를 입력하면 2가 나오는 테스트 프로그램을 만든다.
19 | 3. 그 다음에 그 테스트를 통과할 프로그램(1. 을 목표로 작성한 코드를)만든다.
20 | * 올해의 연도 - 태어난 해
21 | * 2018 - 2015
22 | 4. 테스트 프로그램으로 이 프로그램(3.에 대행하는 코드)를 실행한다.
23 | 5. 통과했으면 새로운 테스트를 추가한다.
24 | * 이번에는 생월을 추가했을 때 계산하는 프로그램
25 | 6. 위 작업을 계속 왔다갔다 수행한다.
26 |
--------------------------------------------------------------------------------
/DevFeed/URI.md:
--------------------------------------------------------------------------------
1 | # 🥲 URI vs URL vs URN
2 | ## INDEX
3 | 1. URI, URL, URN 개념
4 | 2. URL의 한계
5 | 3. URI, URL 차이점
6 |
7 | ## URI(Uniform Resource Identifier)
8 | > URI는 인터넷의 우편물 주소 같은 것으로, 정보 리소스를 고유하게 식별하고 위치를 지정할 수 있다.
9 | > ### URI는 두 가지 형태가 있는데 이것이 URL, URN이라는 것이다.
10 |
11 | ## URL(Uniform Resource Locator)
12 | > URL은 특정 서버의 한 리소스에 대한 구체적인 위치를 서술한다.
13 | > URL은 리소스가 정확히 어디에 있고 어떻게 접근할 수 있는지 분명히 알려준다.
14 |
15 | ```
16 | http://naver.com - 네이버 사이트의 URL
17 | http://img.naver.net/static/www/dl_qr_naver.png - 네이버 앱 QR 코드의 이미지에 대한 URL
18 | ```
19 |
20 | ## URN(Uniform Resource Name)
21 | > URN은 콘텐츠를 이루는 한 리소스에 대해, 그 리소스의 위치에 영향 받지 않는 유일무이한 이름 역할을 한다.
22 | > 이 위치 독립적인 URN은 리소스를 여기저기로 옮기더라도 문제없이 동작한다.
23 | > 리소스가 그 이름을 변하지 않게 유지하는 한, 여러 종류의 네트워크 접속 프로토콜로 접근해도 문제없다.
24 |
25 | "URN은 아직 채택되지 않아, 접할 기회가 없었을 것이다."
26 |
27 | ## **URL의 한계**
28 | > ### URL의 한계란, URL은 주소이지 실제 이름이 아니다.
29 | > 이 뜻은 특정 시점에 어떤 것이 위치한 곳을 알려준다는 것이다.
30 |
31 | > ### 결론적으로 요약하자면, URL과 URN은 URI의 종류이다.
32 | > ### 그렇기에 모든 URL은 URI이고, 또한 모든 URN은 URI이다.
33 | > ### 그리고 위에 언급했듯이, URL, URN은 다르다.
34 | > ### 그렇다는건 모든 URI는 URL이라고 말할 수 없다.
35 |
36 |
--------------------------------------------------------------------------------
/DevFeed/githubLicense.md:
--------------------------------------------------------------------------------
1 | # Github license의 종류와 나에게 맞는 라이센스 선택하기
2 | ## 라이센스는 "해야할 것"과 "하지 말아야할 것"에 대한 약속이다.
3 | ### README.md 파일에서
4 | ```
5 | “This project is licensed under the terms of the MIT license.”
6 | ```
7 | 이런식으로 라이센스를 명시한다.
8 |
9 | ### 라이센스 종류
10 | 1. BSD: 소스코드를 공개하지 않아도 되는 라이선스, 저작권을 명시해야한다.
11 | 2. GPL: 사용하고 싶은 오픈소스의 라이센스가 GPL 이라면 주의를 기울어야한다.
12 | > GPL 라이센스를 적용받는 프로그램은 유료로 판매할 수 있지만 전체 소스코드는 무료로 공개 해야한다. 상업적인 용도로 사용할 수 있지만 코드를 공개해여하기 때문에 회사에서 라이브러리를 채택할 때는 반드시 어떤 라이센스가 있는지 미리 체크해야한다.
13 | 3. MIT: 라이센스 및 저작권을 명시해야하고 상업적, 사적으로도 이용이 가능하다.
14 | 4. Apache: 아파치 재단에서 만든 라이센스이다.
15 | > 구글이 안드로이드 오픈소스프로젝트의 기본 라이센스를 Apache2.0으로 선택했기 때문에, 대부분의 안드로이드 소프트웨어는 Apache2.0 라이센스가 적용된다.
--------------------------------------------------------------------------------
/DevFeed/h2db.md:
--------------------------------------------------------------------------------
1 | ## h2 DB 설치 및 사용 방법
2 | 우선 h2 db 공식 사이트로 접속
3 | > https://www.h2database.com/html/main.html
4 |
5 | 안정화 된 버전 다운로드
6 |
7 |
8 |
9 | 내가 좋아하는 디렉터리에 옮긴 후 실행
10 | ```
11 | $ cd h2/
12 | $ cd bin/
13 | $ chmod 755 ./h2.sh
14 | $ ./h2.sh
15 | ```
16 |
17 | 최초 실행할때
18 | ```
19 | jdbc:h2:~/yourdb
20 | ```
21 |
22 | 디렉토리에 ~/ 디렉토리 `db` 확장자 생성 확인 후
23 | 다음 실행에서는 아래 url 입력 (tcp 모드)
24 | ```
25 | jdbc:h2:tcp://localhost/~/yourdb
26 | ```
27 |
28 | ⚠️ 중요한건 h2 DB 를 실행시키지 않으면 아래와 같은 오류가 발생한다.
29 | ```
30 | Failed to load ApplicationContext
31 | ```
32 |
--------------------------------------------------------------------------------
/DevFeed/mysql-reset.md:
--------------------------------------------------------------------------------
1 | ## 🍺 homebrew 로 설치된 mysql 삭제 후 재설치
2 |
3 | 1. mysql 서비스 중지
4 |
5 | ```sh
6 | $ brew services stop mysql
7 | ```
8 |
9 | 2. mysql 삭제
10 |
11 | ```sh
12 | $ brew uninstall mysql
13 | ```
14 |
15 | 3. mysql 관련 파일을 모두 삭제한다.
16 |
17 | ```sh
18 | $ rm -rf /usr/local/var/mysql
19 | ```
20 |
21 | 4. mysql 설정 파일 삭제한다.
22 |
23 | ```sh
24 | $ rm /usr/local/etc/my.cnf
25 | ```
26 |
27 | 5. mysql 재설치
28 |
29 | ```
30 | $ brew update
31 | $ brew install mysql
32 | ```
33 |
34 | 6. mysql 시작하기
35 | ```
36 | $ mysql.server start
37 | ```
38 |
39 | 7. MySQL 설정 방법
40 | ```
41 | $ mysql_secure_installation
42 | ```
43 |
44 | ... 세부세팅
45 | ```
46 | "Would you like to setup VALIDATE PASSWORD component?
47 |
48 | Press y|Y for Yes, any other key for No"
49 | > no
50 | > 1234
51 |
52 | "Remove anonymous users? (Press y|Y for Yes. any other key for No)"
53 | > yes
54 |
55 | "Disallow root login remotely? (Press y|Y for Yes, any other key for No)"
56 | > yes
57 |
58 | "Remove test database and access to it? (Press y|Y for Yes, any other key for No)"
59 | > yes
60 |
61 | "Reload privilege tables now? (Press y|Y for Yes, any other key for No)"
62 | > yes
63 |
64 | All done!
65 | ```
66 |
67 | 8. mysql user 접속
68 | ```
69 | $ "mysql -uroot -p"
70 | ```
--------------------------------------------------------------------------------
/DevFeed/on,off-premise.md:
--------------------------------------------------------------------------------
1 | ## 온프레미스와 클라우드의 장 단점 분석
2 |
3 | ### 온프레미스란?
4 | > 소프트웨어 등 솔루션 클라우드 같이 원격 환경이 아닌, 자체적으로 보유한 전산실 서버에 직접 설치해 운영하는 방식.
5 |
6 | ### 클라우드 필요성 대두
7 | T 인프라가 점차 복잡해지면서 기업이 관리해야 하는 네트워크 트래픽은 점점 늘어나고 있다.
8 | 이처럼 환경이 복잡하고 지능화되면서 IT 인프라 관리는 점차 어려워지고, 비용은 지속적으로 늘어나는 비 효율적인 환경이 되고 있다.
9 | 보안이 중요한 시점에서 IT 인프라가 점차 복잡해지면서 네트워크 트래픽에 대한 모니터링과 이를 분석할 관리 솔루션에 대한 지속적인 투자가 필요해지고 있다.
10 | 기존의 온프레미스 기업들로서는 이러한 복잡성과 비용의 증가는 반갑지만은 않을 것 이다.
11 |
12 | ### 클라우드의 장점
13 | 온프레미스 기업들은 IT 인프라의 확충과 컴퓨팅 파워 및 저장능력 향상에 대한 부담감과
14 | 고도화되고 지능화되는 해커들로부터 기업 자산을 보호하기 위해서 끊임없이 네트워크를 모니터링 해야하고,
15 | 이를 분석할 고성능 관리 솔루션을 구입해야 한다.
16 |
17 | > 갑작스러운 환경 변화에 신속하고 탄력적으로 대응할 수 있다.
18 | > IT 인프라 운영에 대한 부담에서 벗어나 기업의 핵심 업무에 역량을 집중할 수 있다.
19 | > 클라우드는 IT 투자비용(CAPEX)을 절감한다.
20 |
21 |
22 | ### 클라우드 사용의 좋은 예.
23 |
24 |
25 | LG 전자의 스마트 TV 서버를 아마존의 AWS 의 클라우드로 이전해 40% 비용 절감
26 |
27 |
28 |
29 |
30 |
31 | 다우존스는 월 900만건에 달하는 아시아 지역 트래픽 관리를 AWS 통해 수행에 25% 비용 절감을 했다.
32 |
33 |
34 |
35 | ### 결론적으로.......
36 | ```
37 | On-Premise -> Off-Premise(Cloud-platform)
38 | ```
--------------------------------------------------------------------------------
/DevOps/HttpsConnect.md:
--------------------------------------------------------------------------------
1 | ## 내 어플리케이션에 Https 적용하는 방법
2 |
3 | 문제상황
4 | * mixed contents 이슈 발생
5 | * 프론트에서 https를 사용하고 있고 http에서 https로는 브라우저가 똑똑하게 s를 붙여줘서 연결이 되지만
6 | https(클라이언트)가 http(서버)로 XHR(요청)을 보내게 되면 연결 이슈가 발생
7 |
8 |
9 |
10 | 해결방안w
11 | * ``the-moment.org`` 도메인을 Route 53 과 연결
12 | * ELB에 SSL Listener 생성
13 | * ELB Security group 설정
14 | * 최종 SSL 적용
15 |
16 | ## 도메인 Route 53과 연결하고 접속하기
17 |
18 |
19 |
20 | > Route 53에 자신의 도메인을 등록한다.
21 |
22 |
23 |
24 | > ns@@~~ 로 시작하는 부분 4개의 값을 가비아의 네임서버에 등록한다. (마지막 . 제외)
25 |
26 |
27 |
28 | > 레코드를 생성한다.
29 | > 여기서 ec2 를 사용한다면 ec2의 주소를 ip 값으로 넣어주면 된다.
30 |
31 | ## ELB 생성하기
32 | * 먼저 ELB를 생성합니다.
33 |
34 |
35 | * 해당 메뉴를 선택합니다.
36 |
37 |
38 | * ``기본구성/이름`` 자신이 원하는 이름을 입력합니다.
39 | * ``리스너`` 에 Https 를 추가합니다.
40 | * ``가용영역`` 에 해당하는 체크박스를 다 체크합니다.
41 |
42 |
43 |
44 | * 인증서를 선택합니다. 없다면 ACM으로부터 새 인증서를 발급합니다.
45 |
46 |
47 | * 인증서를 선택하고 보안그룹을 선택합니다.
48 |
49 |
50 | * 라우팅을 세팅합니다 저는 docker-compose 포트를 5000 포트로 사용하기 때문에 5000을 넣어줍니다.
51 |
52 |
53 | * 다음으로 대상 등록을 해주고
54 |
55 |
--------------------------------------------------------------------------------
/DevOps/IaaS,PaaS,SaaS.md:
--------------------------------------------------------------------------------
1 | # 클라우드 서비스 이해하기 IaaS, PaaS, SaaS
2 | > 도움을 주셔서 감사합니다 🙇🏻♂️
3 | > https://www.whatap.io/ko/blog/9/
4 |
5 | ### 🥑 용어정리
6 | 1. IaaS_아이아스(Infastructure as a Service): 서비스로 제공되는 인프라 스트럭쳐, 개발사에 제공되는 물리적 자원을 가상화.
7 | 2. PaaS_파스(Platform as a Service): 서비스로 제공되는 플랫폼, 개발사에 제공되는 플랫폼을 가상화
8 | 3. SaaS_사스(Software as a Service): 서비스로 제공되는 소프트웨어, 고객에게 소프트웨어를 가상화
9 |
10 | ### 🥕 어떤 것을 제공하나요?
11 |
12 |
13 | **IaaS** 는 기존의 데이터센터에서 제공받던 물리적인 자산을 완벽하게 가상화하여 제공하기 때문에 서버 사양의 변경 등 물리적 수정이 필요한 경우 기존에 비해 훨씬 빠른 대응이 가능합니다.
14 |
15 | **PaaS**를 사용하면 기업에서는 특수 소프트웨어 구성 요소를 사용하여 PaaS에 내장된 응용프로그램을 설계하고 만들 수 있습니다.
16 |
17 | **SaaS**를 공급하는 업체는 데이터, 미들웨어, 서버 및 스토리지와 같은 모든 잠재적인 기술적 문제를 관리하기 떄문에 고객은 유지 보수 및 자원을 간소화 하면서 비즈니스에 집중 할 수 있습니다.
18 |
19 | ## 🐷 각 클라우드 서비스의 장단점
20 |
21 | ### IaaS (aws, azure, GCE)
22 | * 비용: 물리적 자원을 서버 형태로 사용하기 때문에 고정비가 없음
23 | * 속도: 물리적 자원을 즉시 소비할 수 있다
24 | * 관리: 자동화된 배포, 운영을 벤더에 맡기고, 확장 축소가 자유롭다
25 |
26 | ### PaaS (aws Elastic Beanstalk...etc)
27 | * 장점: 필요한 플랫폼만 소비 형태로 사용하기에 비용 부담이 덜하다
28 | * 속도: 개발 및 배포 프로세스를 빠르게 확보할 수 있다.
29 | * 관리: 소프트웨어 유지 관리가 손쉽다, 가상화 기술을 기반으로 구축되어 비즈니스가 변함에 따라 리소스를 쉽게 확장, 축소 가능
30 | * 단점: 특정 플랫폼에 종속될 수 있음
31 |
32 | ### SaaS (Google apps, Dropbox)
33 | * 비용: 소프트웨어를 소비 형태로 사용하기 때문에 비용 부담을 덜 수 있다.
34 | * 속도: 즉시 사용이 가능하다.
35 | * 관리: 소프트웨어를 설치하는 물리적 자원이 필요가 없다, 언제든 접근 가능
36 | * 단점: 커스터마이징이 어렵다.
--------------------------------------------------------------------------------
/DevOps/RDS-fatal-error.md:
--------------------------------------------------------------------------------
1 | ## RDS를 Springboot project에 연동하며...
2 |
3 | ### 우선 간단히 RDS 를 연동하는 과정에 대해서 설명하겠다.
4 |
5 |
6 |
7 | > 우선 유형으로 자기가 선택한 종류의 DB를 선택하고
8 | > TCP 및 DB 포트를 적고 내 IP, EC2 보안그룹에 대해서 허용해준다.
9 |
10 |
11 |
12 | RDS 에서는 개인적으로 세팅해줘야 할 부분이 많지 않다.
13 |
14 | ### 마주할 수 있는 치명적 에러
15 |
16 |
17 |
18 | 계속 IntelliJ에서 위와 같은 오류가 발생한다.
19 | > 나도 로컬에서는 해결하지 않아 정확한 해답을 찾지는 못했는데 발생할 수 있는 경우는 아래와 같다.
20 |
21 |
22 |
23 | 결국에는 EC2 로 접속해서 EC2에 있는 SpringBoot application을 실행하고 Hibernate ``create table`` 시켜주면 저 Exception이 해결되고, table이 생성되는 것을 확인 할 수 있다.
24 |
25 | ### application.yml 더 나아가 설정하기
26 | ```yml
27 | datasource:
28 | url : jdbc:mariadb://rds엔드포인트:포트명/database이름
29 | username : db계정
30 | password : db계정 비밀번호
31 | driver-class-name: org.mariadb.jdbc.Driver
32 |
33 | jpa:
34 | hibernate:
35 | ddl-auto: none
36 | // 최초 DB 연동에는 ddl-auto: ture 해줘야 한다.
37 | ```
--------------------------------------------------------------------------------
/DevOps/Ubuntu+EC2.md:
--------------------------------------------------------------------------------
1 | ## Ubuntu AWS 서버에 프로젝트 올리기
2 |
3 | 1st. Ubuntu Server 구축하기
4 | ```
5 | 다음, 다음, 다음 누르다가
6 | --------------------
7 | 보안 그룹 설정에서 아래와 같이 추가하기
8 | SSH, HTTP [위치무관] + SpringBoot Port:8080 [위치무관]
9 | ```
10 |
11 | 2nd. EC2 서버에 접속하기
12 | ```
13 | pem 파일이 있는 경로에 들어가서
14 | -------------------------
15 | $ ssh -i "***.pem" ec2-user@ec2-34-202-149-32.compute-1.amazonaws.com
16 | ```
17 |
18 | 3. Mysql 설치
19 | ```
20 | $ sudo apt update
21 | $ sudo apt install mysql
22 | ```
23 |
24 | > SpringBoot proj 파일 추가 및 실행 방법은 다른 TIL 참고
25 |
26 | 4. 보안 그룹 수정
27 |
28 |
29 |
30 |
31 | 5. MySQL 접속하기
32 |
33 | ```
34 | $ mysql -u {user-name} -p -h {end-point}
35 | ```
36 |
37 | 6. 사용할 DB 생성
38 |
39 | ```
40 | $ create database {database-name};
41 | ```
42 |
43 | 7. MySQL 연동하기 (application.yml)
44 |
45 | ```yml
46 | datasource:
47 | url : jdbc:mariadb://rds엔드포인트:포트명/database이름
48 | username : db계정
49 | password : db계정 비밀번호
50 | driver-class-name: org.mariadb.jdbc.Driver
51 | ```
--------------------------------------------------------------------------------
/DevOps/docker.md:
--------------------------------------------------------------------------------
1 | # Docker의 개념 및 핵심 설명
2 |
3 |
4 | ### Docker 이란 Go 언어로 작성된 리눅스 컨테이너 기반으로 하는 오픈소스 가상화 플랫폼이다.
5 | 현재 Docker 0.9 버전 부터는 직접 개발한 libcontainer 컨테이너를 사용하고 있다.
6 |
7 | ## 가상화를 사용하는 이유?
8 | 이제는 향상된 컴퓨터의 성능을 더욱 효율적으로 사용하기 위해 가상화 기술이 많이 등장하였다.
9 | 서버 관리자 입장에서 CPU 사용율이 10% 밖에 되지 않는 활용도 낮은 서버들의 리소스 낭비일 수 밖에 없다.
10 | 그렇다고 모든 서비스를 한 서버안에 올린다면 안정성에 문제가 될 수도 있습니다.
11 | 그래서 안정성을 높이며 리소스도 최대한 활용할 수 있는 방법으로 나타난게 서버 가상화이다.
12 | 모두가 아는 대표적인 가상화 플랫폼으로는 VM이 있다.
13 | VM은 누구나 아는 OS 가상화이다. 그렇다면 컨테이너란 무엇일까?
14 |
15 | ## 컨테이너란?
16 |
17 |
18 | 컨테이너는 가상화 기술 중 하나로 대표적으로 LXC가 있다.
19 | 기존 OS를 가상화 시키던 것과 달리 컨테이너는 OS레벨의 가상화로 프로세스를 격리시켜 동작하는 방식이다.
20 | 한 서버의 여러 OS를 가상화 하여 사용하는 것과 컨테이너 방식으로 프로세스를 격리시켜 동작하는 방법은 어떠한 차이점이 있을까요?
21 |
22 |
--------------------------------------------------------------------------------
/DevOps/docker/springboot-docker.md:
--------------------------------------------------------------------------------
1 | ## Springboot 프로젝트를 도커로 실행시키기
2 |
3 | ### 🐳 Dockerfile 만들기
4 | 여기서 주의사항 "무조건 SpringBoot_app root 에 ``Dockerfile`` 만들기"
5 |
6 | ```
7 | $ vim Dockerfile
8 | ```
9 |
10 | Dockerfile 내용
11 |
12 | ```dockerfile
13 | # docker start with a base image containing java runtime
14 | FROM openjdk:11
15 |
16 | # Add Author information
17 | LABEL maintainer="s20062@gsm.hs.kr"
18 |
19 | # Add a volume to /tmp
20 | VOLUME /tmp
21 |
22 | # Make port 8080 available to the world outside this container
23 | EXPOSE 8080
24 |
25 | # The application's jar file
26 | ARG JAR_FILE=target/the-0.0.1-SNAPSHOT.jar
27 |
28 | # Add the application's jar to the container
29 | ADD ${JAR_FILE} the_moment_server.jar
30 |
31 | # Run the jar file
32 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/the_moment_server.jar"]
33 |
34 | ```
35 |
36 | 해석하자면..
37 | > 1. openjdk:11 을 사용할것이다.
38 | > 2. maintainer 이메일은 "s20062@gsm.hs.kr" 이다.
39 | > 3. 8080 포트로 바인딩 할 것이다.
40 | > 4. JAR 파일 위치는 여기다.
41 | > 5. 이 JAR 파일을 컨테이너로 만들어주세요.
42 |
43 | ### 📦 사용방법
44 | * 빌드하기
45 | ```
46 | $ docker build -t dockerhub ID/project_name:tag .
47 | ```
48 | * 실행시키기
49 | ```
50 | $ docker run -name ConatinerName -d -p 5000:8080 dockerhub ID/project_name:tag
51 | ```
52 | * 배포확인
53 | ```
54 | $ (sudo) docker ps
55 | ```
--------------------------------------------------------------------------------
/DevOps/notion-targeting.md:
--------------------------------------------------------------------------------
1 | ## 노션사이트 내 도메인 주소로 redirect 하기.
2 | > [도움을 주셔서 감사합니다 🙇🏻♂️](https://fruitionsite.com/)
3 |
4 | 1. CloudFlare 에 가입해서 DNS를 등록해준다.
5 | 2. CloudFlare의 네임서버를 도메인 관리 서비스에 등록해준다.
6 | 3. 연결을 원하는 도메인을 CNAME 으로 생성하고 대상을 notion.so 로 설정해준다.
7 | 4. 위에 안내한 사이트에 따라 script를 worker 로 만들어 등록해주고
8 | 5. 생성한 도메인에 그 worker을 등록해준다.
--------------------------------------------------------------------------------
/DevOps/solve-50x-error.md:
--------------------------------------------------------------------------------
1 | ## ELB 에서 발생하는 50x 문제 해결
2 |
3 | ### 문제 해결 방법에 앞서서........
4 | 1. ELB 생성을 꼼꼼하게 하자.
5 | 2. 코드, 환경은 거짓말 하지 않는다.
6 |
7 | ### 해결을 위해 참고 해야하는 문제 유형
8 |
9 | HTTP 502(잘못된 게이트웨이)
10 | > EC2 인스턴스에서 실행 중인 웹 서버 또는 연결된 백엔드 애플리케이션 서버가 CLB(Classic Load Balancer)에서 구문 분석 할 수 없는 메시지를 반환하면 HTTP 502 오류가 발생할 수 있습니다.
11 |
12 |
13 | HTTP 504(게이트웨이 제한 시간)
14 | > 웹 서버 인스턴스 또는 백엔드 애플리케이션 서버 인스턴스가 사용 중이며 구성된 ELB(Elastic Load Balancing) 유휴 시간 제한 내에서 요청에 응답할 수 없습니다.
15 |
16 |
17 | > 로드 밸런서가 연결을 종료하기 전에 웹 서버 인스턴스 또는 백엔드 애플리케이션 서버 인스턴스가 연결을 종료하므로 연결이 조기에 종료됩니다.
18 |
19 |
20 | > 요청이 진행 중일 때 웹 서버 인스턴스 또는 백엔드 애플리케이션 서버 인스턴스가 서버 프로세스를 중단시키거나 재시작하여 결과적으로 서버가 모든 연결을 끊게 됩니다.
21 |
22 |
23 | 나는 우선 502 error에 하루동안 빠져있었는데..
24 | 그냥 다시 ELB를 차근차근 만들어보자.
25 |
26 |
27 |
28 | 나는 대상 등록에서의 문제였다.
29 | ``http:80`` , ``https:443`` 을 넣는게 아니라 자신이 포워딩 하고자 하는 ``5000`` docker-compose app port 를 넣어 추가해야한다.
--------------------------------------------------------------------------------
/DevOps/springbootDocker.md:
--------------------------------------------------------------------------------
1 | ## 스프링부트 도커에 올리기
2 |
3 | index
4 | * Dockerfile
5 | * Docker Build
6 | * Docker Run
7 |
8 | ## Dockerfile
9 | 도커가 이해할 수 있는 Dockerfile이라는 것응ㄹ 만들어 줘야 한다
10 | 어떤 자바를 사용 할 것인지, 어떤 어플리케이션을 사용 할 것인지, 어떤 명령어로 이 도커 컨테이너를 실행시켜야 되는지
11 |
12 |
13 | 일단 SpringBoot root 디렉토리에 ``Dockerfile``을 만들자.
14 |
15 | ```Dockerfile
16 | # Start with a base image containing Java runtime
17 | FROM java:8
18 |
19 | # if you want to use java 11,
20 | FROM centos
21 | RUN yum install -y java-11
22 |
23 | # Add Author info
24 | LABEL maintainer="authinfo@gmail.com"
25 |
26 | # Add a volume to /tmp
27 | VOLUME /tmp
28 |
29 | # Make port 8080 available to the world outside this container
30 | EXPOSE 8080
31 |
32 | # The application's jar file [jar file이 있는 위치]
33 | ARG JAR_FILE=build/libs/MySpringApp-0.0.1-SNAPSHOT.jar
34 |
35 | # Add the application's jar to the container [어떤 이름으로 하고 싶은지 지정]
36 | ADD ${JAR_FILE} to-do-springboot.jar
37 |
38 | # Run the jar file
39 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/to-do-springboot.jar"]
40 | ```
41 |
42 | Docker build
43 |
44 | 이제 작성한 도커파일로 도커 이미지를 만들어야 한다.
45 | 도커 이미지를 만드는 명령어는 간단하다 ``Dockerfile``이 존재하는 디렉토리 아래에서 실행시켜야 한다는 점을 명심해라.
46 |
47 | ```shell
48 | $ cd */
49 | $ docker build -t {my jar name} .
50 | ```
51 |
52 | ``Successfully tagged...``로 끝나면 완료 된 것이다.
53 |
54 | Docker Run
55 |
56 | * Docker images 가 제대로 만들어 졌는지 확인
57 |
58 | ```shell
59 | $ docker images
60 | ```
61 |
62 | * Docker image 를 이용해 도커 컨테이너를 실행 해 보자.
63 |
64 | ```shell
65 | $ docker run -p 5000:8080 {my jar name}
66 | ```
67 |
68 | * 이렇게 하면 개발당시에는 8080을 사용하고 도커에 올리고 나서는 5000포트를 이용 할 수 있다는 장점이 있다.
69 |
70 |
--------------------------------------------------------------------------------
/DevOps/themoment-v1.1.1-issue.md:
--------------------------------------------------------------------------------
1 | ## 학교가 불편한 순간 - 서버 v1.1.1 트러블슈팅 여정기 - redis
2 |
3 | #### docker redis unable to connect error
4 | [🥕 여기를 참고했습니다](https://github.com/luin/ioredis/issues/763#issuecomment-451041838)
5 | 하지만.. 왜 아직도 connect 가 안되는거야? 똑같은 error log 가 발생하네? 해서 docker-compose 자체에도 cache 가 있는지 구글링을 하게 됩니다.
6 |
7 | 여기서!!! 원하는 답을 얻게됩니다.!!
8 | [🥕 여기를 참고했습니다](https://medium.com/sjk5766/docker-compose-cache-%EC%97%86%EC%9D%B4-%EC%84%A4%EC%B9%98%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-4ac3561815be)
9 |
10 | 바로 아래와 같은 command 를 사용하여 다시 실행해보기로 하는데요..!!
11 | ```sh
12 | $ docker-compose build --no-cache
13 | ```
14 |
15 | 결과는 success!! 그래서 바로 `docker-compose-env.sh` 라는 저희가 만든 자동 실행 쉘스크립트 맨 처음에 넣어주게 됩니다!!
16 |
17 |
--------------------------------------------------------------------------------
/DevOps/tooManyRedirection.md:
--------------------------------------------------------------------------------
1 | ## xx.com 리디렉션 횟수가 많습니다.
2 | > 서버를 재시작 해보기도 했지만. 의외로 해결방안은 간단했다.
3 |
4 |
5 |
6 | 그냥 아래와 같이 SSL/TSL 설정을 변경해주니깐 정상적으로 작동하였다.
7 |
8 |
--------------------------------------------------------------------------------
/DevOps/use-nohup.md:
--------------------------------------------------------------------------------
1 | ## nohup 명령어 사용하기
2 |
3 | ### 우선 ``nohup``이란?
4 | > nohup이란 리눅스, 유닉스에서 쉘스크립트파일 (*.sh)을 데몬형태로 실행시키는,
5 | > 프로그램 터미널 세션이 끊겨도 실행을 멈추지 않고 동작하도록 하게 하는 명령어.
6 |
7 |
8 | ### 사용하기
9 |
10 | 1. ``ubuntu``에 nohup 명령어 설치.
11 |
12 | ```
13 | $ sudo apt-get install nohup
14 | // 여기서 nohub 이 아니라 nohup 이라는 점 헷갈리지 않기.
15 | ```
16 |
17 | 2. 내가 `nohup` 으로 사용하고자 하는 `.sh` 파일의 권한을 755 로 준다.
18 |
19 | ```
20 | $ chmod 755 ./{/sh file name}
21 | ```
22 |
23 | 3. `nohup` 으로 프로젝트 파일 run
24 |
25 | ```
26 | $ sudo nohup ./{/sh file name}
27 | ```
28 |
29 | 4. 여기서 생소한 문구를 발견한다면..
30 |
31 | ```
32 | nohup: ignoring input and appending output to 'nohup.out'
33 |
34 | // 당황하지 말고
35 | $ ls
36 | nohup.out
37 |
38 | $ cat nohup.out
39 | // nohup으로 실행한 화면의 출력이 여기에 기록된다.
40 | ```
--------------------------------------------------------------------------------
/Extra/nest/fast-nest-env.md:
--------------------------------------------------------------------------------
1 | ## nest 빠르게 환경 구성하기
2 |
3 | ### Installation
4 | > https://docs.nestjs.kr/
5 |
6 | nest CLI 를 사용하면 빠르게 프로젝트를 스캐폴딩하거나 시작 할 수 있습니다.
7 |
8 | 1. Global install nestjs cli
9 | ```
10 | $ npm i -g @nestjs/cli
11 | ```
12 |
13 | 2. get start nest project
14 | ```
15 | $ nest new project-name
16 | ```
17 |
18 | 이런 방법도 있습니다 **Git**으로 Ts 시작 프로젝트를 설치하려면..
19 | ```
20 | $ git clone https://github.com/nestjs/typescript-starter.git project
21 | $ cd project
22 | $ npm install
23 | $ npm run start
24 | ```
--------------------------------------------------------------------------------
/GitHub/delPush.md:
--------------------------------------------------------------------------------
1 | # 엎질러진 github 명령 취소하기
2 |
3 | ## git add 취소하기
4 | 먼저 모든 파일을 스테이징한다.
5 | ```
6 | $ git add .
7 |
8 | // 파일들의 상태를 확인한다.
9 | $ git status
10 | ...
11 | modified: ***.md
12 | ```
13 | git reset HEAD [file] 명령어를 통해 git add를 취소한다.
14 | ```
15 | $ git reset HEAD ***.md
16 | ```
17 |
18 | ## git commit 취소하기
19 | 우선 commit 목록을 확인한다.
20 | ```
21 | $ git log
22 | ```
23 | 방법 1
24 | > commit을 취소하고 해당 파일들은 staged 상태로 워킹 디렉터리에 보존
25 | ```
26 | $ git reset --soft HEAD^
27 | ```
28 | 방법 2
29 | > commit을 취소하고 해당 파일들은 unstaged 상태로 디렉터리에 보존
30 | ```
31 | $ git reset --soft HEAD^
32 | $ git reset HEAD^
33 | // 마지막 커밋 2개를 취소
34 | $ git reset HEAD~2
35 | ```
36 | 방법 3
37 | > commit을 취소하고 해당 파일들은 unstaged 상태로 디렉터리에서 삭제
38 | ```
39 | $ git reset --hard HEAD^
40 | ```
41 |
42 | ## git commit message 변경하기
43 | git commit -amend를 통해 git commit message를 변경할 수 있다.
44 | ```
45 | $ git commit --amend
46 | ```
47 |
48 | ## git reset 명령어의 옵션
49 | 1. -soft: index 보존, 디렉터리 보존, 모두 보존.
50 | 2. -mixed: index 취소, 디렉터리 보존, 기본 옵션.
51 | 3. -hard: index 취소, 디렉터리 삭제, 모두 삭제.
52 |
53 | ## git push 취소하기
54 | 1. 가장 최근의 commit을 취소한다.
55 | ```
56 | $ git reset HEAD^
57 | ```
58 | 2. 원하는 시점으로 워킹 디렉터리를 되돌린다.
59 | ```
60 | $ git reflog
61 | $ git reset HEAD@{number} or $ git reser [commit id]
62 | ```
63 | 3. 이 상태에서 다시 commit
64 | ```
65 | $ git commit -m " "
66 | ```
67 | 4. git 강제 push
68 | ```
69 | $ git push origin [branch name] -f
70 | ```
71 |
--------------------------------------------------------------------------------
/Lecture/JAVA/IS-A.md:
--------------------------------------------------------------------------------
1 | ## IS-A 관계
2 | > 상속에 개념에서 나오는 관계이다.
3 |
4 | ### ex.
5 | Dog.class 는 Animal class 를 extends 받았다.
6 | Dog은 Animal의 하위 개념이라고 볼 수 있다. 이런 경우에 Dog은 Animal에 포함되기 때문에 "개는 동물이다"라고 표현 가능하다.
7 |
8 | 자바는 이러한 관계를 IS-A 관계라고 한다. 즉 "Dog `is a` Animal" 과 같이 말 할 수 있다.
9 |
10 | 다음과 같은 코딩이 가능하다.
11 | ```java
12 | Animal dog = new Dog();
13 | ```
14 |
15 | 하지만 이 반대의 경우, 즉 부모 클래스로 만들어진 객체를 자식 클래스의 자료형으로는 사용할 수 없다.
16 | ```java
17 | Dog dog = new Animal();
18 | ```
19 |
20 | 이 부분을 좀 더 개념적으로 살펴보면
21 | ```java
22 | Animal dog = new Dog();
23 | ```
24 |
25 | 위 코드를 읽어보면 "개로 만든 객체는 동물 자료형이다."라고 읽을 수 있다.
26 |
27 | 또 다음 코드를 보자
28 | ```java
29 | Dog dog = new Animal();
30 | ```
31 | 동물로 만든 객체는 개 자료형이다. 라고 읽을 수 있다.
32 | 뭔가 이상하지 않는가? 동물로 만든 객체는 개 자료형 말고 호랑이 자료형 또는 사자 자료형도 될 수 있지 않는가?
33 |
34 | 개념적으로 살펴보아도 두번째 코드는 성립할 수 없다.
35 |
36 | 자바에서 만드는 모든 클래스는 `Object`라는 클래스를 상속받게 되어 있다.
37 | 사실 우리가 만든 `Animal` 클래스는 다음과 기능적으로 완전히 동일하다. 하지만 굳이 아래 코드처럼 Object 클래스를 상속하도록 코딩하지 않아도 자바에서 만들어지는 모든 클래스는 Object 클래스를 자동으로 상속받게끔 돼 있다.
38 |
39 | ```java
40 | public class Animal extends Object {
41 | String name;
42 |
43 | public void setName(String name){
44 | this.name = name;
45 | }
46 | }
47 | ```
48 |
49 | 따라서 자바에서 만드는 모든 객체는 Object 자료형으로 사용할 수 있다.
50 | ```java
51 | Object animal = new Animal();
52 | Object dog = new Dog();
53 | ```
54 |
--------------------------------------------------------------------------------
/Lecture/JAVA/Immutable-with-string.md:
--------------------------------------------------------------------------------
1 | # Java StringBuilder를 쓰는 이유
2 |
3 | ```java
4 | String literal1 = "hello world";
5 | String literal2 = "hello world";
6 | String notLiteral = new String("hello world");
7 |
8 | assertFalse(literal1 == notLiteral);
9 | ```
10 |
11 | String literal은 같은 문자열인 경우 Heap Memory/String pool 전체에서 하나만 존재한다.
12 | `literal1` `literal2` 모두 같은 내용의 literal 문자열인 경우에는 `assertTrue()`를 정상적으로 통과 해야한다.
13 |
14 | ```java
15 | assertTrue(literal1.hashCode() == literal2.hashCode());
16 | ```
17 |
18 |
19 |
20 |
21 |
22 | 하지만 `notLiteral` 문자열은 `new String` Reference Type을 통해 같은 내용의 문자열임에도, 메모리에 새롭게 생성합니다.
23 |
--------------------------------------------------------------------------------
/Lecture/JAVA/JVM-JRE-JDK.md:
--------------------------------------------------------------------------------
1 | ## JVM과 JRE, JDK의 차이는 무엇인가?
2 | 1. JVM은 컴파일 된 클래스 파일을 구동하는 역할을 한다. (실제 자바 프로그램 실행자 역할)
3 | 2. JRE는 Java Runtime Environment 로 자바 프로그램이 실행될 수 있는 환경을 말한다.
4 |
5 | * Class Loader - 컴파일 된 클래스 파일을 메모리에 로딩
6 | * Bytecode verifier - 로딩된 클래스 파일의 정보가 플랫폼에서 실행되는지 문제가 있는지 없는지 검증
7 | * Java Virtual Machine - 검증된 클래스 파일을 플랫폼에서 실행 시켜 준다.
8 |
9 |
10 | JVM은 JRE의 한 부분으로 JRE는 클래스 파일이 주어지는 동안 자바가 실행될 수 있는 환경을 제공한다.
11 |
12 | 그렇다면.. JDK 는 Java Development Kit 프로그램 개발을 위한 것을 제공한다.
13 |
14 | 컴파일러 - javac, 개발을 위한 데이터베이스, 개발에 필요한 여러가지 툴 셋
15 |
16 |
--------------------------------------------------------------------------------
/Lecture/JAVA/JVM.md:
--------------------------------------------------------------------------------
1 | ## JVM 이란?
2 |
3 | ### JVM 이란
4 | `Java Virtual Machine` 의 줄임말 이며, Java Byte Code 를 OS에 맞게 해석 해주는 역할을 한다.
5 | Java Compiler는 `.java` 파일을 `.class` 라는 java byte code로 변환시켜 줍니다.
6 | Byte Code는 기계어가 아니기 때문에 OS 에서 바로 해석되지 않습니다.
7 | 하지막 JVM의 해석은 OS가 ByteCode를 이해할 수 있도록 해줍니다.
8 |
9 | 하지만.. JVM의 해석을 거치기 때문에 c언어 같은 네이티브 언어에 배해 속도가 느렸지만 JIT(Just In Time)컴파일러를 구현해 이점을 극복했습니다.
10 |
11 | **ByteCode 는 JVM 위에서 OS상관없이 실행된다.** 이런점이 java의 큰 장점이라고 할 수 있습니다. OS에 종속적이지 않고 Java 파일 하나만 만들면 어느 디바이스든 JVM 위에서 실행 할 수 있습니다.
12 |
13 | JVM은 `Class Loder`, `Runtime Data Areas`, `Excution Engine` 이렇게 3가지로 구성 돼 있습니다.
14 |
15 |
16 |
17 | ### JVM 구조
18 | 1. Class Loader
19 | 1. RunTime 시점에 클래스를 로딩하게 해주며 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드하게 됩니다.
20 | 2. Runtime Data Areas
21 | 1. JVM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당 받은 메모리 공간을 말하며, Runtime Data Areas는 크게 5가지 영역으로 나눌 수 있다.
22 | 1. PC register `Java는 Platform 에 종속받지 않는다`
23 | 2. Java Virtual Machine Stack `Tread 시작 시, 생성 다른 Thread에는 접근 불가능`
24 | 3. Native Method Stack
25 | 4. Method Area `클래스, 인터페이스, 메서드, 필드, static 등 바이크 코드 보관`
26 | 5. Heap `ClassA a = new ClassA();`
27 |
28 | 3. Execution Engine
29 | > Load된 Class의 ByteCode를 실행하는 Runtime Module이 바로 Execution Engine 입니다.
30 |
31 | > Class Loader를 통해 JVM 내의 Runtime Data Areas에 배치된 바이트 코드는 Executin Executin Engine에 의해 실행되며, 실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행합니다.
32 |
--------------------------------------------------------------------------------
/Lecture/JAVA/POJO.md:
--------------------------------------------------------------------------------
1 | ## POJO 란 무엇인가
2 | 정의
3 | > Plain Old Java Object 의 약자로 직역을 하자면 평범한 구식 자바 오브젝트이다.
4 | > 무거운 EJB와 반대로 경량의 자바 객체를 의미한다.
5 |
6 | 여기서 말하는 EJB란
7 | Enterprise JavaBean의 약자로 자바 기술 중 하나이다.
8 |
9 | 좋은 취지로 나온 기술이지만..
10 | EJB의 혜택을 얻기 위해서는 기능이 필요하지도 않은 WAS를 구입해야 했고, 고급 IDE 도움 없이는 복잡한 설정에 허우적 대야 했다.
11 |
12 | 그래서 객체지향 원리에 따라 만들어진 자바 언어의 기본에 충실하게 비지니스 로직을 구현하는 일명 `POJO` 방식으로 돌아와야 한다는 목소리가 높아졌다. (요즘 Jquery가 많이 무거워져 순수 자바스크립트인 바닐라.js로 돌아가는것과 같은 양상이다.)
13 |
14 | ### POJO 의 특징
15 | POJO는 종속되지 않는 자바 객체를 통칭한다.
16 |
17 | EJB같은 경우에는 `implements, extends`를 사용하는 코드들이 많다.
18 | 그럴 경우에 빈 하나를 만들기 위해 다양한 부모클래스를 참조해야하고, 그러면 클래스간 의존도가 높아져, 나중에는 뭐가 어디서 상속되며 무엇이 있는지 헷갈리기 시작한다.
19 |
20 | 그래서 POJO는 이러한 복잡한 것은 버리고, 간단한 자바 객체만을 가지고 일을 처리하자는 철학을 가지고 있다.
21 |
22 | 현재 POJO는 자바빈(Java Bean)으로 사용되고 있다. JavaBean은 기본 생성자와 멤버 필드에 접근 할 수 있는 `getter/setter` 메서드를 가진 단순 자바 오브젝트이다.
23 |
24 | POJO를 이용한 디자인이 널리 쓰임에 따라 POJO 기반의 프레임워크들이 탄생하게 되었는데 그 중에서도 가장 대표적인 것이 스프링이다.
25 |
26 | ### POJO 하면 가장 대표적으로 들을 수 있는 단어
27 |
28 | 1. IoC/DI
29 | - 스프링의 가장 기본이 되는 기술이자 스프링 핵심 개발원칙이다.
30 |
31 | 2. AOP
32 | - 핵심 관심사를 분리하여 프로그램의 모듈화를 향상시키는 프로그래밍 스타일이다.
33 |
34 | 3. PSA
35 | - 인터페이스가 다른 다양한 구현을 같은 방식으로 사용하도록 중간에 인터페이스 어댑터 역할을 해주는 레이어를 추가하는 방법이다.
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Lecture/JAVA/Procedure-oriented&object-oriented.md:
--------------------------------------------------------------------------------
1 | # 절차지향 언어와 객체 지향 언어의 차이는?
2 |
3 | ## 절차지향
4 | Top -> Bottom: 순차적인 처리가 중요시 된다.
5 | 하드웨어와 소프트웨어의 개발 속도차이가 크지 않았다면 지금은 하드웨어의 개발속도가 소프트웨어의 속도를 따라오지 못하는 상황이 발생한다.
6 |
7 | ### 장점
8 | * 컴퓨터의 처리구조와 유사해 실행속도가 빠르다.
9 | * 메모리를 직접 조작할 수 있다.
10 |
11 | ### 단점
12 | * 유지보수가 어렵다.
13 | * 실행 순서가 정해져 있어 코드의 순서가 바뀌면 동일한 결과를 보장하기 힘들다.
14 | * 원하는 기능의 코드를 가져와서 복붙하면 오류가 발생한다.
15 |
16 |
17 | ## 객체지향
18 | 실제 세계를 모델링 하여 소프트웨어를 개발할 수 있다.
19 | 데이터와 절차를 하나의 덩어리로 묶어서 생각해야 되고 마치 컴퓨터 부품들을 하나씩 모아서 조립하는 것처럼 개발하는 것이다.
20 |
21 | ### 1. 캡슐화
22 | - 데이터와 알고리즘이 하나의 묶음으로 정리된 것이다.
23 | - 데이터를 감추고 외부 세계와의 상호작용은 메소드를 통하는 방법이다.
24 | - 메소드: 메세지에 따라 실행시킬 프로시저로서 객체지향 언어에서 사용되는 것.
25 | > 객체지향 언어에서는 메시지를 보내 메소드를 수행시킴으로써 통신을 한다.
26 |
27 |
28 | ### 2. 상속
29 | - 상속이란 이미 작성된 클래스들을 이어받아서 새로운 클래스를 생성하는 기법이다.
30 | - 절차지향과 비교되는 객체지향 방법의 가장 큰 장점중 하나라고 볼 수 있다.
31 |
32 | ### 3. 다형성
33 | - 다형성이란 하나의 이름으로 많은 상황을 대처하는 기법을 말한다.
34 | - 작업을 하는 함수들에 똑같은 이름을 부여할 수 있고 코드가 더 간단해지는 효과를 볼 수 있다.
35 |
36 | ## 객체지향의 장점
37 | 1. 신뢰성있는 소프트웨어를 쉽게 작성할 수 있다.
38 | 2. 코드 재사용이 쉽다.
39 | 3. 업그레이드가 쉽다(함수들이 유기적으로 연결 돼 있지 않기 때문에 가능하다.)
40 |
41 | > 객체지향 언어는 어떤 모듈에 있는 하나의 기능만 필요하더라도 모듈 전체를 가져와야 하기 때문에 절차지향 언어보다 프로그램 사이즈가 커질 수 있다. 또한 데이터에 대한 접근도 절차지향보다 느려질 가능성이 많다.
--------------------------------------------------------------------------------
/Lecture/JAVA/Reference-veriable.md:
--------------------------------------------------------------------------------
1 | # 참조형 변수
2 | > 자바는 크게 Primitive Type 과 Reference Type으로 분류됩니다.
3 |
4 | ## primitive type, Reference Type
5 | ```java
6 | class ManyType {
7 | // Primitive type
8 | int a = 10;
9 | char myChar = 'm';
10 |
11 | // Reference type
12 | String s = "Hello, world!";
13 | }
14 | ```
15 |
16 | 메모리에서 이 변수들이 갖는 값을 그림을 그리면 아래와 같습니다.
17 |
18 |
19 | ## 메모리 사용 영역
20 |
21 |
22 | ### 메소드 영역
23 | 메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유되는 영역입니다.
24 | 메소드 영역에서는 코드에 사용되는 class 들을 클래스 로더로 읽어 클래스 별로 static feild 와 constant, method code, constructor code 등을 분류해서 저장합니다.
25 |
26 | ### 힙 영역
27 | 힙 영역은 객체와 배열이 생성되는 영역입니다. 여기에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조합니다.
28 | 만일 참조하는 변수나 필드가 없다면 의미없는 객체가 되기 때문에 JVM에서는 GC로 처리합니다.
29 |
30 | ### 스택 영역
31 | JVM 스택은 메소드를 호출할 때마다 frame 을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행합니다 (재귀함수)
32 |
33 | 프레임 내부에서는 로컬 변수 스택이 있는데 기본 타입 변수와 참조 타입 변수가 추가되거나 제거됩니다. 스택 영역에 변수가 생성되는 시점은 최초로 변수의 값이 저장될 때입니다. 변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거됩니다.
34 |
35 | ## 결론
36 | 참조형 변수는 기본형 변수와는 다르게 실제 값을 그대로 저장하는 공간이 아니라 Heap 영역에 값이 저장된 공간의 주소값을 저장하는 공간이라는 것이다.
37 |
38 | **즉, 기본형 변수는 실제 값을 저장하고, 참조형 변수는 주소 값을 저장하고 있는 것이다.**
--------------------------------------------------------------------------------
/Lecture/JAVA/Serialization.md:
--------------------------------------------------------------------------------
1 | # 직렬화(Serialization)란?
2 |
3 | > 도움을 주셔서 감사합니다 🙇🏻♂️
4 | > https://medium.com/@lunay0ung/basics-%EC%A7%81%EB%A0%AC%ED%99%94-serialization-%EB%9E%80-feat-java-2f3eb11e9a8
5 |
6 | 객체를 저장하거나 메모리, 데이터베이스 혹은 파일로 옮기려면 어떻게 해야할까?
7 | 이럴 때 필요한 것이 직렬화다.
8 |
9 | 직렬화란 객체를 바이트 스트림으로 바꾸는 것, 즉 객체에 저장된 데이터를 스트림에 쓰기 위해 연속적인 serial 데이터로 변환하는 것이다.
10 |
11 | 직렬화의 주된 목적은 객체를 상태 그대로 저장하고 필요할 때 다시 생성하여 사용하는 것이다.
12 |
13 |
14 |
15 | 역직렬화는 Deserialization은 직렬화의 반대말로, 네트워크나 영구저장소에서 바이트 스트림을 가져와서 객체가 저장되었던 바로 그 상태로 변환하는 것이다.
16 |
17 | 직렬화하면서 생긴 바이트 스트림은 플랫폼에 독립적이다.
18 | **직렬화된 객체는 다른 플랫폼에서 역직렬화가 가능하다는 뜻이다.**
19 |
20 | ## Serializable
21 | 모든 클래스에서 직렬화 할 수는 없다. `java.io.Serializable` 인터페이스를 구현한 클래스의 객체만 직렬화될 수 있다.
22 |
23 | serializable 인터페이스는 어떤 멤버변수나 메서드도 가지고 있지 않은 마커 인터페이스이다. 해당 인터페이스를 구현한 클래스가 특정 능력을 가진다고 표시 해두기 위해 쓰인다는 뜻이다.
24 |
25 | 단, 클래스에 비밀번호와 같이 보안상 직렬화되면 안 되는 값이나 직렬화가 될 수 없는 객체에 대한 참조가 포함된 경우 transient 라는 제어자를 이용할 수 있다. transient 가 붙은 인스턴스 변수의 값은 그 타입의 기본값으로 직렬화된다.
26 |
27 | ## SerialVersionUID
28 | 직렬화된 객체를 역직렬화 할 때엔 직렬화 당시 클래스와 같은 클래스를 사용해야 하는데, 클래스명이 같더라도 내용이 변경된 경우 역직렬화는 실패한다.
29 |
30 | 클래스 일치여부를 구별하는 기준은 SerialVersionUID로, 직렬화되는 클래스가 명시적으로 serialVersionUid를 선언하지 않으면 직렬화시 자동 생성 되어 직렬환 내용에 포함된다.
31 |
32 | serialVersionUID는 컴파일러 실행에 따라 변경될 수 있는 클래스의 세부 사항에 매우 민감한 반면, 클래스 내에 serialVersionUID를 정의할 경우 클래스 내용이 변경되어도 클래스 버전은 업데이트되지 않으므로 직렬화시에는 serialVersionUID를 정의할 것이 권장된다.
33 |
34 | ## 직렬화가 뭔지 와닿지 않는다면..
35 |
36 |
37 |
38 | 상대방에게 새로 입양한 Rex를 있는 그대로 설명하고 싶지만..
39 | 어떤 사진이나 바디 랭귀지 없이 전화상으로 말로만 하기엔 어려운 일이다.
40 |
41 | 하지만..
42 | ```
43 | {
44 | "name": "Rex"
45 | "age": 5
46 | "fav_food": "apple"
47 | ...
48 | }
49 | ```
50 |
51 | 이렇게 강아지가 가진 특성을 객체로 생성해서 직렬화한 후 통화 상대방에게 보내면 일이 보다 간단해진다.
--------------------------------------------------------------------------------
/Lecture/JAVA/async-nonblocking.md:
--------------------------------------------------------------------------------
1 | ## 동기, 비동기 | 블록킹, 논블록킹
2 | > fcm 서버를 구성하다가 내가 위와 같은 개념들을 혼용해서 쓴다는 생각이 들어 글로 정리한다.
3 |
4 | #### 동기 비동기 그리고 블록킹 논블록킹
5 | 우선 이 개념은 프로그램을 개발할 때 중요한 개념이다. 개발자들 사이에서도 로직을 개발하거나 기획할 때 위 개념을 이해한 정도에 따라 오해석이 발생할 수 있다.
6 |
7 | 우선 `동기 비동기 == 블록킹 논블로킹` 이라고 혼용하여 사용하는 경우가 있지만 둘은 서로 다른 개념이다. 연관관계가 없는 별개의 개념이라는 것이다.
8 |
9 | 동기/비동기는 작업을 수행하는 주체가 두 개(A, B) 이상이여야 한다. 이 때 작업은 시간(시작, 종료 등)을 서로 맞춘 다면 "동기"가 되는 것이고, 서로 작업의 시간이 관계가 없다면 "비동기"가 된다는 것이다.
10 |
11 | 반면에 블록킹/논블록킹은 작업의 대상이 2개 이상이여야 한다.
12 |
13 |
14 | 두 개념이 서로 바라보는 관점이 다르기 때문에 다양한 조합이 가능합니다.
15 | ex) 동기/블록킹, 동기/논블록킹, 비동기/블록킹, 비동기/논블록킹
16 |
17 | ### 동기/비동기
18 | 동기 작업이란 작업을 수행하는 두 개 이상의 주체가 동시에 수행하거나 동시에 끝나거나 끝나는 동시에 시작할 때를 의미한다. 시작과 종료를 동시에 하거나, 하나의 작업이 끝나는 동시에 다른 주체가 작업을 시작하면 이를 동기 작업이라고 볼 수 있다.
19 |
20 | 비동기 작업은 두 주체가 서로의 시작, 종료시간과는 관계 없이 별도의 수행 시작/종료시간을 가지고 있을 때를 뜻한다. 서로 다른 주체가 하는 작업이 자신의 작업 시작, 종료시간과는 관계가 없을 때 비동기라고 부를 수 있다.
21 |
22 |
23 |
24 | ### 블록킹/논블록킹
25 | 블로킹과 논블로킹은 다른 작업을 수행하는 주체를 어떻게 상대하는지가 중요하다.
26 | 자신의 작업을 하다가 다른 작업 주체가 하는 작업의 시작부터 끝까지 기다렸다가 자신의 작업을 수행한다면 **블록킹**.
27 | 다른 주체의 작업과 관계없이 자신의 작업을 계속한다면 이를 **논블로킹**이라고 할 수 있다.
28 |
29 | A쓰레드가 어떤 작업을 하는 다른 대상을 호출하고 그 대상이 가져온 결과를 받아 작업을 제개한다. 이러한 작업을 **블록킹**.
30 | 반대로 다른 주체에게 작업을 요청하고 그 결과를 받을 때까지 기다리지 않으며 자신의 작업을 한다면 이를 **논블록킹**이라고 한다.
31 |
32 |
33 |
34 | [-> stack overflow 에서도 이와 같은 정리를 확인할 수 있습니다](https://stackoverflow.com/questions/52234241/what-is-blocking-in-async-or-sync)
35 |
--------------------------------------------------------------------------------
/Lecture/JAVA/builder-pattern.md:
--------------------------------------------------------------------------------
1 | ## 빌더 패턴을 사용해야만 하는 이유
2 |
3 | #### 생성자와 수정자로 구현된 User 클래스를 바탕으로 왜 생성자나 수정자보다 빌더를 써야하는지 이해해보도록 하자
4 | ```java
5 | @NoArgsConstructor
6 | @AllArgsConstructor
7 | public class User {
8 | private String name;
9 | private int age;
10 | private int height;
11 | private int iq;
12 | }
13 | ```
14 |
15 | #### 빌더 패턴의 장점
16 | 1. 필요한 데이터만 설정할 수 있다.
17 | 2. 유연성을 확보할 수 있다.
18 | 3. 가독성을 높일 수 있다.
19 | 4. 불변성을 확보할 수 있다.
20 |
21 |
22 | #### 1. 필요한 데이터만 설정할 수 있음
23 | > User 객체를 생성해야 하는데 age 라는 파라미터가 필요 없는 상황이라고 가정하면,
24 | > 우리는 age에 더미를 넣어주거나 age 가 없는 생성자를 새로 만들어 줘야 한다.
25 | > 이런 작업이 한두번이면 괜찮지만, 반복적인 경우에는 시간 낭비로 이어지게 된다. 하지만 이러한 것을 빌더를 이용하면 동적으로 처리 가능하다.
26 |
27 |
28 | ```java
29 | User user = User.builder()
30 | .name("지환이는 개발자")
31 | .height(180)
32 | .iq(150).build();
33 | ```
34 |
35 | 그리고 이렇게 필요한 데이터만 설정할 수 있는 빌더의 장점은 테스트용 객체를 생성할 때 용이하게 해주고, 불필요한 코드의 양을 줄이는 등의 이점을 안겨준다.
36 |
37 | ### 2. 유연성을 확보할 수 있다.
38 | User에 몸무게를 나타내는 새로운 변수 weight 를 추가했다고 가정하면..
39 | 하지만 이미 다음과 같은 생성자로 객체를 만드는 코드가 있다고 해보자.
40 |
41 | ```java
42 | // ASIS
43 | User user = new User("망나니개발자", 28, 180, 150)
44 | // TOBE
45 | User user = new User("망나니개발자", 28, 180, 150, 75)
46 | ```
47 |
48 | 그러면 우리는 새롭게 추가되는 변수 때문에 기존의 코드를 수정해야 하는 상황에 직면하게 된다.
49 | 기존에 작성된 코드의 양이 방대하다면 감당하기 어려울 수 있지만 빌더 패턴을 이용하면 새로운 변수가 추가되는 등의 상황에 직면하더라도 기존의 코드에 영향을 주지 않을 수 있다.
50 |
51 | 이외에도..
52 |
53 | 3. 가독성을 높일 수 있고
54 | 4. 불변성을 확보 할 수 있다.
55 | 많은 개발자들이 수정자(Setter) 패턴을 흔히 사용한다. 하지만 Setter 를 구현하는 것은 불필요하게 확장 가능성을 열어두는 것이다.
56 | Open-Closed 법칙에 위반되고, (개방폐쇄의원칙) 불필요한 코드 리딩을 유발한다. 그렇기 때문에 클래스 변수를 final로 선언하고 객체의 생성은 빌더에게 맡기는 것이 좋다.
57 |
58 | ```java
59 | @RequiredArgsConstructor
60 | @Builder
61 | public class User {
62 | private final String name;
63 | private final int age;
64 | private final int height;
65 | private final int iq;
66 | }
67 | ```
68 |
69 | 다른 사람과 협업을 하거나 변경에 대한 요구 사항이 많은 경우라면 빌더 패턴을 이용해야 하는 이유를 더욱 극명하게 느낄 수 있다.
--------------------------------------------------------------------------------
/Lecture/JAVA/classLoader.md:
--------------------------------------------------------------------------------
1 | ## ClassLoader | 클래스로더
2 | > 간략하게 설명하자면.. `.java` 파일을 `.class` 파일로 바꿔주는 핵심적인 역할을 한다. (바이트코드로 변환하는 작업을 한다.)
3 | > 이렇게 생성된 .class 파일들을 엮어서 JVM 이 운영체제로 부터 할당받은 메모리영역인 Rumtime Data Area 로 적재하는 역할을 Class Loader 가 한다.
4 |
5 |
6 |
7 | 우선 classLoader 의 구조를 파악해보자
8 | ```java
9 | public class ClassLoaderEx {
10 | public static void main(String[] args) {
11 | ClassLoader classLoader = ClassLoaderEx.class.getClassLoader();
12 | System.out.println(classLoader);
13 | System.out.println(classLoader.getParent());
14 | System.out.println(classLoader.getParent().getParent());
15 | }
16 | }
17 | ```
18 |
19 |
20 |
21 | > 이렇게 ClassLoader는 `AppClassLoader` 이고.
22 | > `AppClassLoader` 의 부모는 `PlatformClassLoader` 이다.
23 | > 그 부모도 `BootstrapClassLoader` 라고 존재하지만, null 을 반환한다.
24 |
25 | * 이거에 대한 자료를 찾아보니..
26 | *
27 | * 결론적으로 일부 구현에서 `BootstrapClassLoader` 는 null로 나타낼 수 있다고 한다.
28 | * "네이티브코드로 구현되어 볼 수 없다" - 백기선
29 |
30 | #### 클래스를 읽어오는 순서(로딩)
31 | 부모(BootstrapClassLoader) -> 자식(PlatformClassLoader) -> 자식(AppClassLoader)
32 |
33 | 만약에 최하위 클래스에서 못 읽는다면.. `ClassNotFoundException` 이 발생.
34 | > ex) pom.xml 에 의존성 추가 안하고 App 을 실행시킬 때.
35 |
36 |
37 | ### 링크 (Link)
38 | * Verify: `.class` 파일의 형식이 유효한지 확인한다.
39 | * Prepare: 클래스 변수와 static 변수에 필요한 메모리
40 | * Resolve: 이건 `Optional` 이다 "적절한 Heap 영역을 가르킬수도 있고 아닐 수도 있다."
--------------------------------------------------------------------------------
/Lecture/JAVA/constructor.md:
--------------------------------------------------------------------------------
1 | ## 생성자
2 | > 메서드명이 클래스명과 동일하고 리턴 자료형이 없는 메서드를 생성자라고 한다.
3 |
4 | ### 생성자의 규칙
5 | * 클래스명과 메서드명이 동일하다.
6 | * 리턴타입을 정의하지 않는다.
7 |
8 |
9 | 생성자는 객체가 생성될 때 호출된다. 여기서 객체는 `new` 라는 키워드로 객체가 만들어질 때이다.
10 |
11 | 즉, 생성자는 다음과 같이 `new`라는 키워드가 사용될 때 호출된다.
12 | ```java
13 | new 클래스명(입력항목)
14 | ```
15 |
16 | 생성자는 메서드와 마찬가지로 입력을 받을 수 있다.
17 |
18 | 우리가 만든 생성자는 다음과 같이 입력값으로 문자열을 필요로 하는 생성자다.
19 | ```java
20 | public HouseDog(){
21 | this.setName(name);
22 | }
23 | ```
24 |
25 | 따라서 다음과 같이 `new` 키워드로 객체를 만들때 문자열을 전달해야만 한다.
26 | ```java
27 | HouseDog dog = new HouseDog("happy"); // 생성자 호출 시 String을 전달.
28 | ```
29 |
30 | 아래와 같이 코딩하면 컴파일 오류가 발생할 것
31 | ```java
32 | HouseDog dog = new HouseDog();
33 | ```
34 |
35 | 오류가 발생하는 이유는 객체 생성 방법이 생성자 규칙과 맞지 않기 때문에.
36 | 생성자가 선언된 경우 생성자의 규칙대로만 객체를 생성할 수 있다.
37 |
38 | ```java
39 | public class HouseDog extends Dog {
40 | public HouseDog(String name) {
41 | this.setName(name);
42 | }
43 |
44 | public void sleep() {
45 | System.out.println(this.name+" zzz in house");
46 | }
47 |
48 | public void sleep(int hour) {
49 | System.out.println(this.name+" zzz in house for " + hour + " hours");
50 | }
51 |
52 | public static void main(String[] args) {
53 | HouseDog dog = new HouseDog("happy");
54 | System.out.println(dog.name);
55 | }
56 | }
57 | ```
58 | 결과는 .. 다음과 같이 출력된다.
59 | ```
60 | happy
61 | ```
--------------------------------------------------------------------------------
/Lecture/JAVA/generics-harcore.md:
--------------------------------------------------------------------------------
1 | # 제네릭의 활용
2 | > 코딩테스트를 풀며 `Collections` 클래스의 `sort()` 메소드를 사용할 일이 생겼는데
3 | > 복잡한 제네릭을 쓴 것을 보고 이해하지 못해 제네릭에 대해 자세히 알아보려 이 글을 적는다.
4 |
5 |
6 | ## 제한된 Generics 클래스
7 | ```java
8 | FruitBox fruitBox = new FruitBox();
9 | fruitBox.add(new Toy()); // OK, 과일상자에 장난감을 담을 수 있다.. 그러나 뭔가 잘못된 것 같지 않은가?
10 | ```
11 |
12 | * 타입문자로 사용할 타입을 명시하면 한 종류의 타입만 지정할 수 있도록 제한할 수 있지만, 그래도 위의 코드처럼 여전히 모든 종류의 타입을 지정할 수 있다는 것에는 변함이 없다.
13 | * 그렇다면 타입 매개변수 `T`에 지정할 수 있는 타입의 종류를 제한할 수 있는 방법에 대해 알아보자.
14 |
15 | ```java
16 | // Fruit의 자손만 타입으로 지정 가능
17 | class FruitBox {
18 | ArrayList list = new ArrayList();
19 | }
20 | ```
21 | * 위와 같이 제네릭 타입에 `extends`를 사용하면 특정 타입의 자손들만 대입할 수 있게 제한할 수 있다.
22 |
23 | ```java
24 | FruitBox appleBox = new FruitBox(); // OK, Apple은 Fruit의 자손이기 때문에 가능
25 | FruitBox toyBox = new FruitBox(); // 에러, Toy는 Fruit의 자손이 아니기 때문 불가능
26 | ```
27 | * 여전히 한 종류의 타입만 담을 수 있지만, `Fruit` 클래스의 자손들만 담을 수 있다는 제한이 추가 됐을 뿐이다.
28 |
29 | ```java
30 | FruitBox appleBox = new FruitBox();
31 | fruitBox.add(new Apple()); // OK, Apple은 Fruit의 자손
32 | fruitBox.add(new Grape()); // OK, Grape은 Fruit의 자손
33 | ```
34 | * `add()` 매개변수 타입 `T`도 `Fruit`와 자손 타입이 될 수 있으므로, 위와 같이 여러과일을 담을 수 있는 상자가 될 수 있다.
35 |
36 | ```java
37 | class FruitBox {
38 | //...
39 | }
40 |
41 | interface Eatable {}
42 | ```
43 | * 만약 클래스가 아닌 인터페이스를 구현해야 할 때는 implement가 아닌 extends를 사용 한다.
44 |
45 | ```java
46 | class FruitBox {
47 | //...
48 | }
49 | ```
50 | * 타입 `T`를 `Fruit`의 자손이면서 `Eatable`을 구현해야한다면 `&`기호로 연결해준다.
--------------------------------------------------------------------------------
/Lecture/JAVA/how-working-DI.md:
--------------------------------------------------------------------------------
1 | ## spring의 DI 는 어떻게 작동하는걸까?
2 | > springboot 를 사용하면서 당연시하게 지나갔던 부분인것 같은데 한번 정리해보려고 한다.
3 |
4 | 우선 임의적인 `repository, service`.class 를 만들어 보겠다.
5 | 1. bookRepository.java
6 | ```java
7 | @Repository
8 | public class BookRepository {
9 | }
10 | ```
11 | 2. BookService.class
12 | ```java
13 | @Service
14 | public class BookService {
15 | @Autowired
16 | BookRepository bookRepository;
17 | }
18 | ```
19 |
20 | 이렇게 하면 service 에 bookRepository가 null인지 아닌지 테스트에서 성공이 뜬다.
21 | 너무 신기하지 않는가?? 어떻게 `@Autowired` 만 붙였다고 주입이 될 수 있는지.
22 |
23 |
24 |
25 | 궁금증을 안고.. [리플랙션 문서](../../Lecture/JAVA/reflection-1.md)에서 계속..
--------------------------------------------------------------------------------
/Lecture/JAVA/invent-bytecode.md:
--------------------------------------------------------------------------------
1 | ## 바이트코드를 조작해보자 - 실습
2 |
3 | 우선.. 내가 개인적으로 만든 Class 를 참고하여 구조를 파악해보자
4 |
5 | Foo.java
6 | ```java
7 | public class Foo {
8 | String name = "";
9 |
10 | public String answerName(){
11 | return name;
12 | }
13 | }
14 | ```
15 |
16 | main.java
17 | ```java
18 | public class ByteCodeInvent {
19 | public static void main(String[] args) {
20 | Foo foo = new Foo();
21 | System.out.println(foo.answerName());
22 | }
23 | }
24 | ```
25 |
26 | 이렇게 실행시키면 당연히 콘솔에는 아무것도 안뜨겠죠?
27 |
28 |
29 | 아... 나 maven 빌드 툴 안썻지 말입니다.. (아래 내용은 다른 강의 내용으로 대체)
30 |
31 | #### 본격적인 바이트코드 조작 실습
32 | * [ByteBuddy를 사용합니다](https://bytebuddy.net/#/)
33 |
34 | maven인 경우 `pom.xml`에 의존성을 추가해줍니다.
35 | * [여기로 들어간 후 버전은 알잘딱](https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy)
--------------------------------------------------------------------------------
/Lecture/JAVA/java-8-defualt-static-method.md:
--------------------------------------------------------------------------------
1 | # 자바 8 API의 기본 메서드와 스태틱 메서드
2 |
3 | ## 문자열 출력을 보다 더 다양하게 하는 방법들..
4 |
5 | ### ArrayList a.foreach()
6 |
7 |
8 | 자바 1.8v 부터 사용가능하게 됐고, foreach()는 특정 기능만을 수행하기 보다는 응용하여 다양하게 활용 가능하다.
9 |
10 | #### 사용해보기..
11 | ```java
12 | public class JavaEx {
13 | public static void main(String[] args) {
14 | ArrayList names = new ArrayList<>();
15 | names.add("jihwan");
16 | names.add("sunwoo");
17 | names.add("changgue");
18 |
19 | names.forEach(s -> System.out.println(s));
20 | }
21 | }
22 | ```
23 |
24 | names변수명의 ArrayList를 만들고 이름 하나하나(index) 출력할 때 람다식을 사용할 수 있다.
25 | 하지만.. 이 출력문을 더 간결하게 하는 방법이 있다. 바로!!! 메소드 레퍼런스를 사용하는 방법이다.
26 | IntelliJ에서는 메소드 레퍼런스를 사용하라고 추론해주기도 한다. 그래서.. 아래와 같이 더 간결하게 할 수 있다.
27 |
28 | ```java
29 | names.forEach(System.out::println);
30 | ```
31 |
32 | ### Spliterator
33 |
34 |
35 | ... 이외에 다양함.. [-> 참고](https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html)
--------------------------------------------------------------------------------
/Lecture/JAVA/java-collection.md:
--------------------------------------------------------------------------------
1 | ## 자바 컬렉션
2 | > java 에서 컬렉션이란 데이터의 집합, 그룹을 의미하며,
3 | > JCF(Java Collections Framework)은 이러한 데이터, 자료구조인 컬렉션과 이를 구현하는 클래스를 정의하는 인터페이스를 제공한다.
4 |
5 |
6 |
7 | Collection 인터페이스는 List, Set, Queue 로 크게 3가지 상위 인터페이스로 분류할 수 있다.
8 | 그리고 여기에 **Map의 경우 Collection 인터페이스를 상속받고 있지 않지만 Collection 으로 분류된다.**
9 |
10 | ### Collection 인터페이스의 특징
11 | 1. Set - HashSet, TreeSet: **순서를 유지하지 않는 데이터의 집합**, 데이터의 중복을 허용하지 않는다.
12 | 2. List - LinkedList, Vector, ArrayList: **순서가 있는 데이터의 집합**으로 데이터의 중복을 허용한다.
13 | 3. Queue - LinkedList, PriorityQueue: List와 유사.
14 | 4. Map - Hashtable, HashMap, TreeMap: key, value 쌍으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며, **키 중복을 허용하지는 않으나 값의 중복은 허용한다.**
15 |
16 | * Set 인터페이스
17 | * 순서를 유지하지 않는 데이터의 집합으로, 데이터의 중복을 허용하지 않는다.
18 | * HashSet
19 | * 가장빠른 임의 접근 속도
20 | * 순서를 예측할 수 없음
21 | * TreeSet
22 | * 정렬방법을 지정할 수 있음
23 |
24 | * List 인터페이스
25 | * 순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.
26 | * LinkedList
27 | * 양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 데이터의 위치정보만 수정하면 되기에 유용
28 | * 스택 큐 양방향 큐 등을 만들기 위한 용도로 쓰임
29 | * Vector
30 | * 과거에 대용량 처리를 위해 사용했으며, 내부에서 자동으로 동기화처리가 일어나 비교적 성능이 좋지 않고 무거워 잘 쓰이지 않음
31 | * ArrayList
32 | * 단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 조회 기능에 성능이 뛰어남
33 |
34 | * Map 인터페이스
35 | * 키, 값의 쌍으로 이루어진 데이터의 집합으로,
36 | 순서는 유지되지 않으며 키의 중복을 허용하지 않으나 값의 중복은 허용한다.
37 | * Hashtable
38 | * HashMap 보다는 느리지만 동기화를 지원
39 | * Null 불가능
40 | * HashMap
41 | * 중복과 순서가 허용되지 않으며 null 값이 올 수 있다.
42 | * TreeMap
43 | * 정렬된 순서대로 key와 value를 저장하여 검색이 빠르다.
44 |
45 |
--------------------------------------------------------------------------------
/Lecture/JAVA/java-completableFuture-callback.md:
--------------------------------------------------------------------------------
1 | # java completableFuture 그리고 callback
2 |
3 | ## 콜백이란?
4 | 콜백 메소드란 다른 함수에 인수로 전달되는 함수이자 `myMethod(bMethod())` 이벤트 후에 실행되는 것이다.
5 | 콜백 메서드의 용도는 다른 클래스에서 일부 작업이 완료된 경우 클래스에 완료되었다는 것을 알려줍니다.
6 |
7 | ## completableFuture
8 | 이전에 포스팅했던 Future를 사용했을때 처리하기 힘든 일들(콜백..)을 쉽게 해준다.
9 | 원하는 쓰레들풀을 이용해서 실행할 수도 있지만 기본은 `ForkJoinPool.commonPool()`이다. (쓰레드풀을 지정해주면 sutdown의 번거러움이 있다.)
10 |
11 | ### 비동기로 작업을 실행하는 방법
12 | * 리턴값이 있는 경우: `CompletableFuture.supplyAsync()`
13 | * 리턴값이 없는 경우: `CompletableFuture.runAsync()`
14 |
15 | 기본적으로 `ExecutorService` 와 달리 굳이 `shutdown();` 하지 않아도 `CompletableFuture`의 Task가 완료되면 프로세스도 종료된다.
16 |
17 | ```java
18 | public class CompletableFutureEx {
19 | public static void main(String[] args) throws ExecutionException, InterruptedException {
20 | CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
21 | System.out.println("======= completableFuture ========");
22 | return "it is good!";
23 | });
24 |
25 | System.out.println(completableFuture.get());
26 | }
27 | }
28 | ```
29 |
30 |
31 |
32 | ### 콜백도 제공한다.
33 | `CompletableFuture`라는 클래스의 `supplyAsync()` 메소드의 처리 결과를 `.thenApply()` 메소드로 넘겨 실행한다.
34 |
35 | ```java
36 | public class CompletableFutureEx {
37 | public static void main(String[] args) throws ExecutionException, InterruptedException {
38 | CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
39 | System.out.println("======= completableFuture ========");
40 | return "it is good!";
41 | }).thenApply(String::toUpperCase);
42 |
43 | System.out.println(completableFuture.get());
44 | }
45 | }
46 | ```
47 |
48 |
--------------------------------------------------------------------------------
/Lecture/JAVA/java-executors.md:
--------------------------------------------------------------------------------
1 | # java Executors
2 | 쓰레드를 만들고 관리하는 작업을 고수준의 API에게 위임하는게 Executors 이다.
3 | 쓰레드를 만들고 처리하고 실행하고 종료하는 것을 해주는 역할을 한다. [-> 자세한 내용은 여기에서](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html)
4 |
5 | ### ExecutorService 사용하기
6 | 우선 ExecutorService는 Executor를 상속받은 인터페이스로, Callable도 실행할 수 있으며 Executor를 종료시키거나 , Callable을 동시에 실행하는 등의 기능을 제공한다.
7 |
8 | ```java
9 | public class ExecutorEx {
10 | public static void main(String[] args) {
11 | ExecutorService executorService = Executors.newSingleThreadExecutor();
12 | executorService.submit(() -> {
13 | System.out.println("Thread " + Thread.currentThread().getName());
14 | });
15 | }
16 | }
17 | ```
18 | 이 코드를 실행해 보면
19 |
20 |
21 | 이처럼 `newSingleThreadExecutor()`은 무제한 큐에서 작동하는 단일 쓰레드를 사용하는 Excecutor를 만들어 줍니다. 그래서 프로세스가 실행되고 계속 유지되고 종료되지 않는 것을 확인 할 수 있다.
22 |
23 | 프로세스를 종료하고 싶다면 종료 메소드를 사용하여 프로세스를 닫아줘야 한다. `executorService.shutdown();`
24 |
25 | Fork/Join 프레임워크를 사용하여 멀티 프로세스도 활용할 수 있다.
--------------------------------------------------------------------------------
/Lecture/JAVA/java-method-reference.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/Lecture/JAVA/java-method-reference.md
--------------------------------------------------------------------------------
/Lecture/JAVA/lambda.md:
--------------------------------------------------------------------------------
1 | ## 람다 표현식
2 | **람다 표현식(lambda expression)이란?**
3 | ```java
4 | int min(int x, int y){
5 | return x < y ? x : y;
6 | }
7 | ```
8 |
9 | 이런식으로 람다 표현식으로 표현하면, 클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있습니다.
10 |
11 | 그런데 자바에서는 클래스의 선언과 동시에 객체를 생성하므로, 단 하나의 객체만을 생성할 수 있는 클래스를 익명 클래스라고 합니다.
12 |
13 | 따라서 자바에서 람다 표현식은 익명 클래스와 같다고 할 수 있습니다.
14 |
15 | ```java
16 | new Object(){
17 | int min(int x, int y){
18 | return x {함수몸체}
31 | ```
32 |
33 | 자바에서 람다 표현식을 작성할 때 유의해야 할 사항
34 |
35 | 1. 매개변수 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있습니다.
36 | 2. 매개변수가 하나인 경우에는 괄호를 생략할 수 있습니다.
37 | 3. 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호를 생략할 수 있습니다.
38 | 4. 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호를 생략할 수 있습니다.
39 | 5. return 문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 됩니다.
40 |
41 | ```java
42 | new Thread(new Runnable() {
43 | public void run() {
44 | System.out.println("전통적인 방식의 일회용 스레드 생성");
45 | }
46 | }).start();
47 |
48 |
49 |
50 | new Thread(()->{
51 | System.out.println("람다 표현식을 사용한 일회용 스레드 생성");
52 | }).start();
53 | ```
54 |
55 | 이렇게 람다 표현식을 사용하면 불필요한 코드를 줄일 수 있으며, 코드의 가독성이 훨씬 좋아집니다.
--------------------------------------------------------------------------------
/Lecture/JAVA/prac_interview_java.md:
--------------------------------------------------------------------------------
1 | ## 기술 면접 예상 질문 대비하기 - Java편
2 |
--------------------------------------------------------------------------------
/Lecture/JAVA/reflection-1.md:
--------------------------------------------------------------------------------
1 | ## java reflection
2 | > Reflection을 사용하는 기술을 나열하자면, 우리가 잘 아는 스프링 프레임워크, 대표적 ORM 기술인 하이버네이트, jackson라이브러리 등에 사용됩니다.
3 |
4 | #### 클래스 정보를 조회하는 다양한 방법
5 | ```java
6 | // 이렇게 바로 접근도 가능합니다.
7 | Class bookRepositoryClass = BookRepository.class;
8 |
9 | // app 에 이미 인스턴스가 잡혀 있을 때.
10 | BookRepository bookRepository = new BookRepository();
11 | Class extends BookRepository> aClass = bookRepository.getClass();
12 |
13 | // 이렇게 forName 을 통해서 경로로 class 를 접근할 수도 있다.
14 | Class> aClass1 = Class.forName("com.example.thejava.repository.BookRepository");
15 | ```
16 |
17 | #### 클래스의 필드를 가져오는 방법
18 | 1. public 에 한에서 가져오기
19 | ```java
20 | /**
21 | * 해당 클래스의 필드를 전부 가져오는 방법
22 | */
23 | Class bookRepositoryClass1 = BookRepository.class;
24 |
25 | // 해당 클래스의 필드를 가져오기(Public)
26 | Arrays.stream(bookRepositoryClass1.getFields()).forEach(System.out::println);
27 | ```
28 |
29 | 2. private 까지 전부 가져오기
30 | ```java
31 | Arrays.stream(bookRepositoryClass1.getDeclaredFields()).forEach(System.out::println);
32 | ```
33 |
34 |
35 |
36 | **아래는 앞으로 잘 사용하게 될 여러가지의 option들이다 잘 참고하시길 (귀찮아서 절대 아님)**
37 |
--------------------------------------------------------------------------------
/Lecture/JAVA/shallowcopy-deepcopy.md:
--------------------------------------------------------------------------------
1 | # 자바 배열의 깊은 복사와 얕은 복사
2 | > 배열에서 어떠한 값이 복사되는데 크게 2가지 복사 방법이 있습니다.
3 |
4 | ## 얕은복사 (shallow copy)
5 | 간단히 정리하면 한쪽에서 수정이 발생하면 다른쪽에도 영향을 끼쳐 같아지게 됩니다.
6 | 복사한 배열에서 어떠한 값을 수정하면 원래 배열에도 변경된 값이 들어갑니다.
7 |
8 | ```java
9 | public class Main {
10 | public static void main(String[] args) {
11 | // Given
12 | int[] targetArr = {1,2,3,4,5};
13 | int[] sortArr = targetArr;
14 | // When
15 | Arrays.sort(sortArr);
16 | // Then
17 | System.out.println("targetArr: "+Arrays.toString(targetArr));
18 | System.out.println("sortArr: "+Arrays.toString(sortArr));
19 | }
20 | }
21 | ```
22 |
23 |
24 |
25 | 위와 같이 b 배열에 a를 복사하고 b에 변경(sort)를 주었지만 a까지 값이 변경되는것을 볼 수 있다.
26 |
27 | ## 1차원 배열에서의 깊은 복사
28 | 깊은 복사는 배열을 복사 한 후에 한쪽 값을 수정해도 다른 배열에 영향을 끼치지 않습니다.
29 | 만약 원래 배열의 값을 수정했다해도 복사한 배열의 값은 복사했을때 그대로의 값이 저장되어 있습니다.
30 |
31 | ```java
32 | public class Main {
33 | public static void main(String[] args) {
34 | // Given
35 | int[] targetArr = {1,2,3,4,5};
36 | int[] sortArr = targetArr.clone();
37 | // When
38 | Arrays.sort(sortArr);
39 | // Then
40 | System.out.println("targetArr: "+Arrays.toString(targetArr));
41 | System.out.println("sortArr: "+Arrays.toString(sortArr));
42 | System.out.println(targetArr == sortArr);
43 | }
44 | }
45 | ```
46 |
47 |
48 |
49 | 위와 같이 b배열에 sort라는 함수를 통해 값을 변경해도 타겟 a에게는 영향이 없는 것을 볼 수 있다.
50 |
51 | ## 정리
52 | 1차원 배열의 깊은 복사는 `배열.clone()`을 사용해서 정말 간단하게 할 수 있다.
53 | (array of int .. etc ) 일반 배열의 구조에 한 함.
54 |
55 | 하지만, 객체 배열의 경우 `.clone()`을 사용하면 깊은 복사가 되지 않는다.
56 | 이유는 객체(Object)는 주소값을 가지고 있기 때문인데.. 마찬가지로 2차원 배열의 경우도 각각 row에 대한 주소값을 가지고 있기 때문에 deepCopy(깊은 복사)가 되지 않는다.
--------------------------------------------------------------------------------
/Lecture/OOP/OCP.md:
--------------------------------------------------------------------------------
1 | # OCP 개방 폐쇄의 원칙
2 |
3 | ### Index
4 | 1. OCP 적용이 필요한 사례 보기
5 | 2. OCP 란?
6 | 3. 전략패턴 (Strategy Pattern)
7 |
8 | ## OCP란?
9 | > 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들고자 로버트 마틴이 명명한 객체지향설계 5대원칙 SOLID 중 하나.
10 |
11 | OCP는 소프트웨어 구성 요소(컴퍼넌트, 클래스, 모듈, 함수)는 **확장에 대해서는 개방**, **변경에 있어서는 폐쇄 되어야 한다** 라는 의미.
12 |
13 | 즉, 기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되어야 한다는 의미.
14 |
15 |
16 |
17 | 기존 코드에서 확장을 위해 코드가 수정되었다.
18 | 이런경우에 Close 를 위반하게 된다. OCP의 핵심은 `Close` 입니다.
19 | 변경, 확장을 위해서 기존 코드가 수정되면 변경, 확장 Open 도 힘들어집니다.
20 |
21 | ## OCP 적용방법
22 | 1. 상속 (is-a)
23 | 2. 컴포지션 (has-a)
24 |
25 | 주로 컴포지션을 사용함.
26 | 상속은 상위클래스가 바뀌면 하위클래스에 끼치는 영향이 매우 크다는 단점이 존재하기 때문에.
27 |
28 | 1. 변경(확장)될 것과 변하지 않을 것을 엄격히 구분
29 | 2. 이 두 모듈이 만나는 지점에서 인터페이스를 정의
30 | 3. 구현에 의존하기보다 **정의한 인터페이스에** 의존하도록 코드를 작성
31 |
32 | ### 1. 변경될 부분과 변하지 않을 부분을 엄격히 구분하라
33 |
34 |
35 |
36 | `B` 부분에서 변경이 생기니 이 부분을 `interface`로 추출 해야한다.
37 |
38 | ### 2. 모듈이 만나는 지점에 인터페이스 정의
39 |
40 |
41 |
42 | `B` 를 `shuffle()` 메서드를 가진 `ShuffleStrategy` 라는 인터페이스로 분리했다.
43 | 여기서 주의할 점은 인터페이스로 만들어야 한다는 것. 변하는 것과 변하지 않는 모듈의 교차점으로 서로를 보호하는 역할을 한다.
44 |
45 | 인터페이스가 아닌 구현 클래스에 의존하면 기능 변경을 위해 코드를 수정해야 한다.
46 |
47 |
48 |
49 | ### 3. 인터페이스에 의존하도록 코드를 작성
50 |
51 |
52 |
53 | `..Generator.class`가 `ShuffleStrategy` 인터페이스에 의존하도록 해주고 생성자를 통해 구현 클래스의 인스턴스를 외부에서 주입해주는 방식으로 이용한다.
54 |
55 | ## 기능을 바꿔도 내부 코드의 변경이 일어나지 않는다.
56 |
57 |
58 |
59 | 다른 기능을 사용하고 싶을 때, `..Generator.class` 생성자에 원하는 기능을 넣어주면 된다.
60 | 이렇게 해줌으로써 기능이 추가, 수정되어도 기존의 코드에는 영향이 가지 않는다.
61 |
62 | ### 정리
63 | 1. OPEN: 확장에 열려있다.
64 | 2. CLOSE: 변경에 닫혀있다.
65 |
66 | 기존의 코드를 변경하지 않으면서 기능을 추가할 수 있다.
--------------------------------------------------------------------------------
/Lecture/algorithm/DFS.md:
--------------------------------------------------------------------------------
1 | # DFS, 깊이 우선 탐색
2 | > 하나의 정접으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문하는 것
3 |
4 | ## Tree
5 |
6 |
7 | - rootNode 는 level 이 1 이다.
8 |
9 | ### 깊이 우선 탐색이란
10 | > 루트 노드에서 시작하여 다음 분기로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법
11 |
12 | - 미로를 탐색할 때 한 방향으로 갈 수 있을 때까지 계속 가다가 더 이상 갈 수 없게 되면 가장 가까운 갈림길로 돌아와서 이곳으로부터 다른 방향으로 다시 탐색을 진행하는 방법과 유사하다.
13 | - 즉 넓게(Wide) 탐색하기 전에 깊게(Deep) 탐색하는 것이다.
14 | - 속도: DFS > BFS (단, 단순 검색에서는 BFS가 빠르다.)
15 |
16 | ### 깊이 우선 탐색(DFS) 특징
17 | * 자기 자신을 호출하는 순환 알고리즘의 형태를 가지고 있다. (재귀함수)
18 | * 전위 순회를 포함한 다른 형태의 트리 순회는 모두 DFS의 한 종류이다.
19 | * 이 알고리즘을 구현할 때 가장 큰 차이점은, 그래프 탐색의 경우 어떤 노드를 방문했었는지 여부를 반드시 검사해야한다. (노드의 주소를 저장하면 될 듯)
20 | * 검사하지 않으면 무한루프에 빠질 수 있다.
21 |
22 | ## DFS 구현하기
23 |
24 | 우선 Node라는 객체를 만든다.
25 | ```java
26 | class Node{
27 | int data;
28 | // lt, rt 노드의 주소를 담아야 하기 때문에 참조형 변수를 선언한다.
29 | Node lt, rt;
30 | /**
31 | 새로운 노드를 생성할 때 마다 그 노드의 값과
32 | lt, rt를 null로 초기화 한다.
33 | */
34 | public Node(int data){
35 | this.data = data;
36 | lt = rt = null;
37 | }
38 | }
39 | ```
40 | > 참조형 변수에 대해서 모른는 사람은 [여기](../JAVA/Reference-veriable.md)를 참고하기 바란다.
--------------------------------------------------------------------------------
/Lecture/algorithm/bubbleSort.md:
--------------------------------------------------------------------------------
1 | # 버블정렬
2 |
3 | ## 버블정렬 알고리즘의 개념
4 | 1. 서로 인접한 두 원소를 검사하여 정렬한다.
5 | 1. 인접한 2개의 레코드르르 비교하여 크기가 순서대로(오름차순, 내림차순)대로 되어 있지 않으면 서로 교환한다.
6 | 2. 선택 정렬과 기본 개념이 유사하다.
7 |
8 | ## 버블정렬 알고리즘의 구체적 개념
9 | * 1-2 2-3 3-4 이런식으로 (마지막-1)번째 자료와 마지막 자료를 비교하여 교환한다.
10 | * 1회전을 마치고 나면 가장 큰 자료가 맨 뒤로 이동하므로 2회전에서는 맨 끝에 있는 자료는 정렬에서 제외되고, 2회전을 하고 나면 끝에서 두번째 자료까지는 제외된다. 결론적으로 1회전을 추가 수행할 때마다 정렬에서 제외되는 데이터가 하나씩 늘어난다.
11 |
12 | ## 버블정렬 알고리즘의 예
13 |
14 |
15 | ## 버블정렬 코드 및 설명
16 | ```java
17 | public String solution(int n, int[] arr){
18 | for (int i=n-1; i>0; i--){
19 | /**
20 | * 버블정렬 그 턴 마지막 index는 다음 턴 정렬 대상에 포함하지 않아야 한다.
21 | * - 이유는 그 턴의 가장 큰 숫자가 맨 마지막 index에 자리잡기 때문이다.
22 | * 그래서 순차적으로 j가 j arr[j+1]){
27 | int tmp = arr[j];
28 | arr[j] = arr[j+1];
29 | arr[j+1] = tmp;
30 | }
31 | }
32 | }
33 | }
34 | ```
35 |
36 | ## 버블정렬의 알고리즘 특징
37 | * 장점
38 | * 구현이 매우 간단하다
39 | * 단점
40 | * 순서에 맞지 않은 요소를 인접한 요소와 교환한다
41 | * 하나의 요소가 가장 왼쪽에서 가장 오른쪽으로 이동하기 위해서는 배열의 모든 다른 요소들과 교환되어야 한다.
42 | * 일반적으로 자료의 교환이 이동보다 더 복잡하기 때문에 버블정렬은 단순함에도 거의 쓰이지 않는다.
--------------------------------------------------------------------------------
/Lecture/algorithm/insertionSort.md:
--------------------------------------------------------------------------------
1 | # 삽입정렬
2 |
3 | ## 삽입정렬의 알고리즘 개념
4 | * 손안의 카드를 정렬하는 방법
5 | * 새로운 카드를 기존의 정렬된 카드 사이의 올바른 자리를 찾아 삽입한다.
6 | * 새로 삽입될 카드의 수만큼 반복하게 되면 전체 카드가 정렬된다.
7 | * 자료 배열의 모든 요소를 앞에서부터 차례대로 이미 정렬된 배열 부분과 비교하여, 자신의 위치를 찾아 정렬을 완성하는 알고리즘
8 | * 매 순서마다 해당 원소를 삽입할 수 있는 위치를 찾아 해당 위치에 넣는다.
9 |
10 |
11 | ## 삽입정렬의 구체적인 개념
12 | * 삽입 정렬은 두 번째 자료부터 시작하여 그 앞의 자료들과 비교하여 삽입할 위치를 지정한 뒤 자료를 뒤로 옮기고 지정한 자리에 자료를 삽입하여 정렬하는 알고리즘이다.
13 | * 즉, 두 번째 자료는 첫 번째 자료, 세 번째 자료는 두 번째와 첫 번째 자료...
14 | * 처음 Key 값은 두 번째 자료부터 시작한다 (i=1 ~ )
15 |
16 |
17 |
18 | ## 삽입 정렬 코드와 예
19 | ```java
20 | public int[] solution(int n, int[] arr){
21 | int j;
22 | // 2번째 수 부터 시작한다 index 기준 1
23 | for (int i=1; i=0 && arr[j] > key; j--){
27 | arr[j+1] = arr[j];
28 | }
29 | arr[j+1] = key;
30 | }
31 | return arr;
32 | }
33 | ```
34 |
35 | ## 삽입 정렬 알고리즘의 특징
36 | * 장점
37 | * 안정한 정렬
38 | * 레코드 수가 적을 경우 알고리즘 자체가 매우 간단하므로 다른 복잡한 정렬보다 유리하다.
39 | * 대부분의 레코드가 이미 정렬되어 있는 경우에 매우 효율적일 수 있다.
40 | * 단점
41 | * 비교적 많은 레코드들의 이동을 포함한다.
42 | * 레코드 수가 많고 레코드 크기가 클 경우에 적합하지 않다.
--------------------------------------------------------------------------------
/Lecture/algorithm/selectionSort.md:
--------------------------------------------------------------------------------
1 | # 선택정렬
2 |
3 | ## 선택정렬의 알고리즘 개념
4 | 1. 제자리 정렬 알고리즘의 하나이다.
5 | 1. 입력배열 이외에 다른 추가 메모리를 요구하지 않는다.
6 | 2. 해당 순서에 원소를 넣을 위치는 이미 정해져 있고, 어떤 원소를 넣을지 선택하는 알고리즘이다.
7 | 1. 첫번재 순서에는 첫번째 위치에 가장 최솟값을 넣는다.
8 | 2. 두번째 순서에는 두번재 위치에 남은 값 중에서의 최솟값을 넣는다.
9 |
10 | 3. 과정
11 | 1. 주어진 배열 중에서 최솟값을 찾는다.
12 | 2. 그 값을 맨 앞에 위치한 값과 교체한다.
13 | 3. 맨 처음 위치를 뺀 나머지 리스트를 같은 방법으로 교체한다.
14 | 4. 하나의 원소만 남을 때까지 반복한다.
15 |
16 | ## 선택정렬 회전 및 정렬 결과
17 |
18 |
19 | ## 코드 구현 & 설명
20 | ```java
21 | public int[] solution(int[] arr){
22 | // 0~last 인덱스까지 반복한다.
23 | for (int i=0; i arr[j]){
28 | int tmp = arr[i];
29 | arr[i] = arr[j];
30 | arr[j] = tmp;
31 | }
32 | }
33 | }
34 | return arr;
35 | }
36 | ```
37 |
38 | ## 선택정렬의 특징
39 | * 장점
40 | * 자료 이동 횟수가 미리 결정된다. arr[n]의 n만큼
41 | * 단점
42 | * 안정성을 만족하지 않는다.
43 | * 즉, 값이 같은 레코드가 있는 경우에 상대적인 위치가 변경될 수 있다.
44 |
45 |
--------------------------------------------------------------------------------
/Lecture/recode/variousNotation.md:
--------------------------------------------------------------------------------
1 | ## 다양한 프로그래밍 표기법
2 |
3 | |표기법 이름|예시|설명|사용하는 곳|
4 | |----------|------|-----|---------|
5 | |카멜 표기법|camelCase|첫번째 글자는 무조건 소문자로 하되, 두 단어 이상이 연결 될 때에는 연결되는 단어의 첫번째 글자는 대문자로 표기한다.|지역변수 등
6 | |파스칼 표기법|PascalCase|모든 단어의 첫번째 글자를 대문자 그 이외는 소문자로 표기한다.|전역변수, 함수, 클래스 등
7 | |스네이크 표기법|snake_case|모든 단어를 소문자로 표기하되 두 단어 이상이 연결될 때에는 연결되는 부분을 언더바 '_'를 사용하여 연결한다.|지역변수 등
--------------------------------------------------------------------------------
/Lecture/한번에 끝내는/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/Lecture/한번에 끝내는/README.md
--------------------------------------------------------------------------------
/Network/Proxy.md:
--------------------------------------------------------------------------------
1 | # Proxy
2 | ## 프록시란?
3 | > Proxy란 '대리' 라는 의미로, 네트워크 기술에서는 프로토콜에 있어서 대리 응답 등에서 친숙한 개념입니다.
4 | >
5 | > 보안 분야에서는 주로 보안상의 이유로 직접 통신할 수 없는 두 점 사이에서 통신을 할 경우 그 상이에 있어서 중계기로서 대리로 통신을 수행하는 기능을 가르켜 "프록시" 그 중계 기능을 하는 것을 프록시 서버라고 부릅니다.
6 |
7 |
8 |
9 | ## 프록시 서버의 특징
10 | 프록시 서버는 클라이언트 입장과 서버의 입장에서 볼 때 서로 상반되는 역할을 하는 것처럼 인식됩니다.
11 | 다시 말해서, **클라이언트 호스트에서의 입장에서 본다면 프록시 서버는 마치 원격 서버처럼 동작**하는 것이고, **원격 서버에서의 입장에서 본다면 마치 클라이언트처럼 동작**한다는 것입니다.
12 |
13 | ## 프록시 서버의 종류
14 | > 서버의 위치에 따라 분류하면 크게 두 가지로 나눌 수 있습니다.
15 |
16 | ### Forward 프록시
17 | Forward 프록시는 클라이언트 호스트들과 접근하고자 하는 원격 리소스의 사이에 위치시키는 것입니다.
18 |
19 | 이 프록시 서버는 원격 서버로부터 요청된 리소스를 가져와서 요청한 사용자에게 돌려주는 역할을 수행하며, 만일 캐시에 데이터가 남아 있다면 다음 요청시 캐시된 데이터로부터 제공해 주게 된다.
20 |
21 | 이 서버는 전형적으로 로컬 디스크에 데이터를 저장하며, 클라이언트 호스트들은 사용중인 웹 브라우저를 이용하여 프록시 서버 사용을 해야 하므로 프록시 서버를 사용하고 있다는 것을 인식할 수 있습니다.
22 |
23 | 또한 대역폭 사용을 감소시킬 수 있다는 것과 접근 정책 구현에 있어 다루기 쉬우면서도 비용이 저렴하다는 장점을 갖는다.
24 | **또한 사용자의 정해진 사이트만 연결할 수 있는 등 웹 사용환경을 제한할 수 있으므로 기업 환경등에서 많이 사용합니다.**
25 |
26 |
27 |
28 |
29 | ### Reverse 프록시
30 | 이것은 프록시 서버를 인터넷 리소스 또는 인트라넷 리소스 앞에 위치시키는 방식입니다.
31 | 이 방식을 사용하면 클라이언트들이 프록시 서버에 연결됐다는것을 알지 못하며, 마치 최종 사용자가 요청 리소스에 직접 접근하는 것과 같이 느끼게 됩니다.
32 | 내부 서버가 직접 서비스를 제공해도 되지만, 이렇게 구성하는 이유는 보안 때문입니다.
33 |
34 |
--------------------------------------------------------------------------------
/Network/cache.md:
--------------------------------------------------------------------------------
1 | ## Cache 란?
2 | > 자주 사용하는 데이터나 값을 미리 복사해 놓은 임시 장소를 가르킨다.
3 | > 아래와 같은 저장공간 계층 구조에서 확인할 수 있듯이, 캐시는 저장 공간이 작고 비용이 비싼 대신 빠른 성능을 제공한다.
4 |
5 |
6 |
7 | ### ((Cache는 아래와 같은 경우에 사용을 고려하면 좋다))
8 | * 접근시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우(서버의 균일한 API 데이터)
9 | * 반복적으로 동일한 결과를 돌려주는 경우(이미지나 썸네일)
10 |
11 | ### ((Cache에 데이터를 미리 복사해 놓으면 계산이나 접근시간 없이 더 빠른 속도로 데이터에 접근할 수 있다.))
12 |
13 | 결국 Cache란 반복적으로 데이터를 불러오는 경우에, 지속적으로 DBMS 혹은 서버에서 요청하는 것이 아니라, Memory에 데이터를 저장시켰다가 불러다 쓰는 것을 의미한다.
14 |
15 | Enterprise 급 App 에서는 DBMS의 부하를 줄이고, 성능을 높이기 위해 캐시를 사용한다.
16 |
17 | 원하는 데이터가 테시에 존재할 경우 해당 데이터를 반환하며, 이러한 상황을 **Cache Hit** 라고 한다.
18 | 캐시는 저장공간이 작기 때문에, 지속적으로 **Cache Miss**가 발생하는 데이터의 경우 캐시 전략에 따라서 저장중인 데이터를 변경해야한다.
19 |
20 | ### Cache의 필요성
21 |
22 |
23 | > 위의 그래프는 Long Tail 법칙의 그래프인데. Long Tail 법칙은 20% 의 요구가 스스템 리소스의 대부분을 사용한다는 법칙이다. **그렇기 때문에 20%의 기능에 Cache를 이용함으로써 리소스 사용량은 대폭 줄이고, 성능은 대폭 향상 시킬 수 있다.**
--------------------------------------------------------------------------------
/Network/spring-security.md:
--------------------------------------------------------------------------------
1 | # spring application으로 백엔드를 운영할 때 고려해야 할 보안사항
2 |
3 | ## index
4 | 1. CSRF
5 |
6 |
7 | ## CSRF (Cross Site Request Forgery)
8 |
9 |
10 | 우선 CSRF 를 직역하면 "사이트 간 요청 위조" 라는 뜻을 갖는다.
11 | OWASP top10 에도 오른적이 있을 만큼 대단히 위험도가 높은 것으로 평가되었던 공격이다.
12 |
13 | 1. 공격자는 희생자의 개인정보나 권한을 얻기 위해 보안이 취약한 웹사이트에 HTTP로 작성된 요청문을 게시판에 등록한다.
14 | 2. 공격자의 게시물이 DB에 저장되고, 게시글로 등록된다.
15 | 3. 희생자는 공격자가 올려놓은 게시글을 읽게 되고 링크 또는 이미지에 삽입한 링크를 클릭하면서 **공격자가 작성한 HTTP를 자신의 권한으로 실행, 요청한다.**
16 | 4. 희생자 권한으로 HTTP 요청을 받은 웹서버는 요청을 처리하고 응답을 보낸다. **공격자의 의도대로 실행이 되었고** 희생자는 의도하지 않은 피해를 입게 된다.
17 |
18 | ### CSRF에 취약하다고 판단을 할 수 있는 기준
19 |
20 |
21 | 웹 애플리케이션 사용자가 입력할 수 있는 형식(게시판, Q&A 등등)에서 img src 이용하여 공격할 수 있는 조작문을 작성하고 모의 공격을 해본다.
22 |
23 | ### CSRF 보안 대책
24 | 1. 중요한 요청에 대한 재인증 요청
25 | 2. 사용자의 접근 권한 정보가 포함된 토큰을 생성하고 사용자가 웹 서버에 요청을 보낼 때 토큰 값으로 검증.
--------------------------------------------------------------------------------
/README_legacy.md:
--------------------------------------------------------------------------------
1 | It was current migrated !!
2 | please signin target account and try ssh clone. !
3 | Is author change??
--------------------------------------------------------------------------------
/Spring/Concept/Auditing.md:
--------------------------------------------------------------------------------
1 | # JPA Auditing으로 생성일/수정일 자동화하기
2 | ## 🙉 동기
3 | > ### project에서 해당 data의 생성시간과 수정시간을 관리해야 할 부분이 있었다.
4 | > ### 주문 도메인에서 주문한 시간과 주문 내용을 수정한 시간이 필요했다.
5 | > ### 그리고 결제 도메인에는 결제 요청한 시간과 결제 내용을 수정하는 시간이 필요했다.
6 |
7 | ## JPA Auditing으로 생성시간/수정시간 자동화하기
8 | 보통 엔티티는 해당 데이터의 생성시간과 수정시간을 포함한다.
9 | 이렇다 보니 매번 DB에 insert하기 전, update하기 전에 날짜 데이터를 등록/수정하는 코드가 여기저기 들어간다.
10 | ```java
11 | public void savePosts() {
12 | ...
13 | posts.setCreateDate(new LocalDate());
14 | postsRepository.save(posts);
15 | ...
16 | }
17 | ```
18 | 이런식으로 단순하고 반복적인 코드가 모든 테이블과 서비스 메서드에 포함되어야 한다고 생각하면 어마어마 하게 귀찮고 코드가 지저분해진다. 이 문제를 해결할 수 있는 것이 JPA Auditing.
19 |
20 | ## 적용하기
21 | ```java
22 | @MappedSuperclass
23 | @EntityListeners(AuditingEntityListener.class)
24 | public abstract class BaseTimeEntity {
25 |
26 | @CreatedDate
27 | private LocalDateTime createdDate;
28 |
29 | @LastModifiedDate
30 | private LocalDateTime modifiedDate;
31 |
32 | public LocalDateTime getCreatedDate() {
33 | return createdDate;
34 | }
35 |
36 | public LocalDateTime getModifiedDate() {
37 | return modifiedDate;
38 | }
39 | }
40 | ```
41 | * ```@MappedSuperclass```: JPA Entity 클래스들이 BaseTimeEntity를 상속할 경우 필드들도 칼럼으로 인식하도록 해줌.
42 | * ```@EntityListeners(AuditingEntityListener.class)```: BaseTimeEntity 클래스에 Auditing 기능을 포함시킨다.
43 | * ```@CreatedDate```: Entity가 생성되어 저장될 때 시간이 자동 저장됩니다.
44 | * ```@LastModifiedDate```: 조회한 Entity의 값을 변경할 때 시간이 자동으로 저장.
45 |
46 | **JPA Auditing 어노테이션을 모두 활성화, Application 클래스에 활성화 어노테이션 추가**
47 | ```java
48 | @EnableJpaAuditing
49 | @SpringBootApplication
50 | public class Application {
51 |
52 | public static void main(String[] args) {
53 | SpringApplication.run(CaffeineApplication.class, args);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/Spring/Concept/ErrorVsException.md:
--------------------------------------------------------------------------------
1 | # Error vs Exception
2 | ## 👩🏻🏫 오류와 예외의 개념
3 | ### Error vs Exception
4 | 오류: 시스템에 비정상적인 상황이 생겼을 때 발생. 심각한 수준의 오류. 예측 처리 불가.
5 | 예외: 개발자가 구현한 로직에서 발생. 예측 처리 가능. 예회를 구분하고 명확한 처리 방법을 적용.
6 |
7 | ### Exception class
8 |
9 |
10 | Exception은 수 많은 자식클래스를 갖고 있다.
11 | **```RuntimeException```이 중요하다, ```CheckedException``` 과 ```UncheckedException```을 구분하는 기준이 되기 때문에.**
12 |
13 | ### CheckedException과 Unchecked(Runtime)Exception
14 |
15 |
16 | CheckedException 과 UncheckedException의 가장 명확한 기준은 "꼭 처리를 해야 하느냐" 이다.
17 | Checked Exception이 발생할 가능성이 있는 method는 ```try/catch```로 감싸거나 ```throw```로 던져야 한다.
18 | 반면에 UncheckedException은 명시적인 예외처리를 하지 않아도 된다. 개발자의 부주의에서 발생하는 경우가 대부분이고 미리 예측하지 못했던 상황에서 발생하는 예외가 아니기에.
--------------------------------------------------------------------------------
/Spring/Concept/SOLID.md:
--------------------------------------------------------------------------------
1 | ## SOLID 원칙
2 | > 객체지향 5대원칙 또는 SOLID 원칙이란 단어를 들어본 적이 있을 것이다.
3 | > SOLID 원칙 하나하나 예를 들며 설명해보겠다.
4 |
5 | 객체지향 5대 원칙
6 | 1. SRP(단일 책임 원칙)
7 | 2. OCP(개방-폐쇄 원칙)
8 | 3. LSP(리스코프 치환 원칙)
9 | 4. DIP(의존 역전 원칙)
10 | 5. ISP(인터페이스 분리 원칙)
11 |
12 | ### SRP 단일 책임 원칙
13 | - 소프트웨어의 설계 부품은 단 하나의 책임만을 가져야 한다.
14 |
15 | 여기서 책임이란 '기능' 정도의 의미이다.
16 |
17 | 설계를 잘한 프로그램은 기본적으로 새로운 요구사항과 프로그램 변경에 영향을 받는 부분이 적다.
18 | 책임이 많아지면 클래스 내부의 함수끼리 강한 결합을 발생할 가능성이 높아진다.
19 | 이는 유지보수에 비용이 증가하게 되므로 따라서 책임을 분리시킬 필요가 있다.
20 |
21 | ### OOP 개방 폐쇄 원칙
22 | - 기존의 코드를 변경하지 않고 기능을 추가하거나 수정할 수 있도록 설계해야 한다.
23 |
24 | OCP 에 만족하는 설계를 할 때는 변경되는것이 무엇인지 초점을 맞춘다.
25 | 자주 변경되는 내용은 수정하기 쉽게 설계하고, 변경되지 않아야 하는 것은 수정되는 내용에 영향을 받지 않게 하는 것이 포인트다.
26 | 이를 위해 자주 사용하는 문법이 인터페이스이다.
--------------------------------------------------------------------------------
/Spring/Concept/SpringAnnotation.md:
--------------------------------------------------------------------------------
1 | # 📄 [Spring] Spring Annotation
2 | ## **Spring Annotation의 종류와 그 역할**
3 | ### 1. ```@Component```
4 | * Component-scan을 선언에 의해 특정 패키지 안의 클래스들을 스캔하고, ```@Component```Annotation이 있는 클래스에 대하여 bean 인스턴스를 생성.
5 |
6 | ### 2. ```@Controller, @Service, @Repository```
7 | * ```@Component``` 구체화 -> ```@Controller, @Service, @Repository```
8 | * bean으로 등록
9 | * 해당 클래스가 Controller/Service/Repository로 사용됨을 Spring Framework에 알린다.
10 |
11 | ### 3. ```@RequestMapping```
12 | ```
13 | @Controller
14 | @RequestMapping("/home") // 1) Class Level
15 | public class HomeController {
16 | /* an HTTP GET for /home */
17 | @RequestMapping(method = RequestMethod.GET) // 2) Handler Level
18 | public String getAllEmployees(Model model) {
19 | ...
20 | }
21 | /* an HTTP POST for /home/employees */
22 | @RequestMapping(value = "/employees", method = RequestMethod.POST)
23 | public String addEmployee(Employee employee) {
24 | ...
25 | }
26 | }
27 | ```
28 | * ```@RequestMapping```에 대한 모든 매핑 정보는 Spring에서 제공하는 HandlerMapping Class 가 가지고 있다.
29 | 1. Class Level Mapping
30 | * 모든 메서드에 적용되는 경우
31 | * "/home"으로 들어오는 모든 요청에 대한 처리를 해당 클래스에서 한다는 것을 의미한다.
32 |
33 | 2. Handler Level Mapping
34 | * 요청 url에 대해 해당 메서드에서 처리해야 되는 경우
35 | * "/home/employees"POST 요청에 대한 처리를 addEmployee()에서 한다는 것을 의미한다.
36 | * value: 해당 url로 요청이 들어오면 이 메서드가 수행된다.
37 | * method: 요청 method를 명시한다. 없으면 모든 http method 형식에 대해 수행된다.
38 |
--------------------------------------------------------------------------------
/Spring/Concept/SpringBean.md:
--------------------------------------------------------------------------------
1 | # 📄 [Spring] 스프링 빈(Bean)의 개념과 생성 원리
2 |
--------------------------------------------------------------------------------
/Spring/Concept/TDD.md:
--------------------------------------------------------------------------------
1 | # TDD (Test-driven Development)
2 |
3 | ### TDD의 필요성과 동기
4 | * 객체지향적인 코드 개발
5 | * 모든 코드가 재사용 성 기반으로 작성되어야 한다.
6 | * 설계 수정 시간의 단축
7 | * 최초 설계 안을 만족시키며 입출력 구조와 기능의 정의를 명확히 하게 되므로 설계의 구조들을 많이 수정하게 된다.
8 | * 경함은 일찍 찾을 수록 고치는 비용이 적게 든다.
9 | * 디버깅 시간의 단축시킨다.
10 | * 유지 보수의 용이성
11 | * 테스트 문서의 대체 가능
12 |
13 |
14 | ### 들어가기
15 |
16 |
17 | build.gradle
18 | ```gradle
19 | dependencies {
20 | compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' // log를 위해 slf4j 추가
21 | compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' // log를 위해 logback 추가
22 | }
23 | ```
24 |
25 | TestCaseTest.java
26 | ```java
27 | public class TestCaseTest {
28 |
29 | public static void main(String[] args) {
30 | new TestCaseTest().runTest();
31 | }
32 |
33 | public void runTest () {
34 | long sum = 10+10;
35 | Assert.assertTrue(sum == 20);
36 | }
37 | }
38 | ```
39 |
40 | Assert.java
41 | ```java
42 | public class Assert {
43 | private static final Logger logger = LoggerFactory.getLogger(Assert.class);
44 |
45 | private Assert() {} // 인스턴스 생성을 막기 위해 기본생성자 private 선언
46 |
47 | public static void assertTrue(boolean condition) {
48 | if(!condition){
49 | throw new AssertionFailedError();
50 | }
51 |
52 | logger.info("Test Passed");
53 | }
54 | }
55 | ```
56 |
57 | AssertionFailedError.java
58 | ```java
59 | public class AssertionFailedError extends Error {
60 | public AssertionFailedError() {}
61 | }
62 | ```
63 |
64 | console
65 | ```shell
66 | 09:38:29.993 [main] INFO com.mysema.commons.lang.Assert - Test Passed
67 | ```
--------------------------------------------------------------------------------
/Spring/Concept/library/slf4j.md:
--------------------------------------------------------------------------------
1 | # SLF4J 이용하여 로그 남기는 방법 with Logback
2 | ## SLF4J 란?
3 | SLF4J는 로깅 Facade(퍼사드)이다. 로깅에 추상 레이어를 제공하는 interface 모음이다.
4 | 여러 로깅 라이브러리를 하나의 통일된 방식으로 사용할 수 있는 방법을 제공한다.
5 |
6 |
7 |
8 | application은 SLF4J를 이용하여 로깅 라이브러리가 어떤 것이든 같은 방법으로 로그를 남길 수 있게 되는 것이다.
9 |
10 | 나중에 더 많은 라이브러리가 생기더라도, application의 코드를 변경할 필요가 없다.
11 |
12 | ## Spring 에서 SLF4J 활용하기
13 | - 우선 스프링은 기본적으로 아파치 재단의 commons-logging을 이용해 로그를 남긴다.
14 | - Logback 라이브러리로 로그를 남기려면 commons-logging이 사용되지 않도록 설정을 해야 한다.
15 | - 그런데 Spring은 내부적으로 commons-logging을 찾아 로깅 하려고 해서, commons-logging을 사용하지 못하도록 설정하면 ClassNotFoundException이 발생한다.
16 |
17 | > 이 문제를 해결하기 위해 SLF4J 에서 제공하는 jcl-over-slf4j 라이브러리를 추가한 것이다.
18 |
19 |
20 | jcl-over-slf4j는 commons-logging과 동일한 구조를 가지며, SLF4J를 사용하여 로그를 남긴다.
21 |
22 | ## Logback 설정하기
23 |
24 | SLF4J는 로그를 남기기 위한 공통 인터페이스이다.
25 | SLF4J로 logback 라이브러리를 이용하여 로그를 남기는 것이므로, 실제 로그를 남기는 것은 logback 라이브러리다.
26 |
27 |
28 | ### 로그의 다섯 가지의 레벨 (아래쪽으로 내려 갈수록 심각한 오류)
29 | > 1. trace
30 | > 2. debug
31 | > 3. info
32 | > 4. warn
33 | > 5. error
--------------------------------------------------------------------------------
/Spring/Concept/webSpec.md:
--------------------------------------------------------------------------------
1 | # **✅ 웹 생태계의 스펙**
2 | > ## HTML, HTTP
3 | ```
4 | HTML: Hyper Text Markup Language
5 | HTTP: Hyper Text Transfer Protocol
--------------------------------------------------------------------------------
/Spring/Concept/whatIsSDK.md:
--------------------------------------------------------------------------------
1 | # **✅ 기본 SDK, 라이브러리/프레임워크 이해와 활용**
2 | ## **1️⃣ SDK**
3 | >"Software Development Kit"
4 | > SDK 안에는 개발에 도움이 될 개발 도구 프로그램, 디버깅 프로그램, 문서,
5 | > API 등이 있다.
6 |
7 | ## **2️⃣ Library**
8 | >라이브러리는 다른 프로그램들과 링크되기 위하여 존재하는, 하나 이상의 서브루틴이나 함수의 집합.
9 | > 함께 링크 될 수 있도록 보통 컴파일된 형태의 목적코드(objcet code)로 존재.
10 | > 운영체계나 소프트웨어 개발 환경 제공자들에 의해 제공되는 경우가 많다.
11 | > 라이브러리는 코드 재사용을 위해 조직화된 오래된 기법 중 하나.
12 |
13 | ## **3️⃣ FrameWork**
14 | > 애플리케이션 개발에 바탕이 되는 템플릿과 같은 역할을 하는 클래스와 인터페이스의 집합.
15 | > "목적에 따라 효율적으로 구조를 짜놓은 개발 방식" 이라고도 한다.
--------------------------------------------------------------------------------
/Spring/JPA/JpaEntity.md:
--------------------------------------------------------------------------------
1 | # ⛳️ JPA 엔티티 매핑 방법
2 | ### JPA 란?
3 | * Java Persistence Api
4 | * ORM 기술들을 자바에서 사용하기 위한 표준
5 |
6 | ## JPA 엔티티 매핑
7 | 1. 클래스는 public, protected로 선언돼있고, 매개변수가 없는 생성자를 반드시 가져야 함.
8 | 2. 클래스를 final로 지정하면 안됨.
9 |
10 | ```@Entity```
11 | > 엔티티로 사용하려면 반드시 붙여야 하는 애노테이션
12 | > javax.persistence.Entity 애노테이션 이용
13 | > name 옵션이 있고 default는 클래스의 이름
14 |
15 | ```@Table```
16 | > ddl 같은 테이블 세부사항을 조정하고 싶을 때 사용하는 애플리케이션
17 | > 주요 옵션은 name, schema, catalog, indexs 등 설정 가능
18 | > name 옵션은 기본 값은 Entity의 이름
19 |
20 | ```@Column```
21 | > 컬럼 매핑 애노테이션
22 | > 기본적으로 필드에는 자동적으로 @Column이 붙음
23 | > 옵션으로 name, unique, nullable, columnDefinition 등이 있음
24 | > nullable의 기본값은 true, unique의 기본값은 false
25 |
26 | ```@Id```
27 | > primary key 타입을 하는 필드에 이 애노테이션을 붙여야 함
28 | > primitive, wrapper, String, Date, BigInteger 타입이 가능
29 |
30 | ```@Enumerate```
31 | > enum 타입을 매핑하고 싶을 때 사용
32 | > enum의 순서나 이름중 하나를 선택해서 DB에 저장가능
33 |
34 | ```@Temporal```
35 | > 시간 관련 필드를 매핑하고 싶을 때 사용
36 | > BaseTimeEntity를 활용하여 시간 필드를 매핑하는 것이 좋다
37 |
38 | ```@Transient```
39 | > 매핑하고 싶지 않은 멤버를 제외할 때 선언
40 |
41 | ```@OneToMany```
42 | > 1에 해당하는 엔티티 클래스에서 Many에 해당하는 엔티티의 관계를 참조할 때 콜렉션으로 참조하고, 애노테이션을 @OneToMany를 붙여줌
43 |
44 | ```@ManyToOne```
45 | > n에 해당하는 엔티티 클래스에서 1에 해당하는 엔티티의 관계를 참조할 때 1에 해당하는 엔티티의 객체타입을 참조하고, @ManyToOne 애노테이션을 붙임
46 |
47 | **ManyToOne → 외래키 생성**
48 | **OneToMany → 조인테이블 생성**
49 |
--------------------------------------------------------------------------------
/Spring/JPA/can'tReturn2Result.md:
--------------------------------------------------------------------------------
1 | ## 데이터베이스에서 하나 이상의 값에 엑세스 하고 있어서 발생하는 Exception
2 |
3 | 발생하는 원인
4 |
5 | ```
6 | 1. 데이터베이스 값 (ID, 이름 등)이 고유 한 복제 수정인지 확인하십시오.
7 | 2. 데이터베이스를 변경하지 않으려면 get (0)을 0 인덱스 값만 반환하십시오.
8 | 3. 그렇지 않으면 uniqueResult ()를 List ()로 대체합니다.
9 | ```
10 |
11 | 발생하는 코드
12 |
13 |
14 |
15 | 해결방안
16 |
17 |
--------------------------------------------------------------------------------
/Spring/JPA/column-mapping-wrapperclass.md:
--------------------------------------------------------------------------------
1 | ## 왜 JPA column에 wrapperClass를 사용할까?
2 |
3 |
4 | 여러분들은 궁금하지 않았나요??
5 | 근데 자바의 굉장히 본질적인 측면에서 답을 얻을 수 있었습니다.
6 |
7 | ```java
8 | public class WrapperClassEx {
9 | Long id;
10 | long idx;
11 |
12 | public static void main(String[] args) {
13 | WrapperClassEx wrapperClassEx = new WrapperClassEx();
14 | System.out.println("Long id: " + wrapperClassEx.id + "\nlong idx: " + wrapperClassEx.idx);
15 | }
16 | }
17 | ```
18 |
19 |
20 |
21 | 자 이렇게 Long으로 선언된 id 는 아무것도 대입해주지 않았을때 null을 반환하지만, long은 0을 반환합니다.
22 | 여기서 알 수 있죠 DB를 조회했을때 해당 column이 primitive type 이라면 값이 0일때 null이여서 0인지 값이 실제로 0인지 구별할 수 없게 됩니다.
23 |
24 | #### Hibernate 공식문서에서도 권장사항을 확인할 수 있습니다.
25 |
26 |
27 | > 이처럼 기본열이 Nullable 해야함을 요구하고 있습니다.
--------------------------------------------------------------------------------
/Spring/JPA/ddl-auto.md:
--------------------------------------------------------------------------------
1 | ## spring.jpa.hibernate.ddl-auto 의 치명적 결함
2 | > 이 문서에는 내가 직접 겪은 내용을 간단히 정리할 것이다.
3 |
4 |
5 | 간단하게 3만건 insert 후 findAll JPA method를 실행했을 때 3만건이 조회되는지 확인하는 `@Test` 였다.
6 |
7 | 기존에는 `spring.jpa.hibernate.ddl-auto: create` 를 사용하고 있었다.
8 | 하지만 아래와 같은 검증 코드에서 3만건이 아닌 12만건을 조회하는 결과를 초래하더라..
9 |
10 |
11 |
12 |
13 | query를 확인하니 초반에 create 속성의 기능인 drop query를 안날리는 것을 발견했다!!
14 | 원래는 아래와 같이(해결된 쿼리) drop 날라간후에 create 되면서 기존 data를 다 밀어줘야 함.
15 |
16 |
17 |
18 | 암튼... 구글링을 엄청 해본 결과 답을 얻을 수 있었다.
19 | 그건 바로 `hibernate.hbm2ddl.auto` 라는 속성이다.
20 | 이 속성을 설명하자면! `spring.jpa.hibernate.ddl-auto` 프로퍼티 또한 `hibernate.hbm2ddl.auto`라는 속성으로 결국 hibernate에 전달 될 값을 지정하는 기능을 한다.
21 |
22 | 결론적으로 둘 중 어떤걸 사용해야 하는가에 대한 레퍼런스는 찾을 수 없었다.
23 | 나 처럼 drop 이 안되고 계속 create 만 하는 오류를 범하게 된다면 해당 옵션으로 대응하길 바란다.
24 |
25 | 아 결론적으로 `hibernate.hbm2ddl.auto` 쓰면 된다는 것이다.
--------------------------------------------------------------------------------
/Spring/JPA/extendsRelation.md:
--------------------------------------------------------------------------------
1 | # 상속관계 매핑
2 |
3 | > 관계형 데이터베이스는 상속 관계가 없다.
4 | > 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사.
5 | > 상속관계 매핑: 객체의 상속과 구조와 DB의 슈퍼타입 서브타입 관계를 매핑.
6 |
7 |
8 | ## 주요 어노테이션
9 | ```java
10 | - @Inheritance(strategy=InheritanceType.XXX)
11 | - @Discriminatorcolumn(name="DTYPE")
12 | - name = DTYPE이 Default
13 | - @Discriminatorvalue("xxx")
14 | ```
15 |
16 | ## 조인 전략
17 | - 장점
18 | - 테이블 정규화
19 | - 외례 키 참조 무결성 제약조건 활용가능
20 | - 저장공간 효율화
21 | - 단점
22 | - 조회시 조인을 많이 사용, 성능 저하
23 | - 조회 쿼리가 복잡함
24 | - 데이터 저장시 INSERT SQL 2번 호출 (성능에는 큰 타격이 없다.)
25 |
26 | ## 단일 테이블 전략
27 | - 장점
28 | - 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
29 | - 조회 쿼리가 단순함
30 | - 단점
31 | - 자식 엔티티가 매핑한 컬럼은 모두 Null 허용
32 | - 단일 테이블에서 모든 것을 저장하므로 테이블이 커질 수 있음.
33 | - 상황에 따라서 조회 성능이 오히려 느려질 수 있다(Column이 엄청 많지 않는 이상은 성능 저하 x)
34 |
35 | ## 구현 클래스마다 전략
36 | > 후회할 날이 오니 실무에서는 생각도 하지 마라.
--------------------------------------------------------------------------------
/Spring/JPA/findby.md:
--------------------------------------------------------------------------------
1 | ## 다양한 JPA findBy 메서드
2 |
3 | 오늘은 하루종일 top10 을 어떻게 처리할까에 대한 고민을 했다
4 | 처음에는 ```@Querydsl```로 리밋을 걸까 했지만 일반 JPA 메서드에서도 가능했었다.
5 |
6 | TableRepository.java
7 | ```java
8 | List findTop10ByOrderByGoodsDesc();
9 | ```
10 |
11 |
12 |
13 | 이렇게 하면 select query limit 이 10개 까지 걸림과 동시에 좋아요 갯수대로 정렬까지 되는걸 알 수 있다.
14 |
15 | console
16 | ```shell
17 | Hibernate:
18 | select
19 | tabledomai0_.board_idx as board_id1_3_,
20 | tabledomai0_.content as content2_3_,
21 | tabledomai0_.goods as goods3_3_
22 | from
23 | board tabledomai0_
24 | order by
25 | tabledomai0_.goods desc limit ?
26 |
27 | ```
--------------------------------------------------------------------------------
/Spring/JPA/mad-jpa.md:
--------------------------------------------------------------------------------
1 | # 알고나면 화가나는 JPA 오류 유형들
2 | > 오류를 발견하고 원인을 🙄 찾아내는 과정은 매우 고통스럽지만.. 알고나면 너무 허무한 JPA 관련 오류들을 모아볼게요
3 |
4 | ## 무작정 Table 관련 속성들을 추가하고 변경할 때.
5 |
6 | ### 발생한 에러
7 | ```
8 | org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException WARN: GenerationTarget encountered exception accepting command : Error executing DDL " drop table Order if exists" via JDBC Statement
9 | ```
10 |
11 | ### 해결방안
12 | 1. 기존에 있던 TABLE 들을 모두 날려주고(DROP) 실행해 본다.
13 |
14 |
15 |
16 | 2. [H2 데이터베이스 버전 확인하기.](https://inf.run/4uLo)
17 | 3. [데이터베이스 예약어랑 테이블, 칼럼 이름이랑 겹치는지 확인한다.](https://bit.ly/3telu1m)
18 |
19 | ### 내가 겪은 것
20 |
21 | 나는 이 글을 작성하는 이 시점에 3번째 해결방안을 검토해서 해결했다.
22 | 난 테이블 이름이 `Order` 여서..(Order는 `OrderBy` sql의 예약어임) `@Table` 애노테이션에 name 옵션을 줘서 해결했다.
23 |
24 |
25 |
26 | ## 무작정 hibernate 버전을 업데이트 했을 때.
27 |
28 | ### 에러를 유발한 코드
29 | ```xml
30 |
31 | org.hibernate
32 | hibernate-entitymanager
33 | 5.4.13.Final
34 |
35 | ```
36 |
37 | ### 발생한 에러
38 | ```
39 | The following method did not exist: 'void org.hibernate.annotations.common.reflection.ReflectionManager.reset()'
40 | ```
41 |
42 | 이건 Hibernate Error 인데, 우리는 JPA 를 이미 dependency로 가지고 있기 때문에 `hibernate-core` 와 `hibernate-annotations` 사이에 dependency conflict 를 내는것임.
43 | 아무튼 무작정 hibernate 관련 dependency는 추가하지 말것 !!
44 |
45 | ## 무지성 import 를 했을 때.
46 |
47 | ### 에러를 유발한 코드
48 | ```java
49 | import com.jpa.just.wrong.Member; // 잘못된 entity import
50 |
51 | public interface MemberRepository extends JpaRepository{}
52 | ```
53 |
54 | ### 발생한 에러 (IDE 시점의 에러)
55 | ```
56 | Inferred type 'S' for type parameter 'S' is not within its bound;
57 | ```
58 |
59 | 처음보는 에러라 당황했는데, 내가 작업하고 있는 환경이 `MemberEntity` 를 두개 가지고 있는 환경이여서 import가 잘 못 해서 발생한 문제였다.
--------------------------------------------------------------------------------
/Spring/JPA/mappedBy.md:
--------------------------------------------------------------------------------
1 | # 양방향 연관관계와 연관관계의 주인
2 |
3 | ## 연관관계 누구를 주인으로?
4 | > 외례키가 있는 곳으로 주인으로 정해라
5 | ```java
6 | public class Team {
7 | @OneToMany
8 | private List members = new ArrayList();
9 | }
10 | ```
11 | ```java
12 | public class Member {
13 | @ManyToOne(mappedBy="team")
14 | @JoinColumn(name = "TEAM_ID")
15 | private Team team;
16 | }
17 | ```
18 |
19 | ## 이유는?
20 | 그냥 이상하다!! ㅋㅋㅋㅋㅋㅋ
21 | JPA를 엄청 잘하면 One으로도 이해할 수 있지만 일반적으로는 Many인 부분에 mappedBy 한다.
--------------------------------------------------------------------------------
/Spring/JPA/querydsl-in-maven.md:
--------------------------------------------------------------------------------
1 | # Maven에 querydsl 설정하기
2 |
3 | ## 의존성 추가
4 |
5 | pom.xml
6 | ```xml
7 |
8 | ...
9 |
10 |
11 | com.querydsl
12 | querydsl-apt
13 | ${querydsl.version}
14 | provided
15 |
16 |
17 |
18 | com.querydsl
19 | querydsl-jpa
20 | ${querydsl.version}
21 |
22 |
23 | ...
24 |
25 | ```
26 |
27 | maven APT plugin -> "QClass Generate Structure 설정도 여기서"
28 |
29 | ```xml
30 |
31 |
32 |
33 | ...
34 |
35 | com.mysema.maven
36 | apt-maven-plugin
37 | 1.1.3
38 |
39 |
40 |
41 | process
42 |
43 |
44 | target/generated-sources/java
45 | com.querydsl.apt.jpa.JPAAnnotationProcessor
46 |
47 |
48 |
49 |
50 | ...
51 |
52 |
53 |
54 | ```
55 |
56 | ## 여기서 발생할 수 있는 에러
57 |
58 | `mvn clean` -> `mvn compile` (Qclass 생성) 시 생성되는 `target/generated-sources/java/` 하위의 QClass를 class 소스코드로 인식하지 못하는 점
59 |
60 | `⌘ + ;` 눌러서 project-structure 에 들어간다.
61 |
62 |
63 |
64 | 소스폴더에 해당 경로를 추가해준다.
65 |
66 |
--------------------------------------------------------------------------------
/Spring/JPA/warn-querydsl.md:
--------------------------------------------------------------------------------
1 | ## querydsl 사용시 이것만은 주의하자.
2 | > 일주일동안 헤맸던 문제였고 해결했지만 너무나도 어이없는 곳에서의 오류라 난감했고 허무했다. 정말 주의하자.
3 |
4 |
5 | ### 배경
6 | 1. Repository extends CustomRepo
7 | 2. CustomRepoImpl 만들어서 qeurydsl projection field 사용할 예정
8 | 3. ??? 동욱님 레퍼런스 정확히 이해하고 따라 했는데 도대체 왜 안되는걸까??
9 |
10 | ### 하나하나 차근차근 찾아보자
11 |
12 | * 우선 딱 봤을 때 아무문제 없는 file-structure (보고 이상한 점을 못느꼈다면 정말 이 글 잘 본거임)
13 |
14 |
15 |
16 | 하지만... 여기에는 크나큰 문제가 있었으니..
17 | 우선 이 자료를 보면 확실하게 이해할 수 있다.
18 |
19 | [구해주셔서 감사합니다🙇🏻♂️](https://insanelysimple.tistory.com/245)
20 |
21 | **하지만 나는 아래와 같이 이 레퍼런스와 같은 오류를 내뱉었던 것 아니였다.**
22 | ```
23 | spring data jpa querydsl property not found
24 | ```
25 |
26 | **나는 아래와 같은 오류가 생겼었음..**
27 | ```
28 | No converter found capable of converting from type [com.server.EZY.model.plan.tag.TagEntity] to type [com.server.EZY.model.plan.tag.dto.TagGetDto]
29 | ```
30 |
31 | 하지만.. 시원이가 해준 `repository 분할 그리고 비즈니스 로직에 DI 후 사용` 실험이 정상적인 query 출력이 결과를 통해 알아낸..
32 | **원인_1 querydsl projection을 인식못하는 것.**
33 |
34 | 설마 설마 하면서 ㅋㅋㅋ class 를 refectoring 했다.. 결과는 성공적..
35 |
36 | 결론적으로.. 클래스 명명규칙이 위 레퍼런스에서 말했던 것과 맞지 않다면..
37 | JPA 가 properties 를 인식하지 못하고 오류를 내뱉는 결과를 초래하게 된다.
38 |
39 | #### 진짜 네이밍은 마음대로 하는 것이 아니다. querydsl 사용시 꼭 주의하길 바란다.
--------------------------------------------------------------------------------
/Spring/SpringBoot/@BootstrapWith-error.md:
--------------------------------------------------------------------------------
1 | # Configuration error: found multiple declarations of @BootstrapWith for test class
2 |
3 | [발생 원인](https://bit.ly/35sy1oa) 해당 자료를 참고하면 해결방법과 다양한 원인들을 쉽게 확인할 수 있다.
4 |
5 | ## 원인 그리고 해결 방안
6 |
7 | 나는 아래와 같이 Controller를 테스트하다 에러가 발생했다.
8 | ```java
9 | @SpringBootTest
10 | @ContextConfiguration(classes = {Controller.class})
11 | public class ControllerTest {
12 |
13 | @Autowired
14 | private MockMvc mockMvc;
15 |
16 | ...
17 | }
18 | ```
19 |
20 |
21 | Junit 4에는 `@RunWith(SpringRunner.class)` 사용이 가능하지만, Junit 5 부터는 해당 애노테이션이 비활성화 되었다.
22 | 그래서 그냥 무지성으로 `@SpringBootTest`를 달아서 테스트 했는데 오류가 발생한 것이다.
23 |
24 | Junit 5 환경에서는 아래 처럼 바꾸어 시도해보면 될 것 같다.
25 |
26 | ```java
27 | @ExtendWith(SpringExtension.class) // 변경된 점
28 | @ContextConfiguration(classes = {Controller.class})
29 | public class ControllerTest {
30 |
31 | @Autowired
32 | private MockMvc mockMvc;
33 |
34 | ...
35 | }
36 | ```
37 |
38 | ## MockMvc 사용하면 @ExtendWith(SpringExtension.class)를 해줘야 하는 이유
39 |
40 |
41 | ### 서블릿 컨테이너를 Mocking 한다는 의미는..
42 |
43 | 웹 환경에서 컨트롤러를 테스트하려면 서블릿 컨테이너가 구동되고 DispatcherServlet 객체가 메모리에 올라가야 한다.
44 | 이 때 서블릿 컨테이너를 모킹하면 실제 서블릿 컨테이너가 아닌 테스트용 모형 컨테이너를 사용해서 간단하게 컨트롤러를 테스트할 수 있다.
45 |
46 | ### 실무에서 사용할 때
47 |
48 | 즉, 컨트롤러만 테스트할 때는 `@WebMvcTest`를 이외에 컴포넌트들도 테스트하려면 `@AutoConfigureMockMvc`를 사용하자.
49 | `@SpringBootTest` 로 테스트 했을 때 controller - service 사이에 `autowired` 가 되지 않았다고 오류가 뜨는데 그 이유가 이런 이유이다.
50 |
51 | MockMvc 테스트를 하는데 Controller 단에서 테스트가 그치는게 아니라 Service 혹은 다른 컴포넌트와 유기적인 결합을 통해 결과를 만들어 낸다면 서블릿 컨테이너를 사용해야 하기 때문에 `@AutoConfigureMockMvc` or `@ExtendWith(SpringExtension.class)` 를 추가하여 테스트 하자.
--------------------------------------------------------------------------------
/Spring/SpringBoot/CORS.md:
--------------------------------------------------------------------------------
1 | # SpringBoot에서 CORS 문제 해결하기
2 |
3 | ### 특정 컨트롤러나 요청에 대해서 Cross Origin 허용하기
4 |
5 | ``@CrossOrigin`` 사용
6 | ```java
7 | @RestController
8 | @CrossOrigin(origins = "http://localhost:63342") //해당 origin 승인하기
9 | @RequestMapping("/api/books")
10 | public class VocaTestApiController {
11 | ...
12 | }
13 | ```
14 |
15 | 전역 설정을 통해서 Corss Origin 허용하기
16 | ```java
17 | import org.springframework.context.annotation.Configuration;
18 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
19 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
20 |
21 | @Configuration
22 | public class WebMvcConfigurerImpl implements WebMvcConfigurer {
23 | @Override
24 | public void addCorsMappings(CorsRegistry registry) {
25 | registry.addMapping("/**") //모든 요청에 대해서
26 | .allowedOrigins("http://localhost:8080"); //허용할 오리진들
27 | }
28 | }
29 | ```
30 |
31 | ### Origin 이란?
32 | * Origin 은 아래 세가지의 조합이다.
33 | * URL 스키마(http, https)
34 | * Hostname(도메인 네임)
35 | * 포트 번호
36 |
37 | 즉, 호스트네임이 같더라도 다른 포트번호를 사용하면 다른 Origin 이라는 것
38 |
39 | ### 그래서 CORS는 뭐고 SOP는 뭔데
40 | * SOP(Same Origin Policy) - 악의적인 문서로부터 잠재적인 공격을 방어하기 위한 웹 보안 정책
41 | * CORS(Cross Origin Resource Sharing) - 안전한 Origin 들에 대해서 SOP 보안정책을 풀어주기 위한 방법
42 |
43 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/EJB.md:
--------------------------------------------------------------------------------
1 | ## Spring @Component @Bean 알고 쓰기
2 |
3 | 스프링을 사용할때는 무조건 알아야 하는 것에 대해 말해주겠다.
4 | 이것을 알아야 당신은 스프링 쓴다고 말할 수 있다.
5 |
6 | ### ``@Component`` 란
7 |
8 | 싱글톤 클래스 빈을 생성하는 어노테이션이다.
9 | 물론 ``@Scope("Prototype")`` 어노테이션을 통해 싱글톤이 아닌 빈을 생성할 수도 있다.
10 | 또한 ``@Service``, ``@Repository`` 어노테이션 또한 이에 포함된다.
11 |
12 |
13 |
14 | 이 어노테이션은 선언적인 어노테이션이다.
15 | 즉, 패키지 스캔 안에 이 어노테이션은 "이 클래스를 정의했으니 빈으로 등록해줘" 라는 뜻이 된다.
16 |
17 |
18 |
19 | ### ``@Bean`` 이란
20 | Bean은 주로 ``@Configuration`` 어노테이션이 들어간 Spring을 설정하는 클래스 내에 들어가는 매소드에서 선언한다.
21 | 만약 이를 ``@Component``로 따지면, 스프링은 스캔할 패키지를 검색해서 ``@Component`` 어노테이션을 발견하면 이렇게 등록하는 꼴이 된다.
22 |
23 | ```java
24 | @Component
25 | public class MyBean{
26 |
27 | }
28 | ```
29 |
30 | 물론 생성자에 인자가 있다면 그 빈이 있는지 확인 후 넣는다.
31 | 물론 없으면 스프링은 오류를 뱉으며 앱을 끝내버린다.
32 |
33 |
34 |
35 | 예전 스프링은 XML 설정만 가능했으며, 3.0 부터 어노테이션 지원이 시작되었다.
36 | 물론 최신 버전인 5.2에서도 XML 설정은 지원한다. XML을 이용해서 설정할 때의 장점이라면?
37 | 바로 넣었다 뺏다, 클래스를 바꾸는 등의 유연한 설정이 가능하다는 이점이다. 그냥 XML 파일 편집하고 앱을 재시작하면 끝이다. 정말 간단하다.
38 |
39 |
40 | ### 정리
41 |
42 | 일반적인 당신의 빈 등록은 간편하게 ``@Component`` 어노테이션으로, 유연한 빈 등록이 필요하다면 ``@Configuration`` 어노테이션이 들어간 클래스 내 ``@Bean`` 어노테이션 메소드 선언으로!
43 |
44 |
45 | 아, Spring Boot의 경우 ``@SpringBootApplication`` 어노테이션이 들어간 스프링 실행부에서도 ``@Bean`` 어노테이션이 깃든 메소드 등록이 가능하다는 것도 잊지 말자.
--------------------------------------------------------------------------------
/Spring/SpringBoot/JubJubStrcture.md:
--------------------------------------------------------------------------------
1 | # JubJub Server File Structure
2 | ## 💩 JubJub Project Servser File Structure
3 |
4 | ### 📄 File Structure
5 | ```
6 | com.gsm.jubjub
7 | - advice
8 | - exception
9 | - ExceptionAdvice.java
10 | - config
11 | - security
12 | - MessageConfiguration
13 | - SwaggerConfiguration
14 | - controller
15 | - exception
16 | - v1
17 | - model
18 | - responce
19 | - Admin
20 | - User
21 | - repo
22 | - Application
23 | ```
24 | ### 1. ```advice/exception/**.java``` 분석
25 | class를 보면 ```extends RuntimeException``` 가 상속 받아진 것을 볼 수 있다.
26 | > 말 그대로 실행 중에 발생하며 시스템 환경적으로나 인풋 값이 잘못된 경우, 혹은 의도적으로 프로그래머가 잡아내기 위한 조건등에 부합할 때 발생되게 만든다.
27 |
28 | ex) test 인자에 a 가 0인 경우 프로그램이 더이상 동작하지 않게 하고 싶다면 RuntimeException을 발생하면 된다.
29 | ```java
30 | public static void test(int a){
31 | if(a == 0){
32 | throw new RuntimeException("a는 0이 되선 안됩니다.");
33 | }
34 | }
35 | ```
36 |
37 | ### 2. ```@ExceptionHandler``` 이란
38 | ```@ExceptionHandler``` 같은 경우는 ```@Controller, @RestController```가 적용된 Bean 내에서 발생하는 예외를 잡아서 하나의 메서드에서 처리해주는 기능을 한다.
39 |
40 | ```java
41 | @RestController public class MyRestController {
42 | ...
43 | ...
44 | @ExceptionHandler(NullPointerException.class)
45 | public Object nullex(Exception e) {
46 | System.err.println(e.getClass());
47 | return "myService";
48 | }
49 | }
50 | ```
--------------------------------------------------------------------------------
/Spring/SpringBoot/MockMvc-test.md:
--------------------------------------------------------------------------------
1 | ## Spring Boot JUnit 5 MockMvc Test
2 | > [도움을 주셔서 감사합니다 🙇🏻♂️](https://gofnrk.tistory.com/74)
3 |
4 |
5 | ## AbstractControllerTest
6 | > 저는 test/testConfig 패키지에 따로 뺏습니다.
7 |
8 | 설정하는 방법
9 | * AutoConfiguration
10 | * Customizing
11 |
12 | ## AutoConfiguration
13 | > 아주 간단하게 테스트 할 때 사용하는 방법 mockMvc 객체를 사용해서.
14 |
15 | ```java
16 | @SpringBootTest
17 | @AutoConfigureMockMvc
18 | public abstract class AbstractControllerTest {
19 |
20 | @Autowired
21 | protected MockMvc mockMvc;
22 |
23 | }
24 | ```
25 |
26 | ## Customizing
27 | 오토컨피그로 설정하면 MockMvc 를 커스텀하기 어려움이 있다.
28 | 그래서 MockMvcBuilders 를 활용하여 직접 MockMvc 인스턴스를 생성한다.
29 |
30 | ```java
31 | @SpringBootTest
32 | public abstract class AbstractControllerTest {
33 | protected MockMvc mvc;
34 |
35 | abstract protected Object controller();
36 |
37 | /**
38 | * MockMvcBuilders 를 활용한 MockMvc 커스텀 메서드
39 | * 1. addFilter: UTF-8 인코딩을 해주지 않으면 테스트 수행 시 body가 깨진다.
40 | * 2. alwaysDo: 항상 콘솔에 테스트 결과를 찍어줘라.
41 | * 3. alwaysExpect: 항상 200 코드를 반환하기를 기대한다.
42 | *
43 | * @author: 전지환
44 | */
45 | @BeforeEach
46 | private void setup(){
47 | mvc = MockMvcBuilders.standaloneSetup(controller())
48 | .addFilter(new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true))
49 | .alwaysDo(print())
50 | .alwaysExpect(status().isOk())
51 | .build();
52 | }
53 | }
54 | ```
55 |
56 | ## 사용방법
57 | > 내가 테스트 하고 싶은 controller + extends + AbstractControllerTest
58 |
59 |
60 | ### 주의사항
61 | * 새션발급로직을 추가(@BeforeEach)하면 JWT 추가적인 header 검증이 필요가 없다.
--------------------------------------------------------------------------------
/Spring/SpringBoot/ModelMapperEntity.md:
--------------------------------------------------------------------------------
1 | ## ModelMapper Entity to DTO 변환 시 프로퍼티 null 해결
2 |
3 | 문제상황
4 | * findAll() 메서드를 사용할때, 쓸모없는 데이터를 제외한 유의미한 데이터를 끌어오기 위함에서 ModelMapper을 사용
5 | * 계속 select query trace에서는 정확히 나가는데 response code에는 null 이 뜨는 현상
6 |
7 | null 이 뜨는 현상
8 |
9 |
10 |
11 | 처음에는 service 부분이 문제라고 생각했다.
12 |
13 |
14 |
15 |
16 | ### 하지만 그냥 Dto에 ``Setter``을 안적은게 나의 문제였다
17 |
18 | 이유는 이러하다
19 | * "ModelMapper는 해당 클래스의 기본 생성자를 이용해 객체를 생성하고 setter를 이용해 매핑을 한다."
20 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/ThreadPool.md:
--------------------------------------------------------------------------------
1 | ## Thread Pool(스레드 풀) 이란??
2 |
3 | 간단하다. 스레드를 미리 만들어 놓은 하나의 풀장...이라고 생각하면된다.
4 | 군대를 빗대어보면, 전쟁이 나서 사방팔방에서 국지전을 펼친다고 생각해보자.
5 | 그때그때 추가병력을 요청할때마다 당신이 지휘관이라면, 1명씩 지원을 보낼텐가???
6 |
7 | > 미리 100명의 군인들을 섭외해서 다중적으로 발생되는 국지전에 예비 병력을 즉각 국지전에 대응해야한다.
8 |
9 |
10 |
11 | 그렇다면 이제 SW적으로 접근해보자.
12 | "스레드"라는 녀석은 생성될 때 컴퓨터 내부적으로 운영체제가 OS가 요청을 받아드려 메모리공간을 확보해주고, 그 메모리를 스레드에게 할당해준다.
13 | 스레드는 동일한 메모리영역에서 생성되고 관리되지만, 생성/수거에 드는 비용을 무시할 수 없다.
14 |
15 |
16 |
17 | > 그렇기 때문에 요청이 들어올 때 마다 스레드를 생성하고 일을 다하면 수거하고 하는 작업은 프로그램 퍼포먼스에 지대한 영향을 줄 수 있다.
18 |
19 |
20 | ## Thread Pool(스레드 풀)의 동작 원리
21 | 우리가 만든 어플리케이션에서 사용자로부터 들어온 요청을 작업큐에 넣고
22 |
23 | 스레드풀은 작업큐에 들어온 Task일감을 미리 생성해놓은 Tread들에게 일감을 할당한다.
24 |
25 | 일을 다 처리한 Thread들은 다시 어플리케이션에게 결과값을 리턴한다.
26 |
27 |
28 |
29 |
30 | > 자바에서는 스레드풀을 생성하고 사용할 수 있도록 ``java.util.concurrent Package``에서 ``ExecutorService`` 인터페이스와 ``Executors`` 클래스를 제공하고 있다. ``Executors``의 다양한 정적 메서드를 통해 ``ExecutorService`` 구현객체를 만들어서 사용할 수 있으며, 그것이 바로 스레드 풀이다.
31 |
32 | ## 그래서 Thread Pool 왜 사용해야해?
33 |
34 | 1. 프로그램 성능저하를 방지하기 위해
35 |
36 | 매번 발생되는 작업을 병렬처리하기 위해 스레드를 생성/수거 하는데 따른 부담은 프로그램 전체적인 퍼포먼스 저하시킨다.
37 |
38 | 2. 다수의 사용자의 요청을 처리하기 위해
39 |
40 | 서비스적인 측면으로 바라볼때,
41 | 특히 대규모 프로젝트에서 중요하다. 다수의 사용자의 요청을 수용하고, 빠르게 처리하고 대응하기 위해 스레드풀을 사용한다.
42 |
43 |
44 | ## Thread Pool 의 단점?
45 |
46 | 1. 과유불급.. 너무 많이 만들어 놓았다가 메모리 낭비만 발생.
47 |
48 | 많은 병렬처리를 예상해서 1억개의 스레드를 만들어 놓았다고 생각해보자, 실제로 100개정도의 요청과 병렬처리를 했다. 그러면 나머지 스레드들은 아무일도 하지 않고 메모리만 차지하는 최악의 경우를 발생할 수 있다.
49 |
50 | 2. 노는 스레드가 발생한다.
51 |
52 | 1번과 비슷하지만 조금 다르다.
53 |
54 | 예를 들어 A,B,C 스레드 3개가 있는데, 병렬적으로 일을 처리하는 과정에서 A,B,C 작업완료 소요시간이 다른 경우 스레드 유휴시간 즉 A스레드는 아직 일이 많아서 허덕이고 있는데, B,C는 일을 다하고 A가 열심히 일하는 것을 보고 놀고만 있는 유휴시간이 발생된다.
55 |
56 | 자바에서는 이를 방지하기 위해 forkJoinPool 을 지원한다. 아래 링크를 통해 알아보자
--------------------------------------------------------------------------------
/Spring/SpringBoot/dependency-option.md:
--------------------------------------------------------------------------------
1 | # 스프링 @Autowired 필드 명, @Qualifier, @Primary
2 | > 조회 대상의 빈이 2개 이상일 때 해결 방법
3 |
4 | ## 서론
5 | 조회 대상 빈이 두 개 이상?
6 | 어떻게 생긴건지 코드로 알아보자.
7 |
8 |
9 |
10 | 대략적으로 이런 상황에서 발생한다.
11 | Fare(요금) 이라는 인터페이스를 2개 이상의 클래스에서 구현하고 있는데.
12 |
13 | ```java
14 | @Service
15 | public class MobilityMarketService {
16 | @Autowired
17 | private Fare fare;
18 | }
19 | ```
20 |
21 | Fare 라는 타입의 인스턴스를 DI 받고싶을 때.
22 | DI 받아 사용하고자 하는 클래스에 `@Autowired`를 사용하여 주입하게 될 거다.
23 |
24 | `@Autowired`는 가장 먼저 타입으로 Bean을 조회한다.
25 | 근데 아까 말했듯 Fare를 구현하고 있는 클래스가 2개라 어느 클래스를 DI 받아야 할지 난감한 상황이 발생한다. `NoUniqueBeanDefinitionException`
26 |
27 |
28 |
29 | ### 이런 상황을 어떻게 해결하면 좋을까?
30 |
31 | ## 문제 해결
32 | 1. `@Autowired` 필드명으로 조회
33 |
34 | ```java
35 | @Service
36 | public class MobilityMarketService {
37 | @Autowired
38 | private Fare taxiFare;
39 | }
40 | ```
41 |
42 | 이렇게 필드에 내가 DI 원하는 클래스 명을 명시하는 방법이 있다.
43 |
44 | 2. `@Qualifier` 를 사용하는 방법
45 |
46 | ```java
47 | @Service
48 | public class MobilityMarketService {
49 | @Autowired
50 | @Qualifier("publicBusFare")
51 | private Fare fare;
52 | }
53 | ```
54 |
55 | 3. `@Primary`를 사용하는 방법
56 |
57 | ```java
58 | @Component
59 | @Primary
60 | public class TaxiFare implements Fare{
61 | // 생략
62 | }
63 | ```
64 |
65 | 이와 같은 오류가 발생하면 현명하게 대처하자.
--------------------------------------------------------------------------------
/Spring/SpringBoot/gradle-6-to-7.md:
--------------------------------------------------------------------------------
1 | # Gradle 6 to 7 what's different?
2 |
3 | 자세한 내용은 [여기서](https://docs.gradle.org/current/userguide/upgrading_version_6.html) 확인할 수 있다.
4 |
5 | ## 개요
6 |
7 | How to solve..
8 | ```
9 | Could not find method testCompile() for arguments
10 | ```
11 |
12 | ## IntelliJ에서 gradle version을 확인하는 방법은 굉장히 간단하다.
13 |
14 | ```
15 | gradle/wrapper/gradle-wrapper.properties
16 | ```
17 |
18 | 해당 디렉토리의 파일에 보면 `distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip` 이렇게 gradle 버전을 확인할 수 있다.
19 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/jar-html-execute.md:
--------------------------------------------------------------------------------
1 | # Gradle jar에 html 파일들을 생성하는 방법
2 | > Spring REST Docs을 사용하면 운영에서 AsciiDoc를 html로 실행해야 편하다.
3 |
4 | [이호진님 Spring REST Docs 적용](https://techblog.woowahan.com/2597/)이라는 글에는 html executor 설정이 아래와 같이 명시 돼 있다.
5 |
6 | ```Groovy
7 | bootJar {
8 | dependsOn asciidoctor // (3)
9 | from ("$/html5") { // (4)
10 | into 'static/docs'
11 | }
12 | }
13 | ```
14 |
15 | 하지만 이렇게 하면 `gradle-doesnt-copy-html-files-into-executed-jar` 라는 에러를 반환한다.
16 |
17 | #### best practice
18 | ```Groovy
19 | bootJar {
20 | dependsOn asciidoctor
21 | from ("${asciidoctor.outputDir}/html5") {
22 | into 'static/docs'
23 | }
24 | }
25 | ```
26 |
27 | 문제가 해결되는 것을 확인할 수 있다.
--------------------------------------------------------------------------------
/Spring/SpringBoot/modular-monoliths.md:
--------------------------------------------------------------------------------
1 | # 우아한 모듈형 모노리스
2 |
3 | ## 잡음
4 |
5 |
6 |
7 | 당근마켓🥕 1차를 붙었다. 진짜 나랑 친한 몇몇 친구들, 아니 그보다 안되는 친구들이 알고 있다.(최종이 아니라 1차니깐)
8 | 채용 담당자 분께서 메일로 면접관님들의 닉네임을 보내주셨다. 아니 설마 깃헙 이름이랑 같겠어 하고 궁금해서 구글링을 했다.(이래서 구글링은 개발자의 필수 덕목이다)
9 |
10 | 1달 전에 대덕에 다니는, Entry-DSM 백엔드 개발을 하고 있는 친구에게 "이거 처음보는 아키텍쳐인데 뭐야?" 라고 물어봤던 적이 있었는데.
11 | 아무튼 그때 "모듈형 모노리스 시스템"으로 개발되었다고 해서 오 ~ 하고 다음에 꼭 공부해봐야지 하고 넘어 갔던 적 있다.
12 |
13 | 근데 그 모듈형 모노리스 시스템 적용사례, ["우아한 모듈형 모노리스"](https://youtu.be/SrQeIz3gXZg) 를 발표하신 개발자분이 나의 면접관...!
14 | 이참에 모듈형 모노리스 그리고, arawn님의 [발표를 보며](https://www.slideshare.net/arawnkr/ss-195979955) 여러가지를 정리 해보려고 한다.
15 |
16 | 아참! 모듈형 모노리스 시스템에 대해 정리하기 전에,
17 |
18 | 이력서에 MSA에 관심이 많다고 했다.
19 | 실제로도 관심이 많다. 하지만 내가 공감할 수 없는 레벨이다.
20 | (하지만 뭐든 개념적인 부분은 다져두고 회사에 입사해야 한다고 생각한다.)
21 |
22 | 공감할 수 없는 이유는 간단하다.
23 | 도메인을 분산할 정도의 트래픽을 가진 서비스를 운영중에 있는 것도 아니고
24 | 서비스의 도메인중에 특정 부분이 독립적으로 기술적 문제를 풀어나가야 하는 것도 아니기 때문이다.
25 |
26 | 그리고 제일 중요한건 배포 파이프라인 구축과 인스턴스 관리가 복잡해지고 어려워진다. 비용도 많이 든다 ^^
27 | 뭔가 모듈형 모노리스는 이런 MSA의 단점들을 보완하면서도 적절히 일반 모노리스 시스템의 단점들을 해결해줄 것이라고 생각이 들었다.
28 |
29 | ## 들어가며..
30 |
31 |
32 |
33 | arawn님은 배달의민족에서 모노리스 시스템에서 MSA 로 전환하는 과정의 경험을 하셨다고 했다.
34 | 근데 왜 또 MSA 아키텍쳐에서 모노리스로 돌아가고 싶어 하시는걸까? 궁금해졌다. (뭔가 다들 MSA로 마이그레이션해서 장애 발생도 줄이고 쿨 해졌다고 했잖아?)
35 |
36 | 처음에 "모듈형 모노리스" 라는 단어를 듣고 굉장히 생소했다. 모노리스인데 모듈형이라고??
37 |
38 | ## 왜 모듈형 모노리스인가
39 |
40 | 세미나에서 모듈형 모노리스를 도입하게된 배경에 대해 그리고 MSA와 모듈형 모노리스 시스템의 장/단점 그리고 왜 우리 조직에는 모듈형 모노리스가 적합했는지 설명해주신다.
41 |
42 |
43 | * 조직 내 구성원의 수는 적었지만 프로젝트는 많았다.
44 | * 개발자 한명이 담당 해야하는 프로젝트가 많다.
45 | * 하나의 테이블을 여러개의 서비스가 공유하여 사용하는 경우.
46 | * 중복된 코드가 생길 수 밖에 없다.
47 | * 코드와 로직이 분산되어 있다 보니 서비스끼리 굉장히 복잡하게 동작할 수 박에 없다.
48 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/singleton-container.md:
--------------------------------------------------------------------------------
1 | # 싱글톤 컨테이너
2 |
3 | 스프링의 의존성을 관리해주는 컨테이너는 다양한 이름으로 불린다.
4 | 스프링 컨테이너, IoC 컨테이너, DI 컨테이너, 싱글톤 컨테이너 다 맞는 말이다. 싱글톤 개념은 앞에서 이미 많이 다루었으니 거기를 참고하도록 하자
5 |
6 | ## 코드로 알아보기
7 |
8 | 스프링 컨테이너가 싱글톤 컨테이너라는 사실을 입증하기 위해서는 아래의 테스트면 충분하다.
9 |
10 | ### DI 대상이 되는 컨테이너를 하나 만든다. (@Component)
11 | ```java
12 | @Component
13 | public class MySingletonService {
14 | public String singletonResponse(){
15 | return "wow it's singleton container";
16 | }
17 | }
18 | ```
19 |
20 | ### 싱글톤이 맞는지 테스트 하기 -> 객체 생성을 해도 같은 인스턴스를 반환 함.
21 | ```java
22 | @Test
23 | @DisplayName("singleton을 유지하는 방법")
24 | void singletonTest(){
25 | AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(JustApplication.class);
26 |
27 | MySingletonService bean1 = ac.getBean(MySingletonService.class);
28 | MySingletonService bean2 = ac.getBean(MySingletonService.class);
29 |
30 | System.out.println(bean1);
31 | System.out.println(bean2);
32 |
33 | assertEquals(bean1, bean2);
34 | }
35 | ```
36 |
37 | * `new AnnotationConfigApplicationContext()` () 안에 컴포넌트 스캔 할 대상을 넣는다.
38 |
39 | ### 테스트 결과
40 |
41 |
42 | ## 마무리
43 | spring, springboot 를 쓰는 사람들이라면 당연히 알거라고 생각한다.
44 | 혹, 내 TIL 을 보는 사람 중 아직 몰랐던 사람이 있다면, 직접 구현해서 좀 더 학습해보길 바란다.
45 |
46 | **앞으로의 내용이 다 싱글톤 컨테이너라는 개념을 베이스로 이야기 할 것이다.**
47 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/solve-with-provider.md:
--------------------------------------------------------------------------------
1 | # 프로토타입 스코프, 스프링 빈과 함께 사용시 발생하는 문제 Provider로 해결
--------------------------------------------------------------------------------
/Spring/SpringBoot/spring-bean-cycle-error.md:
--------------------------------------------------------------------------------
1 | ## 스프링 빈 순환 참조
2 | > The dependencies of some of the beans in the application context form a cycle:
3 |
4 | ### 문제가 왜 생겼나요?
5 | 내 app은 한 모델에 대해서 `repository, customRepository, repositoryImpl` 가 있었는데 각 클래스, 인터페이스 관계는 repository 가 customRepository를 parent 로 갖고 customRepository를 Impl가 구현한다.
6 |
7 | **순환 종속성 또는 순환 문제는 둘 이상의 Bean 이 생성자를 통해 서로를 주입하려고할 때 발생한다.**
8 |
9 | ### 해결방안
10 | 보통 의존성 주입은 `@Autowired` 또는 `@RequiredArgsConstructor` 를 통한 주입을 할 것이다.
11 |
12 | 일반적으로 Spring 은 애플리케이션 컨텍스트의 시작 / 부트스트랩 과정에서 모든 싱글톤 Bean 을 즉시 생성한다. 그 이유는 런타임이 아닌 컴파일 과정에서 모든 가능한 오류를 즉시 피하고 감지하는 것이다.
13 |
14 | 이처럼 문제가 되는 빈들을 주입 받을 때, `@Lazy` 어노테이션을 통해 지연로딩으로 임시방편 문제를 해결한다.
15 |
16 | 어플리케이션이 실행하는 즉시 초기화가 아닌 필요에 따라 지연 해결 프록시가 주입되는 방식으로 사용한다.
17 |
18 | ### 결론
19 | `@Lazy` 를 사용해 임시방편으로 문제를 해결하려 하지말고, 스프링 빈들의 관계를 재설계해서 문제를 해결하는것이 중요하다.
20 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/spring-bean-sigleton.md:
--------------------------------------------------------------------------------
1 | ## spring bean 과 싱글톤
2 | > 일정시간마다 데이터를 정재하는 스케쥴이 실행된다.
3 | > 해당 스케쥴을 실행하기 위해 Service Bean 을 수행하는데 초반에는 별 문제가 되지 않다가 데이터가 늘어나면서 속도가 느려지기 시작했다.
4 |
5 | AppRunner.class
6 | ```java
7 | @Component
8 | public class AppRunner implements ApplicationRunner {
9 | @Autowired
10 | private SampleService sampleService1;
11 |
12 | @Autowired
13 | private SampleService sampleService2;
14 |
15 | @Override
16 | public void run(ApplicationArguments args) throws Exception {
17 |
18 | System.out.println(sampleService1);
19 |
20 | System.out.println(sampleService2);
21 | }
22 | }
23 | ```
24 |
25 | console-result
26 | ```java
27 | com.example.sample.service.SampleService@439f37c4
28 | com.example.sample.service.SampleService@439f37c4
29 | ```
30 |
31 | 이러한 현상이 발생하는 이유는 Spring의 Bean은 기본적으로 singleton으로 관리되고 있기 때문이다.
32 | 이는 어찌보면 당연한 일이다. 서버가 실행되는 동안 수도 없이 많이 호출 될 수 있는데, 그때마다 일일히 생성한다면 메모리가 오래 버티지 못할 것이다.
33 |
34 |
35 | ### 호출 될 때마다 생성하기
36 | 그럼 호출 될 때마다 생성하게 할 순 없을까? 가능하다
37 | SampleService 클래스에 Scope 어노테이션을 추가하고 value 에 prototype 을 선언한다.
38 |
39 | ```java
40 | @Service
41 | @Scope(value = "prototype")
42 | public class SampleService {
43 | ...
44 | }
45 | ```
46 |
47 | 이후 실행해보면 다음과 같이 각각 객체가 생성됨을 확인할 수 있다.
48 |
49 | ```
50 | com.example.sample.service.SampleService@49860486
51 | com.example.sample.service.SampleService@3e3e51a6
52 | ```
53 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/spring-mvc-lifecycle.md:
--------------------------------------------------------------------------------
1 | ## Spring MVC Lifecycle
2 | > 개발을 하다 exception handling 을 하는데 기본적인 mvc 라이프사이클도 정확히 모르고 있는 것 같아 정리한다.
3 |
4 |
5 |
6 | 이 사진 하나면 설명이 가능하다.
7 |
8 | #### Filter
9 | * 여기 filter 은 springboot application 에서 전역적인 로직을 담당한다.
10 | * 전체적인 필터링을 하는 곳이고, DispatcharServlet에 들어가기 전인 Web Application 딴에서 실행된다.
11 |
12 | #### DispatcherServlet
13 | * App 에 들어오는 모든 req 를 우선적으로 받아 처리하는 서블릿이다.
14 | * HandlerMapping 에게 req 에 대해 매핑한 Controller 의 검색을 요청한 뒤, Controller 의 정보를 받아 해당 Controller 와 매핑시킨다.
15 | * Dispatcher 라는 단어 자체가 '배치 담당자' 라는 뜻이 있듯이, 말 그대로 req 에 대해 어느 Controller 로 매핑시킬 것인지 배치하는 역할을 한다.
16 |
17 | #### HandlerMapping
18 | * 아까 말했듯이 DispatcherServlet 로 부터 controller 검색 요청을 받아 처리한 뒤 반환한다.
19 |
20 | #### HandlerInterceptor
21 | * req 가 controller 에 매핑되기전 앞단에서 부가적인 로직을 끼워 넣는다.
22 | * 보통 `세션, 쿠키, 권한 인증` 로직에 사용된다.
23 |
24 | #### Controller
25 | * req 와 매핑되는 곳이며, req에 대해 어떤 service 를 처리할 것인지 결정하고, 그에 맞는 service 를 호출한다.
26 | * spring bean 을 스프링 컨테이너로부터 주입받아야 하고, 이유는 service bean 의 메서드를 호출해야 하기 때문이다.
27 |
28 | #### service
29 | * 데이터 처리 및 가공을 위한 비즈니스 로직을 수행한다.
30 | * req 에 대해 실질적인 로직을 수행하기 떄문에, Spring MVC Request Lifecycle 의 심장이다.
31 | * service 가 없다면 서버 애플리케이션 존재 이유도 없다.
32 | * req 를 통해 DB 에 접근하여 데이터의 CRUD를 처리한다.
33 |
34 | #### Repository
35 | * DB에 접근하는 객체이다. DAO 라고도 부른다.
36 | * Service에서 직접 DB에 접근할 수 있게 하여 데이터의 CRUD를 가능하게 한다.
37 |
--------------------------------------------------------------------------------
/Spring/SpringBoot/springboot-async.md:
--------------------------------------------------------------------------------
1 | ## springboot @Async 는 어떻게 동작하는가?
2 | > [도움을 주셔서 감사합니다 🙇🏻♂️](https://brunch.co.kr/@springboot/401)
3 | > 스프링 프레임워크에서 제공하는 @Async 비동기 메서드 사용 방법에 대해서 알아보자
4 |
5 | ### 1. 병렬 프로그래밍
6 |
7 | #### 비동기 vs 논블록킹
8 | '비동기'와 '논블록킹'에 대한 비교는 개발자마다 조금씩 기준이 다른 것 같다.
9 | '비동기'는 메서드를 제공하는 입장에서의 개념이고, '논블록킹'은 메서드를 사용하는 클라이언트 입장에서의 개념이라고 생각한다.
10 | 사실 두 개의 입장이 다르기 때문에 비교 대상이 아니라는 얘기다.
11 |
12 | **비동기 & 논블록킹에 대해서 명확하게 정의할 수 있는 개발자는 필자에게 조언을 꼭 해주길 부탁한다.**
13 |
14 | #### 쓰레드풀
15 | 순차 프로그래밍 예시를 먼저 알아본다. 수행시간이 1초가 걸리는 메서드가 있다고 가정한다.
16 | ```java
17 | private static void task(){
18 | try{
19 | Thread.sleep(1000);
20 | } catch(InterruptedException e){
21 | e.printStackTrace();
22 | }
23 | }
24 | ```
25 |
26 | 해당 메서드를 100번 실행하면?
27 | 100초의 시간이 걸릴 것이다. 단 하나의 쓰레드로 모든 작업을 순차적으로 처리하게 된다.
28 | 그래서 1초를 * 100 번 수행하기 떄문에 100초의 지연시간이 발생한다.
29 |
30 | #### 병렬 프로그래밍으로 개선
31 | 짧은 시간에 모든 작업이 완료될 수 있도록 '병렬 프로그래밍'으로 개선해보자. `Executors.newFixedThreadPool` 메서드를 사용해서 쓰레드풀을 정의한다.
32 |
33 | ```java
34 | private static final int THREAD_POOL_SIZE = 100;
35 | private static final Executor executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
36 | ```
37 |
38 |
--------------------------------------------------------------------------------
/backend/architecture/SOA-MSA.md:
--------------------------------------------------------------------------------
1 | # SOA 그리고 MSA
2 | > 원래도 MSA에는 관심이 많았고, 오늘의집도 관심이 많은 나는 우연히 [surfit](https://www.surfit.io/) 최신 콘텐츠에서 오늘의집 MSA Phase 1 포스팅을 접하게 된다.
3 | > 읽어보니 API Gateway.. SOA .. etc 개념들이 방대하게 쏟아져 나온다. 한번 SOA와 MSA 같이 정리해보고 API Gateway는 양이 많아 따로 정리해보려 한다.
4 |
5 | ## SOA (Service Oriented Architecture)
6 |
7 | SOA는 1990년대에 정의되어, 2008년에 유행했던 아키텍처 스타일이다.
8 | 현대의 서버 아키텍처는 SOA 사상에 영향을 많이 받았고 많은 분산 아키텍쳐가 거의 이 SOA 사상에 기인한다고 해도 될 만큼 중요한 아키텍쳐이다.
9 |
10 | ## SOA 개념
11 |
12 |
13 |
14 | * SOA란 기존 애플리케이션들의 기능을 비즈니스적인 의미가 있는 기능 단위로 묶고, 표준화된 호출 인터페이스를 통해 서비스라는 소프트웨어 컴퍼넌트 단위로 재조합한 후, 이 서비스들을 조합하여 업무 기능을 구현한 애플리케이션을 만들어내는 소프트웨어 아키텍쳐
--------------------------------------------------------------------------------
/backend/architecture/restapi.md:
--------------------------------------------------------------------------------
1 | # 그런 REST API로 괜찮은가
2 |
3 | 여러 강의에서도 그렇고 프로젝트를 하면서도 그렇고 REST에 대해서 심도있게 생각해본적이 없는 것 같다.
4 | 그저 HTTP URI로 대상 리소스를 HTTP method로 리소스의 행위를 표현하면 되는게 아닌가 생각하고 넘어갔던 것 같다.
5 |
6 | ## REST API 구성
7 |
8 | * [microsoft rest api guidelines](https://github.com/microsoft/api-guidelines)
--------------------------------------------------------------------------------
/backend/etc/sentry-logging.md:
--------------------------------------------------------------------------------
1 | # Sentry를 통해 로깅 시스템 구축하기
2 |
3 | 자세한 initialize는 [Sentry 공식 페이지](https://sentry.io/welcome/)를 참고하자.
4 |
5 | ## 환경설정 DSN 주소를 public 으로 설정해도 되나요?
6 |
7 | Sentry에서 DSN은 Data Source Name 으로 Sentry에 새로운 프로젝트를 생성해서 모니터링 하고 싶을 때. 자신의 어플리케이션 이벤트를 Sentry 프로젝트에 전송 해주는 역할을 한다.
8 |
9 | 결론적으로 DSN은 내 애플리케이션에서 발생한 이벤트를 내 Sentry 프로젝트에 보내주는 역할을 하는 것이다.
10 |
11 | 이 DSN에 대해서 VCS에 public으로 commit 할것이냐 private으로 commit 할 것이냐에 대해 의견이 분분하다.
12 |
13 | ### 자세한 내용은 [-> Sentry 포럼 참고](https://forum.sentry.io/t/dsn-private-public/6297)
14 | 여기서도 user 한분이 언급한다 VCS(git)에 올리게 되면 모든 사람이 DSN을 볼 수 있는데 이걸 비공개로 유지해야 하는지 어떻게 해야 하는지.
15 |
16 | 하지만 Sentry 개발자는 DSN을 굳이 private 할 필요가 없다고 한다.
--------------------------------------------------------------------------------
/backend/jwt/jwt-dependency-duplicate.md:
--------------------------------------------------------------------------------
1 | # jwt 의존성 중복으로 인한 기이한 에러
2 |
3 | ## 발생한 에러
4 |
5 |
6 | ```shell
7 | 'can not create bean jwtProvider.....'
8 | 'int io.jsonwebtoken.SignatureAlgorithm.getMinKeyLength()'
9 | ```
10 |
11 | ## 해결 방법
12 |
13 |
14 |
15 | jjwt 와 jjwt-api 의 의존성에 충돌이 발생한다.
16 | 회색 하이라이팅 처리 돼 있는 일반 jjwt 의존성을 삭제하면 해결된다.
17 |
18 | (모두들 에러 메시지를 잘 읽자)
--------------------------------------------------------------------------------
/backend/jwt/jwt-http-header-type.md:
--------------------------------------------------------------------------------
1 | # BEST HTTP Authorization header type for JWT
2 |
3 | ## 개요
4 | JWT 예제마다, token 기반 인증/인가 예제마다. 인증 토큰에 가장 적합한 HTTP 헤더 유형이 무엇인지 궁금해서 알아본 내용을 공유한다.
5 | 이미 나와 같은 생각을 많은 분들이 하셔서 [링크](https://bit.ly/3tAfjFe) 걸어둔다. (해당 내용을 발췌해서 만든다.)
6 |
7 | ## JWT HTTP header
8 | 클라이언트가 엑세스 토큰을 보내는데 가장 적합한 HTTP header는 인증 체계가 있는 `Authorization` header 라고 한다.
9 | 이 체계는 [RFC-6750](https://www.rfc-editor.org/rfc/rfc6750)에 의해 설명됩니다.
10 |
11 | 예시:
12 | ```
13 | GET /resource HTTP/1.1
14 | Host: server.example.com
15 | Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9TJV...r7E20RMHrHDcEfxjoYZgeFONFh7HgQ
16 | ```
17 |
18 | (예: 본문 요청 또는 쿼리 문자열)을 사용하여 JWT를 자유롭게 수락할 수 있지만, 헤더가 더 적절하고 HTTP 1.1 컨텍스트에서 인증 프레임워크를 설명하는 RFC7235 `Authenticate`를 준수합니다.
19 |
20 | ### JWT에서도 Bearer 스키마를 사용한 인증 헤더 방식을 권장합니다.
21 |
22 |
23 |
24 | ## JWT secret key
25 |
26 | jwt secret key는 HS512 알고리즘을 사용할 것이기 때문에 512bit, 즉 64byte 이상의 secret key를 사용해야 한다.
27 | [Base64 String](https://generate.plus/en/base64) <- 해당 링크는 Base64 문자열을 byte length에 따라 생성해주는 사이트이다.
28 |
29 | 예시:
30 | ```
31 | jwt.secret: 'BQby6J0BWgJHTF0yE5OO8/+CMSqFINbh7LbiLNno8yVCt787DdsfTDOAjfMrHL46SKjwB8oj6XMAGdwGcs+ZgA=='
32 | ```
33 |
34 | ## JWT가 Base 64 512bit encoding 을 사용하는 이유.
35 | > 이런 질문은 던지는건 굉장히 단순하지만, jwt를 사용하는 개발자는 꼭 짚고 넘어가야 하는 개념이라고 생각한다. [-> stackoverflow에서도 언급 됐다.](https://stackoverflow.com/questions/58341833/why-base64-is-used-in-jwts)
36 |
37 | ASCII 7bits encoding을 사용하여 라이트하게 데이터를 전송할 수 있는데 왜 Base64 512 bit를 굳이 사용할까?
38 |
39 | ### 대표적인 문제는 아래와 같이 설명한다.
40 |
41 | * ASCII는 7 bits 인토딩인데 나머지 1bit를 처리하는 방식이 시스템 별로 상이하다.
42 | * 일부 제어 문자의 경우 시스템 별로 다른 코드값을 가진다.
43 |
44 | Base64는 ASCII 중 제어 문자와 일부 특수문자를 제외한 64개의 안전한 출력 문자만 사용한다. (아래 그림을 참고)
45 |
46 |
--------------------------------------------------------------------------------
/experience/ES.md:
--------------------------------------------------------------------------------
1 | # Elastic Search
2 | ## ES와 RDBMS
3 | > ES에서 사용되는 데이터 구조를 RDBMS에 대응해 보면 다음과 같이 맵핑된다.
4 |
5 | |ES|RDBMS|
6 | |:---:|:---:|
7 | |Index|DataBase|
8 | |Shard|Partition|
9 | |Type|Table|
10 | |Document|Row|
11 | |Field|Column|
12 | |Mapping|Schema|
13 | |Query DSL|SQL|
14 |
15 | Elastic Search는 기본적으로 http 프로토콜 접근이 가능한 REST API를 통해 데이터 조작을 지원한다.
16 |
17 | |ES HTTP Method|RDBMS SQL|
18 | |:---:|:---:|
19 | |GET|SELECT|
20 | |PUT|INSERT|
21 | |POST|UPADTE, SELECT|
22 | |DELETE|DELETE|
23 | |HEAD(index info)| |
24 |
25 | ## 역색인
26 | 일반적인 DB 에서는 볼 수 없는 개념인 '역색인'은 뭘까?
27 | '문서 내의 문자와 같은 내용물'의 맴핑 정보를 색인해놓은 것이다.
28 |
29 |
30 |
31 | 쉬운 예시로 들어보면 일반 색인(forward index)는 책의 목차와 같은 의미이고, 역색인(inverted index)는 책 가장 뒤의 단어 별 색인 페이지와 같다.
32 |
33 | ## ES 의 특징
34 | ES 는 NOSQL 의 일종으로 분류할 수 있고, 분산처리를 통해 실시간성으로 바른 검색이 가능하다. 특히 기존의 데이터로 처리하기 힘든 대령의 비정형 데이터 검색이 가능하며 전문 검색(full text)검색과 구조 검색 모두를 지원한다.
35 | 기본적으로 검색엔진이지만 MongoDB나 Hbase와 같은 대용량 스토리지도 활용이 가능하다.
36 |
37 |
38 |
39 | 장점
40 | * 오픈소스 검색엔진이다. 활발한 오픈소스 커뮤니티가 ES를 끊임없이 개선하고 발전시키고 있다.
41 | * 전문검색: 내용 전체를 색인해서 특정 단어가 포함된 문서를 검색할 수 있다.
42 | * 통계분석: 비정형 로그 데이터를 수집하여 통계 분석에 활용할 수 있다.
43 | * Schemaless: 정형화되지 않은 문서도 자동으로 색인하고 검색할 수 있다.
44 | * RESTful API: HTTP 기반의 RESTful을 활용하고, 요청/응답에 JSON을 사용해 개발 언어, 운영체제, 시스템에 관계없이 다양한 플랫폼에서 활용이 가능하다.
45 | * Multi-tenancy: 서로 상이한 인덱스일지라도 검색할 필드명만 같으면 여러 인덱스를 한번에 조회 할 수 있다.
46 |
47 |
48 |
49 | **단점**
50 | * 완전 실시간은 아니다: 색인된 데이터는 1초 뒤에나 검색이 가능하다. 내부적으로 commit 과 flush 같은 복잡한 과정을 거치기 때문이다.
51 | * Transaction Rollback을 지원하지 않는다: 전체적인 클러스터의 성능 향상을 위해 시스템적으로 비용 소모가 큰 롤백과 트랜잭션을 지원하지 않는다.
52 | * 데이터의 업데이트를 제공하지 않는다: 업데이트 명령이 올 경우 기존 문서를 삭제하고 새로운 문서를 생성한다. 업데이트에 비해서 많은 비용이 들지만, 이를 통해 불변성이라는 이점을 취한다.
--------------------------------------------------------------------------------
/experience/puppeteer.md:
--------------------------------------------------------------------------------
1 | # Puppeteer
2 | > Puppeteer은 Headless Chrome 혹은 Chromium 를 제어하도록 도와주는 라이브러리
3 |
4 | ## Puppeteer 기능
5 | * SPA 화면의 렌더링이 가능하다.
6 | * 렌더링후 키보드, 마우스 입력 제어를 할 수 있다.
7 | * 웹페이지의 자동 테스트 도구를 만들 수 있다.
8 | * 각각의 웹페이지 crawling이 가능하다.
9 | * 접속한 페이지를 스크린샷을 찍거나 PDF로 만들 수 있다.
10 |
11 | ## Handless Browser
12 | > Headless Browser은 CLI에서 작동하는 브라우저이다.
13 | > 일반적으로 사용자가 사용하는 GUI에서 동작하는 브라우저가 아니다.
14 |
15 | 백그라운드에서 동작하며, 일반적인 브라우저와 같이 웹페이지에 접속하여 HTML, CSS로 DOM Tree 와 CSSOM Tree를 만들고 JS 엔진을 구동한다.
16 |
17 |
18 | 일반 브라우저와 큰 차이가 없어, 화면 테스트나 스크린샷을 찍는 것 등 다양한 기능 동작이 가능하며, 사용자가 실제 사용하는 환경과 비슷하게 테스트가 가능하다.
19 |
20 | ## Puppeteer의 특징
21 | > Puppeteer에서는 Chrome 혹은 Chromium의 렌더링 엔진을 사용하여 Headless Browser 환경을 구성하였다.
22 |
23 | 2017년 Google Chrome 59버전 부터 Headless Chrome 이 내장되었고, 얼마후 Google 에서 puppeteer를 발표하였다.
24 |
25 |
26 | 여러 iframe 이나 popup으로 이루어진, 복잡한 화면을 제어하는 것이 가능하며, 최근 ES6로 작성된 SPA 화면들도 렌더링 및 제어가 가능하다.
27 |
28 |
29 | DevTools 프로토콜로 Mouse, Keyboard 뿐만 아니라, 브라우저 스크린 크기, 쿠키 및 세션 스토리지, 심지어 서비스 워커도 제어가 가능하다.
30 |
31 | ## Puppeteer의 구조
32 | Puppeteer API는 계층적이다
33 | * Puppeteer는 하나의 Browser을 갖는다.
34 | * 하나의 Browser는 여러 BrowserContext를 가질 수 있다.
35 | * 하나의 BrowserContext가 여러 Page를 가질 수 있고, Serviceworker와 session을 사용할 수 있다.
36 | * 하나의 Page는 여러 Frame을 가질 수 있다.
37 | * 하나의 Frame은 여러 Context를 가질 수 있다.
38 |
39 |
40 |
41 | ## 마무리
42 | > puppeteer은 Headless Chrome을 제어하도록 도와주는 라이브러리다.
43 | > 이것을 어떻게 이용할지는 오로지 개발자의 몫이다.
44 |
--------------------------------------------------------------------------------
/http/2xx-success.md:
--------------------------------------------------------------------------------
1 | # 2xx - Successful
2 | > 클라이언트 요청을 성공적으로 처리
3 |
4 | * 200 OK
5 | * 요청 성공
6 | * 201 Created
7 | * 요청 성공해서 리소스가 생성됨
8 | *
9 | * 202 Accepted
10 | * 요청이 접수되었으나, 처리가 완료되지 않았음
11 | * 배치 처리 같은 곳에서 사용
12 | * 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리함
13 | * 204 No Content
14 | * 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
15 | * 예) 웹 문서 편집기에서 save 버튼
16 | * save 버튼의 결과로 아무 내용이 없어도 된다.
17 | * save 버튼을 눌러도 같은 화면을 유지해야 한다.
18 | * 결과 내용이 없어도 204 메시지 (2xx)만으로 성공을 인식 할 수 있다.
19 |
20 |
--------------------------------------------------------------------------------
/http/4xx-client-error.md:
--------------------------------------------------------------------------------
1 | # 4xx - 클라이언트 오류
2 | > 클라이언트 오류
3 |
4 | ## 4xx - 공통
5 | * 클라이언트의 요청이 잘못된 문법등으로 서버가 요청을 수행할 수 없음
6 | * 오류의 원인이 클라이언트에 있음
7 | * 중요! 클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기 때문에, 똑같은 재시도가 실패함
8 |
9 | ## 400 - Bad Request
10 | > 클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음
11 |
12 | * 요청 구문, 메시지 등등 오류
13 | * 클라이언트는 요청 내용을 다시 검토하고, 보내야 함
14 | * 예) 요청 파라미터가 잘못되거나, API 스펙이 맞지 않을 때
15 |
16 | ## 401 Unauthorized
17 | > 클라이언트가 해당 리소스에 대한 인증이 필요함
18 |
19 | * 인증 되지 않음
20 | * 401 오류 발생시 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명
21 | * 참고
22 | * 인증(Authentication): 본인이 누구인지 확인 (로그인)
23 | * 인가(Authorization): 권한부여 (Admin인지 Customer인지)
24 | * 오류 메시지가 Unauthorized 이지만, 인증 되지 않음
25 |
26 | ## 403 Forbidden
27 | > 서버가 요청을 이해했지만 승인을 거부함
28 |
29 | * 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우
30 | * 어드민 등급이 아닌 사용자가 로그인은 했지만, 어드민 등급의 리소스에 접근하는 경우
31 |
32 | ## 404 NotFound
33 | > 요청 리소스를 찾을 수 없음
34 |
35 | * 요청 리소스가 서버에 없음
36 | * 또는 클라이언트가 권한이 부족한 리소스에 접근할 때 리소스를 숨기고 싶을 때
37 | * (ex 권한이 없어서 실제로는 403이지만 클라이언트에게 리소스를 아예 없는 것 처럼 숨기고 싶을 때)
38 |
39 |
--------------------------------------------------------------------------------
/http/5xx-server-error.md:
--------------------------------------------------------------------------------
1 | # 5xx Server Error
2 |
3 | ## 5xx - 공통
4 | * 서버 문제로 오류 발생
5 | * 서버에 문제가 있기 때문에 재시도 하면 성공할 수도 있음(복구가 되거나 등등)
6 |
7 | ## 500 - Internal Server Error
8 | 서버 문제로 오류 발생, 애매하면 500 오류
9 |
10 | * 서버 내부 문제로 오류 발생
11 | * 애매하면 500 오류
12 |
13 | ## 503 - Service Unvailable
14 | 서비스 이용 불가
15 |
16 | * 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
17 | * Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수도 있음
--------------------------------------------------------------------------------
/http/DNS.md:
--------------------------------------------------------------------------------
1 | # DNS
2 |
3 | ## IP는 기억하기 어렵다
4 | 저자가 운영하는 서비스 the-moment, 들어가기 위해 `1.23.432.12` 을 사용해야 한다면 어떨까? 그리고 1달 뒤에 `1.253.232.112` 로 바뀐다면 또 어떨까?
5 |
6 | ### 이처럼 IP는 기억하기 어렵다.
7 |
8 |
9 | **+ 또, 아이피는 변경될 수 있다.**
10 |
11 | ## DNS
12 | > 도메인 네임 시스템 (Domain Name System)
13 |
14 | 본 저자는 DNS 관리를 [CloudFlare](https://www.cloudflare.com/ko-kr/)로 하는것을 선호한다. 다양한 기능들을 무료로 즐길 수 있으며 더 많은 기능은 유료로 제공한다. * 무료의 기능도 제법 좋다.
15 |
16 |
17 |
18 | ### 인터넷 네트워크 끝
--------------------------------------------------------------------------------
/http/HTTP-method.md:
--------------------------------------------------------------------------------
1 | # HTTP 메서드
2 |
3 | ## index
4 | * HTTP API를 만들어보자
5 | * HTTP 메서드 - GET, POST
6 | * HTTP 메서드 - PUT, PATCH, DELETE
7 | * HTTP 메서드의 속성
8 |
9 | ## URI 설계
10 | **가장 중요한 것은 "리소스 식별"이다.**
11 |
12 | ### API URI 고민
13 | * 리소스의 의미는 뭘까?
14 | * 회원을 등록하고 수정하고 조회하는게 리소스가 아니다 (동사 X).
15 | * 미네랄을 캐라 -> "미네랄"이 리소스
16 | * 위에 예시에서는 회원이라는 개념 자체가 바로 리소스이다.
17 | * 리소스를 어떻게 식별하는것이 좋을까?
18 | * 회원을 등록하고 수정하고 조회하는 것을 모두 배제
19 | * 회원이라는 리소스만 식별하면 된다 -> 회원 리소스를 URI에 매핑
20 |
21 |
22 |
23 | ## 리소스와 행위를 분리
24 | * URI는 리소스만 식별!
25 | * 리소스와 해당 리소스를 대상으로 하는 행위를 분리
26 | * 리소스: 회원
27 | * 행위: 저장, 조회, 삭제, 변경
28 | * 리소는 명사, 행위는 동사 ([GET] - /member : 회원을 조회하라)
29 | * 행위 메서드는 어떻게 구분??
30 |
31 |
32 | #### [다음편에서 계속..](./GET-POST.md)
--------------------------------------------------------------------------------
/http/HTTP-status-code.md:
--------------------------------------------------------------------------------
1 | # HTTP 상태코드
2 |
3 | ## 상태 코드
4 | > 클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능
5 |
6 | * 1xx(Informational): 요청이 수신되어 처리 중
7 | * 2xx(Successful): 요청 정상 처리
8 | * 3xx(Redirection): 요청을 완료하려면 추가 행동이 필요
9 | * 4xx(Client Error): 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행 할 수 없음
10 | * 5xx(Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함
11 |
12 | ## 만약 모르는 상태 코드가 나타나면?
13 |
14 | * 클라이언트가 인식할 수 없는 상태코드를 서버가 반환하면?
15 | * 클라이언트는 상위 상태코드로 해석하여 처리
16 | * 미래에 새로운 상태 코드가 추가 되어도 클라이언트를 변경하지 않아됨
17 |
18 | ex
19 | * 299 -> 2xx (성공)
20 | * 451 -> 4xx (클라이언트 오류)
21 | * 599 -> 5xx (서버 오류)
22 |
23 | 이런식으로 상위 상태코드로 충분히 요청의 처리 상태를 유추 해볼 수 있다.
24 |
25 | ## 1xx (Informational)
26 | > 요청이 수신되어 처리 중
27 |
28 | * 거의 사용하지 않으므로 생략
29 |
--------------------------------------------------------------------------------
/http/Negotiations.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/http/Negotiations.md
--------------------------------------------------------------------------------
/http/Representation.md:
--------------------------------------------------------------------------------
1 | # 표현 (Representation)
2 |
3 | ## HTTP 표준
4 |
5 | 1999년 RFC2616 <- 폐기됨
6 | 2014년 RFC7230 ~ 7235 등장
7 |
8 | ## RFC723x 변화
9 |
10 | * 엔티티(Entity) -> 표현(Representation)
11 | * Representation = representation MetaData + representation Data
12 | * 표현 = 표현 메타데이터 + 데이터
13 |
14 | ## HTTP BODY
15 | > RFC7230(최신)
16 |
17 |
18 |
19 | * 메시지 본문을 통해 데이터를 전달
20 | * 메시지 본문 = 페이로드(payload)
21 | * 표현은 요청이나 응답에서 전달할 실제 데이터
22 | * 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
23 | * 데이터 유형, 데이터 길이, 압축 정보 등등
24 | * 참고: 표현 헤더는 표현 메타데이터와, 페이로드 메시지를 구분해야 하지만, 여기서는 생략
25 |
26 | ## 표현
27 | * Content-Type: 표현 데이터의 형식
28 | * Content-Encoding: 표현 데이터의 압축 방식
29 | * Content-Language: 표현 데이터의 자연 언어
30 | * Content-Length: 표현 데이터의 길이
31 |
32 | * 표현 헤더는 전송, 응답 둘다 사용
33 |
34 | ## Content-Type
35 | > 표현 데이터의 형식 설명
36 |
37 |
38 |
39 | * 미디어 타입, 문자 인코딩
40 | * 예
41 | * text/html; charset=utf-8
42 | * application/json
43 | * image/png
44 |
45 |
46 | ## Content-Language
47 | > 표현 데이터의 자연 언어
48 |
49 |
50 |
51 | * 표현 데이터의 자연 언어를 표현
52 | * 예
53 | * KO
54 | * EN
55 | * EN-US
56 |
57 | ### 표현 데이터의 우선순위를 설정할 수 있음
58 | > OS언어 기준일 수도 있고..(설정에 따라 상이 함)
59 |
60 |
61 |
62 | 예시 [토스](https://toss.im/) 이렇게 들어가면 Request Header에 language 우선순위를 볼 수 있을 것이다.
63 |
64 | ## Content-Length
65 | > 표현 데이터의 길이
66 |
67 | * 바이트 단위
68 | * Transfer-Encoding(전송 코딩)을 사용하면 Content-Length를
69 |
70 |
71 |
72 | ### [협상(콘텐츠 네고시에이션) 다음화에 계속..](./Negotiations.md)
--------------------------------------------------------------------------------
/http/TCP-UDP.md:
--------------------------------------------------------------------------------
1 | # TCP
2 | > IP 통신의 단점들을 잘 보완해주는 그야말로 대단한 존재이다.
3 |
4 | ## 인터넷 프로토콜 스택의 4계층
5 |
6 |
7 | 여기서 TCP 는 3계층 전송계층에 속한다.
8 |
9 | ## 프로토콜 계층
10 |
11 |
12 | `Hello, world!` 라는 내용을 전달하기 위해서는 위에 과정같은 방법으로 최종적인 목적지에 도착하게 되는데..
13 |
14 | 1. 애플리케이션 단에서 전달 내용을 SOCKET 라이브러리를 통해 전달하고
15 | 2. OS/TCP 단에서 패킷 정보(출발지 PORT, 목적지 PORT, 전송 순서 등을) 감싼다.
16 | 3. IP 단에서 정보 (출발지 PORT, 목적지 PORT 등을)를 감싼 후
17 | 4. 네트워크 인터페이스 단에서 이더넷 프레임을 최종적으로 감싸 도착지에 전달하게 된다.
18 |
19 | 여기서 이제 TCP 의 특징을 명확하게 발견할 수 있는데.
20 |
21 | ## TCP 특징
22 |
23 | * 연결지향 - TCP 3 way handshake (논리적)
24 | * 이 부분은 IP 통신을 할 때의 단점들을 많이 보완을 해주는데 IP 통신에서 일어났던 **패킷 소실, 대상 서비스 불능**을 막아준다.
25 | * 데이터 전달 보증
26 | * 목적지까지 데이터가 전달 됐는지 아닌지 알 수 있다.
27 | * 순서보장
28 | * IP 통신에서는 `Hello` 와 `World`의 두 패킷으로 나누어 보내면 순서를 보장할 수 없었지만, TCP 는 가능하다.
29 |
30 | ### TCP 3 way handshake
31 | > 물리적인 개념이 아니라 논리적인 개념임을 꼭 알고있자.
32 |
33 |
34 |
35 | 1. 클라이언트가 서버에게 연결 요청(SYN)을 하면..
36 | 2. 서버는 응답(ACK)과 동시에 클라이언트와의 연결 요청(SYN)을 보낸다.
37 | 3. 마찬가지로 클라이언트도 응답(ACK)을 한다.
38 |
39 | 요즘에는 업데이트가 돼서 *3번째 과정 +(바로 패킷을 전달) 한다고 함.
40 |
41 | ### 결론적으로
42 | 신뢰할 수 있는 프로토콜이라 현재는 대부분 TCP를 사용한다고 한다.
43 |
44 | ## UDP 특징
45 | > 사용자 데이터그램 프로토콜, 하얀 도화지에 비유(기능이 거의 없다)
46 |
47 | * 연결지향 X
48 | * 데이터 전달 보증 X
49 | * 순서 보장 X, 단순하고 빠르긴 함
50 |
51 | ### 결론적으로
52 | * IP 통신과 거의 같지만, +PORT와 +체크섬 정도만 추가
53 | * 애플리케이션에서 추가 작업이 요구된다.
54 |
55 |
56 | ### [다음편에서 계속..](./port.md)
--------------------------------------------------------------------------------
/http/http-header-intro.md:
--------------------------------------------------------------------------------
1 | # HTTP 헤더 개요
2 | > HTTP 헤더는 클라이언트와 서버가 요청 또는 응답으로 부가적인 정보를 전송할 수 있도록 해준다.
3 |
4 |
5 | ## HTTP 헤더
6 |
7 |
8 |
9 | ## HTTP 헤더의 용도
10 |
11 |
12 |
13 | * HTTP 전송에 필요한 모든 부가정보
14 | * 메시지 바디의 내용, 메시지 바디의 크기, 인증, 요청 클라이언트, 서버 정도 등등
15 | * 표준 헤더가 너무 많음
16 | * [세부적인 내용은 여기를 참고하세요](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields)
17 |
18 | ## HTTP - RFC2616 과거
19 |
20 |
21 |
22 | * 헤더 분류
23 | * General 헤더: 메시지 전체에 적용되는 정보 ex) Connection: close
24 | * Request 헤더: 요청 정보 ex) User-Agent: Mozilla/5.0 (Macintosh;)
25 | * Response 헤더: 응답 정보 ex) Server: cloudflare [우하한형제들]
26 | * Entity 헤더: 엔티티 바디 정보 ex) Content-Type: text/html, Content-Length: 2342
27 |
28 |
29 | ### HTTP BODY
30 |
31 |
32 |
33 | * 메시지 본문은 엔티티 본문을 전달하는데 사용
34 | * 엔티티 본문은 요청이나 응답에서 전달할 실제 데이터
35 | * 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보 제공
36 | * 데이터 유형 (html, json) 데이터 길이, 압축 정보 등등
37 |
38 |
39 | ### [RFC7230~7235 다음화에 계속..](./Representation.md)
--------------------------------------------------------------------------------
/http/http-method-use.md:
--------------------------------------------------------------------------------
1 | # HTTP 메서드 활용
2 | * 클라이언트에서 서버로 데이터 전송
3 | * HTTP API 설계 예시
4 |
5 | ## 클라이언트에서 서버로 데이터 전송
6 |
7 | ### 데이터 전달 방식은 크게 2가지
8 |
9 | * 쿼리 파라미터를 통한 데이터 전송
10 | * GET
11 | * 주로 정렬 필터(검색어)
12 | * 메시지 바디를 통한 데이터 전송
13 | * POST, PUT, PATCH
14 | * 회원가입, 상품 주문, 리소스 등록, 리소스 변경
15 |
16 | ### 4가지의 상황
17 | * 정적 데이터 조회
18 | * 이미지, 정적 텍스트 문서
19 | * 동적 데이터 조회
20 | * 주로 검색, 게시판 목록에서 정렬 필터(검색어)
21 | * HTML Form 을 통한 데이터 전송
22 | * 회원가입, 상품주문, 데이터변경
23 | * HTTP API를 통한 상품 데이터 전송
24 | * 회원가입, 상품주문, 데이터변경
25 | * 서버to서버, 앱 클라이언트, 웹 클라이언트(Ajax)
26 |
27 | ## 정적 데이터 조회
28 |
29 | - 쿼리 파라미터 미사용
30 |
31 |
32 |
33 | > 이미지, 정적 텍스트 문서
34 | > 조회는 GET 사용
35 | > 정적 데이터는 일반적으로 쿼리 파라미터 없이 리소스 경로로 단순하게 조회 가능
36 |
37 | ## 동적 데이터 조회
38 |
39 | - 쿼리 파라미터 사용
40 |
41 |
42 |
43 | > 주로 검색, 게시판 목록에서 정렬 필터
44 | > 조회 조건을 줄여주는 필터, 조회 결과를 정렬하는 정렬 조건에 주로 사용
45 | > 조회는 GET 사용
46 | > GET은 쿼리 파라미터 사용해서 데이터 전달
47 |
48 | ## HTML Form 데이터 전송
49 |
50 | HTML Form 은 HTTP Method 가 `POST, GET` 만 지원된다.
51 |
52 | ### POST 전송 - 저장 요청
53 |
54 |
55 |
56 | 특이하게 웹 브라우저가 생성한 요청을 보면 마치 GET 욫청의 쿼리 파라미터 처럼 `key=value` 사이에 `&` 기호로 메시지가 본문에서 생성된 것을 볼 수 있다.
57 |
58 | ### GET 전송 - 조회 요청
59 |
60 |
61 |
62 |
63 | **또한 HTML Form `GET`은 조회에서만 사용해야 한다. 리소스 변경이 발생하는 곳에 사용하면 안된다.**
64 |
65 | ## 정리
66 |
67 | 참고하면 좋은 URI 설계 개념
68 |
69 | * 문서
70 | * 단일 개념 (파일 하나, 객체 인스턴스, 데이터베이스 row)
71 | * ex) `/members/100`, `/files/{filename}`
72 | * 컬렉션
73 | * 서버가 관리하는 리소스 데릭터리
74 | * 서버가 리소스의 URI를 생성하고 관리
75 | * ex) `/members`
76 | * 스토어
77 | * 클라이언트가 관리하는 자원 저장소
78 | * 클라이언트가 리소스 URI를 알고 관리
79 | * ex) `files`
80 | * 컨트롤러, 컨트롤 URI
81 | * 문서, 컬렉션, 스토어로 해결하기 어려운 프로세스를 실행
82 | * 동사를 직접 사용
83 | * ex) `/members/{id}/delete`
--------------------------------------------------------------------------------
/http/internet-network.md:
--------------------------------------------------------------------------------
1 | # 인터넷 통신
2 |
3 | ## 인터넷 네트워크 목차
4 | * 인터넷 통신
5 | * IP (Internet Protocol)
6 | * TCP, UDP
7 | * PORT
8 | * DNS
9 |
10 | ## 인터넷 통신
11 |
12 | ### 인터넷에서 컴퓨터 둘은 어떻게 통신할까?
13 |
14 |
15 | ### 복잡한 인터넷 망
16 | > 복잡한 인터넷 망에서 도대체 어떻게 통신하는지 앞으로 하나하나 알아볼 예정이다.
17 |
18 |
--------------------------------------------------------------------------------
/http/ip.md:
--------------------------------------------------------------------------------
1 | # IP(인터넷 프로토콜)
2 |
3 |
4 | 위에 이미지 처럼 클라이언트와 서버는 고유한 ip 주소를 가지고 있다.
5 | 만약 클라이언트(100.100.100.1)에서 서버(200.200.200.2)로 어떠한 요청을 보내고자 할 때. IP(인터넷 프로토콜)에서는 패킷(Packet)이라는 통신 단위로 전달한다.
6 |
7 | ### 패킷(Packet)은 아래 그림과 같이 구성되어 있다.
8 |
9 |
10 |
11 | ## 클라이언트의 패킷 전달
12 | > 앞서 말했던 가설, 클라이언트가 서버에 패킷을 보낼 때 어떻게 전달 될까?
13 |
14 |
15 |
16 | 위에 그림처럼 수많은 노드를 걸쳐 전달되게 된다.
17 |
18 | 만약, 패킷에 실어 보낼 전송 데이터가 크다면 어떻게 처리할까?
19 | 패킷을 여러개로 나눠 전달한다. __나중에 언급하겠지만,__ 이 부분에서 **IP통신의 단점**이 발생한다.
20 |
21 | ## 서버의 패킷 전달
22 | > 클라이언트가 서버에게 패킷을 보냈다면 응답을 해야겠죠? 여기서 서버는 어떻게 응답하냐면요..
23 |
24 |
25 |
26 | 방법은 클라이언트와 다를 바 없다.
27 | **하지만, 서버의 응답 패킷 전달과정의 노드 경로와 클라이언트의 요청 패킷 전달 노드의 경로와 같지 않음을 알고 있자.**
28 |
29 | ## IP 프로토콜의 한계
30 | * 비연결성
31 | * 패킷을 받을 대상이 없거나 불능(전원이 꺼져 있다 등) 상태여도 패킷을 전송한다.
32 | * 비신뢰성
33 | * 중간에 패킷이 사라지면?? (응 패킷이 소실될 수 있다.)
34 | * 인터넷 망 노드의 문제가 생겨서 중간의 패킷 소실의 위험이 있다.
35 | * 패킷이 순서대로 안오면?? (응 순서대로 간다는 보장이 없다.)
36 | * 앞서 언급했듯 패킷에 담을 정보의 용량이 크면 패킷을 적절하게 나누어 전달하는 특징이 있는데, 내가 A 보내고 B 보낸다고 해서 목적지에 A 다음 B가 전달 된다는 보장이 없다는 것이다.
37 | * 프로그램 구분
38 | * 같은 IP를 사용하는 서버에서 통신하는 애플리케이션이 둘 이상이면?
39 |
40 |
41 |
42 | ### 다음편에서 계속..
--------------------------------------------------------------------------------
/http/port.md:
--------------------------------------------------------------------------------
1 | # PORT - 포트
2 | > 포트는 개발하면서 많이 보았을 것이다.
3 |
4 | ## 들어가기
5 |
6 |
7 | 이렇게 한번에 둘 이상을 연결해야 할 때 포트를 써야 한다.
8 | 앞서 [TCP&UDP](./TCP-UDP.md) 편에서도 언급했지만, TCP/IP 패킷은 아래와 같이 이루어져 있는데..
9 |
10 |
11 |
12 | 이렇게 ip + `출발지 포트`와 `목적지 포트` 정보를 실어 요청하면,
13 | 브라우저 같은 경우에는 요청에 대해 결과 값을 만들어 요청한 ip의 `출발지 포트`에 정확하게 꽂아주게 된다.
14 |
15 | IP는 아파트 (동) 이라고 하면 PORT는 아파트 (호) 라고 생각하면 쉽다.
16 |
17 | ## PORT
18 | * 0~65535: 할당 가능한 영역
19 | * 0~1023: 잘 알려진 포트, 사용하지 않는 것이 좋다
20 | * 20, 21: FTP
21 | * 23: TELNET
22 | * 80: HTTP
23 | * 443: HTTPS
24 |
25 | ### [다음편에서 계속..](./DNS.md)
--------------------------------------------------------------------------------
/http/web-browser-flow.md:
--------------------------------------------------------------------------------
1 | # 웹 브라우저 요청 흐름
2 | > 웹 브라우저 요청 흐름을 이해시키기 위해 앞전에 인터넷 네트워크에 대해 정리했던 것이다.
3 |
4 | ## 들어가기
5 |
6 | ### 아래와 같이 내가 원하는 url 을 웹 브라우저에 입력하면...
7 |
8 |
9 |
10 | 1. 우선 DNS를 조회와 동시에 생략된 포트를 알아챈다.
11 | 2. 이 때 HTTP 요청 메시지가 생성된다
12 |
13 | 대략 생성된 HTTP 메시지는 아래와 같다.
14 |
15 |
16 |
17 | ### 이렇게 생성된 HTTP 메시지는 구글 서버에 어떻게 전달 될까?
18 |
19 |
20 |
21 | 위에 사진은 [TCP-UDP](./TCP-UDP.md) 개념에 나왔던 것과 같죠?
22 | 웹 브라우져 요청 흐름을 설명하기 위해 앞전에 인터넷 네트워크에 대해 설명했었습니다.
23 |
24 | 1. client 브라우저에서 생성된 요청 HTTP 메시지를
25 | 2. 소켓 라이브러리를 통해 IP/PORT 데이터를 담아 전달한다.
26 | 3. TCP/IP 딴에서 HTTP 메시지를 포함한 TCP/IP 패킷을 생성하여 인테넷 망으로 던진다.
27 |
28 | TCP/IP에서 생성된 HTTP 메시지를 포함한 패킷은 이처럼 생겼다.
29 |
30 |
31 |
32 | ### 전달하기
33 |
34 |
35 |
36 | 구글 서버에 안전하게 전달됐다.
37 | 안전하게!! 안전하게 전달 되지 않았다면 그 또한 클라이언트는 알 수 있을 것이다.
38 | 이유는 !! TCP/IP 통신을 했기 때문이다! 잊지 않았죠?
39 |
40 | ### 응답하기
41 | **HTTP 요청 메시지**를 포함한 패킷을 받은 구글 서버는 그에 맞는 **HTTP 응답 메시지**를 생성한다.
42 |
43 |
44 |
45 | HTTP 응답 패킷을 요청 패킷 정보(출발지 IP, PORT)를 통해 전달하게 된다.
46 |
47 |
48 |
49 | 그 응답 패킷을 클라이언트의 웹 브라우져를 통해 렌더링 하게 되고, 곧 클라이언트 화면에 결과가 깔끔하게 노출되게 된다.
50 |
51 | ### URI 부터 웹 브라우저 요청 흐름 챕터 끝..
--------------------------------------------------------------------------------
/http/재영-질문-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/http/재영-질문-1.png
--------------------------------------------------------------------------------
/img/ACM_Certification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/ACM_Certification.png
--------------------------------------------------------------------------------
/img/ApplicationLoadBanlancer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/ApplicationLoadBanlancer.png
--------------------------------------------------------------------------------
/img/BiFunction-apply-ab-method.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/BiFunction-apply-ab-method.png
--------------------------------------------------------------------------------
/img/CGLIB-keep-singleton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/CGLIB-keep-singleton.png
--------------------------------------------------------------------------------
/img/DI-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/DI-interface.png
--------------------------------------------------------------------------------
/img/DI-st.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/DI-st.jpg
--------------------------------------------------------------------------------
/img/ELB-error-solved.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/ELB-error-solved.png
--------------------------------------------------------------------------------
/img/FI-lecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/FI-lecture.png
--------------------------------------------------------------------------------
/img/Functional-Interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Functional-Interface.png
--------------------------------------------------------------------------------
/img/GoF-Design.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/GoF-Design.png
--------------------------------------------------------------------------------
/img/HttpServlet-동작과정.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/HttpServlet-동작과정.png
--------------------------------------------------------------------------------
/img/Iaas,SaaS,PaaS_구분.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Iaas,SaaS,PaaS_구분.png
--------------------------------------------------------------------------------
/img/JIT-todo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JIT-todo.png
--------------------------------------------------------------------------------
/img/JPA-JDBC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JPA-JDBC.png
--------------------------------------------------------------------------------
/img/JPA-history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JPA-history.png
--------------------------------------------------------------------------------
/img/JVM-Heap.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JVM-Heap.jpeg
--------------------------------------------------------------------------------
/img/JVM-JRE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JVM-JRE.png
--------------------------------------------------------------------------------
/img/JVM-structure.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JVM-structure.jpg
--------------------------------------------------------------------------------
/img/Java-memory-management.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Java-memory-management.png
--------------------------------------------------------------------------------
/img/JavaEE-servlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/JavaEE-servlet.png
--------------------------------------------------------------------------------
/img/LB-Create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/LB-Create.png
--------------------------------------------------------------------------------
/img/LB-setting1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/LB-setting1.png
--------------------------------------------------------------------------------
/img/ModelMapperCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/ModelMapperCode.png
--------------------------------------------------------------------------------
/img/ModelMapperRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/ModelMapperRes.png
--------------------------------------------------------------------------------
/img/N+1-entity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/N+1-entity.png
--------------------------------------------------------------------------------
/img/NotChangeCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/NotChangeCode.png
--------------------------------------------------------------------------------
/img/OCP-find.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/OCP-find.png
--------------------------------------------------------------------------------
/img/OWASP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/OWASP.png
--------------------------------------------------------------------------------
/img/Obejct-hashCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Obejct-hashCode.png
--------------------------------------------------------------------------------
/img/PCB-TCB.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/PCB-TCB.jpeg
--------------------------------------------------------------------------------
/img/PSA-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/PSA-diagram.png
--------------------------------------------------------------------------------
/img/RDS-fatal-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/RDS-fatal-error.png
--------------------------------------------------------------------------------
/img/SOA-concept.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/SOA-concept.png
--------------------------------------------------------------------------------
/img/SOF-cbv-cbr-my-think.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/SOF-cbv-cbr-my-think.png
--------------------------------------------------------------------------------
/img/Serialization-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Serialization-example.png
--------------------------------------------------------------------------------
/img/Spring-rest-docs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Spring-rest-docs.png
--------------------------------------------------------------------------------
/img/Thread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/Thread.png
--------------------------------------------------------------------------------
/img/TooManyRedirection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/TooManyRedirection.png
--------------------------------------------------------------------------------
/img/abstract-method-java-docs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/abstract-method-java-docs.png
--------------------------------------------------------------------------------
/img/add-source-folders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/add-source-folders.png
--------------------------------------------------------------------------------
/img/answer-uncomfortable-table-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/answer-uncomfortable-table-diagram.png
--------------------------------------------------------------------------------
/img/application-context-structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/application-context-structure.png
--------------------------------------------------------------------------------
/img/application-context.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/application-context.jpg
--------------------------------------------------------------------------------
/img/arr-deep-copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/arr-deep-copy.png
--------------------------------------------------------------------------------
/img/arr-foreach-java8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/arr-foreach-java8.png
--------------------------------------------------------------------------------
/img/arrayList-bigO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/arrayList-bigO.png
--------------------------------------------------------------------------------
/img/async-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/async-console.png
--------------------------------------------------------------------------------
/img/async-processing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/async-processing.png
--------------------------------------------------------------------------------
/img/async_ex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/async_ex.png
--------------------------------------------------------------------------------
/img/authentication-jwt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/authentication-jwt.png
--------------------------------------------------------------------------------
/img/aws_route53_enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/aws_route53_enter.png
--------------------------------------------------------------------------------
/img/base64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/base64.png
--------------------------------------------------------------------------------
/img/basic-DI-success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/basic-DI-success.png
--------------------------------------------------------------------------------
/img/big-O-complexity-chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/big-O-complexity-chart.png
--------------------------------------------------------------------------------
/img/blocking-ex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/blocking-ex.png
--------------------------------------------------------------------------------
/img/blocking-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/blocking-process.png
--------------------------------------------------------------------------------
/img/bootstrap-classLoader-why-null.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/bootstrap-classLoader-why-null.png
--------------------------------------------------------------------------------
/img/bubble-sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/bubble-sort.png
--------------------------------------------------------------------------------
/img/builder-cannot-hide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/builder-cannot-hide.png
--------------------------------------------------------------------------------
/img/cache.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/cache.png
--------------------------------------------------------------------------------
/img/can't return 2 result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/can't return 2 result.png
--------------------------------------------------------------------------------
/img/cause-bean-no-qualifying.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/cause-bean-no-qualifying.png
--------------------------------------------------------------------------------
/img/class-reflection-options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/class-reflection-options.png
--------------------------------------------------------------------------------
/img/classLoader-parent-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/classLoader-parent-console.png
--------------------------------------------------------------------------------
/img/classLoader-system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/classLoader-system.png
--------------------------------------------------------------------------------
/img/comparable-compareTo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/comparable-compareTo.png
--------------------------------------------------------------------------------
/img/completable-console-uppercase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/completable-console-uppercase.png
--------------------------------------------------------------------------------
/img/completableFuture-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/completableFuture-console.png
--------------------------------------------------------------------------------
/img/container-magic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/container-magic.png
--------------------------------------------------------------------------------
/img/csrf-attack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/csrf-attack.jpg
--------------------------------------------------------------------------------
/img/daangn-company.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/daangn-company.png
--------------------------------------------------------------------------------
/img/db-engines-ranking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/db-engines-ranking.png
--------------------------------------------------------------------------------
/img/db-예약어-주의.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/db-예약어-주의.png
--------------------------------------------------------------------------------
/img/dispatcher-servlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/dispatcher-servlet.png
--------------------------------------------------------------------------------
/img/dispatcherServlet-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/dispatcherServlet-diagram.png
--------------------------------------------------------------------------------
/img/docker-compose-cache-clear-search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/docker-compose-cache-clear-search.png
--------------------------------------------------------------------------------
/img/docker-resource-limit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/docker-resource-limit.png
--------------------------------------------------------------------------------
/img/drop-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/drop-table.png
--------------------------------------------------------------------------------
/img/em-1st-chache.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/em-1st-chache.png
--------------------------------------------------------------------------------
/img/em-find-logic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/em-find-logic.png
--------------------------------------------------------------------------------
/img/empty-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/empty-console.png
--------------------------------------------------------------------------------
/img/error-ddl-auto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/error-ddl-auto.png
--------------------------------------------------------------------------------
/img/front-controller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/front-controller.png
--------------------------------------------------------------------------------
/img/gabege-collector.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/gabege-collector.gif
--------------------------------------------------------------------------------
/img/generic-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/generic-console.png
--------------------------------------------------------------------------------
/img/generic-type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/generic-type.png
--------------------------------------------------------------------------------
/img/getBeanTypeMoreThanTwo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/getBeanTypeMoreThanTwo.png
--------------------------------------------------------------------------------
/img/getConnection-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/getConnection-flow.png
--------------------------------------------------------------------------------
/img/getFields.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/getFields.png
--------------------------------------------------------------------------------
/img/goodbye.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/goodbye.jpeg
--------------------------------------------------------------------------------
/img/h2DB_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/h2DB_down.png
--------------------------------------------------------------------------------
/img/has-a-method-two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/has-a-method-two.png
--------------------------------------------------------------------------------
/img/has-a-method.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/has-a-method.png
--------------------------------------------------------------------------------
/img/hashcode-return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/hashcode-return.png
--------------------------------------------------------------------------------
/img/hashicrop-vault.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/hashicrop-vault.png
--------------------------------------------------------------------------------
/img/hate-modelmapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/hate-modelmapper.png
--------------------------------------------------------------------------------
/img/hbm2ddl-auto-resolved.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/hbm2ddl-auto-resolved.png
--------------------------------------------------------------------------------
/img/hibernate-nullable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/hibernate-nullable.png
--------------------------------------------------------------------------------
/img/hikari-error-solution.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/hikari-error-solution.png
--------------------------------------------------------------------------------
/img/http/201-created.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/201-created.png
--------------------------------------------------------------------------------
/img/http/301-영구-리다이렉션.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/301-영구-리다이렉션.png
--------------------------------------------------------------------------------
/img/http/302-리다이렉트의-좋은-예.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/302-리다이렉트의-좋은-예.png
--------------------------------------------------------------------------------
/img/http/308-영구-리다이렉션.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/308-영구-리다이렉션.png
--------------------------------------------------------------------------------
/img/http/API-URI-설계-어떻게-구분하지.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/API-URI-설계-어떻게-구분하지.png
--------------------------------------------------------------------------------
/img/http/DNS의-사용.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/DNS의-사용.png
--------------------------------------------------------------------------------
/img/http/F5-야매.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/F5-야매.png
--------------------------------------------------------------------------------
/img/http/HTML-Form-POST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTML-Form-POST.png
--------------------------------------------------------------------------------
/img/http/HTML-GET-조회.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTML-GET-조회.png
--------------------------------------------------------------------------------
/img/http/HTTP-GET-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-GET-flow.png
--------------------------------------------------------------------------------
/img/http/HTTP-GET.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-GET.png
--------------------------------------------------------------------------------
/img/http/HTTP-POST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-POST.png
--------------------------------------------------------------------------------
/img/http/HTTP-메시지-전송.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-메시지-전송.png
--------------------------------------------------------------------------------
/img/http/HTTP-메시지.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-메시지.png
--------------------------------------------------------------------------------
/img/http/HTTP-응답-메시지.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-응답-메시지.png
--------------------------------------------------------------------------------
/img/http/HTTP-패킷-생성.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/HTTP-패킷-생성.png
--------------------------------------------------------------------------------
/img/http/IP-주소부여.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/IP-주소부여.png
--------------------------------------------------------------------------------
/img/http/PATCH-without-feild.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/PATCH-without-feild.png
--------------------------------------------------------------------------------
/img/http/PUT-HTTP-message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/PUT-HTTP-message.png
--------------------------------------------------------------------------------
/img/http/PUT-method-with-resource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/PUT-method-with-resource.png
--------------------------------------------------------------------------------
/img/http/PUT-method-without-feild.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/PUT-method-without-feild.png
--------------------------------------------------------------------------------
/img/http/PUT-method-without-resource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/PUT-method-without-resource.png
--------------------------------------------------------------------------------
/img/http/TCP-3-way-handshake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/TCP-3-way-handshake.png
--------------------------------------------------------------------------------
/img/http/TCP-UDP-패킷-정보.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/TCP-UDP-패킷-정보.png
--------------------------------------------------------------------------------
/img/http/URI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/URI.png
--------------------------------------------------------------------------------
/img/http/URL-URN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/URL-URN.png
--------------------------------------------------------------------------------
/img/http/accept-lang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/accept-lang.png
--------------------------------------------------------------------------------
/img/http/auto-redirection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/auto-redirection.png
--------------------------------------------------------------------------------
/img/http/content-language.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/content-language.png
--------------------------------------------------------------------------------
/img/http/content-type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/content-type.png
--------------------------------------------------------------------------------
/img/http/http-attribute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/http-attribute.png
--------------------------------------------------------------------------------
/img/http/http-body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/http-body.png
--------------------------------------------------------------------------------
/img/http/http-header-short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/http-header-short.png
--------------------------------------------------------------------------------
/img/http/http-header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/http-header.png
--------------------------------------------------------------------------------
/img/http/post-정리.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/post-정리.png
--------------------------------------------------------------------------------
/img/http/rfc-2616.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/rfc-2616.png
--------------------------------------------------------------------------------
/img/http/rfc-7230-http-body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/rfc-7230-http-body.png
--------------------------------------------------------------------------------
/img/http/socket-TCP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/socket-TCP.png
--------------------------------------------------------------------------------
/img/http/stackoverflow-ex1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/stackoverflow-ex1.png
--------------------------------------------------------------------------------
/img/http/stateful-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/stateful-server.png
--------------------------------------------------------------------------------
/img/http/stateless-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/stateless-error.png
--------------------------------------------------------------------------------
/img/http/static-data-get.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/static-data-get.png
--------------------------------------------------------------------------------
/img/http/구글에게-패킷-전달.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/구글에게-패킷-전달.png
--------------------------------------------------------------------------------
/img/http/리다이렉션-실무-권장-사양.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/리다이렉션-실무-권장-사양.png
--------------------------------------------------------------------------------
/img/http/복잡한-인터넷망.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/복잡한-인터넷망.png
--------------------------------------------------------------------------------
/img/http/서버-패킷-전달.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/서버-패킷-전달.png
--------------------------------------------------------------------------------
/img/http/아이피는-기억하기-어렵다.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/아이피는-기억하기-어렵다.png
--------------------------------------------------------------------------------
/img/http/웹브라우져-url-파싱.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/웹브라우져-url-파싱.png
--------------------------------------------------------------------------------
/img/http/응답-HTTP-패킷.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/응답-HTTP-패킷.png
--------------------------------------------------------------------------------
/img/http/인터넷-통신-궁금증.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/인터넷-통신-궁금증.png
--------------------------------------------------------------------------------
/img/http/인터넷-프로토콜-계층.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/인터넷-프로토콜-계층.png
--------------------------------------------------------------------------------
/img/http/인터넷-프로토콜-스택-4계층.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/인터넷-프로토콜-스택-4계층.png
--------------------------------------------------------------------------------
/img/http/쿼리파라미터사용-동적데이터조회.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/쿼리파라미터사용-동적데이터조회.png
--------------------------------------------------------------------------------
/img/http/클라이언트-패킷-전달.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/클라이언트-패킷-전달.png
--------------------------------------------------------------------------------
/img/http/패킷-구조.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/패킷-구조.png
--------------------------------------------------------------------------------
/img/http/한번에-둘-이상-연결해야-하면.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/http/한번에-둘-이상-연결해야-하면.png
--------------------------------------------------------------------------------
/img/insertion-sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/insertion-sort.png
--------------------------------------------------------------------------------
/img/interface-member-constraint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/interface-member-constraint.png
--------------------------------------------------------------------------------
/img/invokeAll-api-docs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/invokeAll-api-docs.png
--------------------------------------------------------------------------------
/img/java-checked-unchecked-exceptions-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/java-checked-unchecked-exceptions-2.png
--------------------------------------------------------------------------------
/img/java-checked-unchecked-exceptions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/java-checked-unchecked-exceptions.png
--------------------------------------------------------------------------------
/img/java-default-functional-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/java-default-functional-interface.png
--------------------------------------------------------------------------------
/img/java-runTime-area.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/java-runTime-area.png
--------------------------------------------------------------------------------
/img/java-runtime-area-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/java-runtime-area-st.png
--------------------------------------------------------------------------------
/img/jcf-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/jcf-st.png
--------------------------------------------------------------------------------
/img/jpa-column-wrapper-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/jpa-column-wrapper-console.png
--------------------------------------------------------------------------------
/img/jpa-persistence-API.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/jpa-persistence-API.png
--------------------------------------------------------------------------------
/img/jvm-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/jvm-st.png
--------------------------------------------------------------------------------
/img/jwt-dependency-duplicate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/jwt-dependency-duplicate.png
--------------------------------------------------------------------------------
/img/logtail.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/logtail.jpeg
--------------------------------------------------------------------------------
/img/managed-context-life-cycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/managed-context-life-cycle.png
--------------------------------------------------------------------------------
/img/mixed-scope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/mixed-scope.png
--------------------------------------------------------------------------------
/img/modelMapper-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/modelMapper-result.png
--------------------------------------------------------------------------------
/img/monolithic-microservice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/monolithic-microservice.png
--------------------------------------------------------------------------------
/img/multi-thread.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/multi-thread.jpg
--------------------------------------------------------------------------------
/img/newSingleThreadExecutorEx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/newSingleThreadExecutorEx.png
--------------------------------------------------------------------------------
/img/node-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/node-tree.png
--------------------------------------------------------------------------------
/img/node-update-need.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/node-update-need.png
--------------------------------------------------------------------------------
/img/non-blocking-callback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/non-blocking-callback.png
--------------------------------------------------------------------------------
/img/non-blocking-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/non-blocking-process.png
--------------------------------------------------------------------------------
/img/not-spring-container-warn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/not-spring-container-warn.png
--------------------------------------------------------------------------------
/img/notLiteral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/notLiteral.png
--------------------------------------------------------------------------------
/img/oauth-data-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/oauth-data-flow.png
--------------------------------------------------------------------------------
/img/parallelStream-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/parallelStream-console.png
--------------------------------------------------------------------------------
/img/pass-array-pointer-value.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/pass-array-pointer-value.png
--------------------------------------------------------------------------------
/img/point-thesame-heap-memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/point-thesame-heap-memory.png
--------------------------------------------------------------------------------
/img/primitive-reference-type-heap-memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/primitive-reference-type-heap-memory.png
--------------------------------------------------------------------------------
/img/project-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/project-st.png
--------------------------------------------------------------------------------
/img/prototype-bean-life-cycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/prototype-bean-life-cycle.png
--------------------------------------------------------------------------------
/img/proxy-mode-in-transactional.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/proxy-mode-in-transactional.png
--------------------------------------------------------------------------------
/img/puppeteer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/puppeteer.png
--------------------------------------------------------------------------------
/img/query-per-entity-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/query-per-entity-diagram.png
--------------------------------------------------------------------------------
/img/querydsl-file-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/querydsl-file-st.png
--------------------------------------------------------------------------------
/img/rds-error-method.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/rds-error-method.png
--------------------------------------------------------------------------------
/img/rds-security.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/rds-security.png
--------------------------------------------------------------------------------
/img/recode_create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/recode_create.png
--------------------------------------------------------------------------------
/img/reflection-정리.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/reflection-정리.png
--------------------------------------------------------------------------------
/img/route53_nameServer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/route53_nameServer.png
--------------------------------------------------------------------------------
/img/routing_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/routing_setting.png
--------------------------------------------------------------------------------
/img/search-reason-why.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/search-reason-why.png
--------------------------------------------------------------------------------
/img/security-group-setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/security-group-setting.png
--------------------------------------------------------------------------------
/img/security-mysql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/security-mysql.png
--------------------------------------------------------------------------------
/img/selection-sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/selection-sort.png
--------------------------------------------------------------------------------
/img/serial-collector.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/serial-collector.jpeg
--------------------------------------------------------------------------------
/img/serialization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/serialization.png
--------------------------------------------------------------------------------
/img/servlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/servlet.png
--------------------------------------------------------------------------------
/img/should-to-make-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/should-to-make-interface.png
--------------------------------------------------------------------------------
/img/singleton-bean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/singleton-bean.png
--------------------------------------------------------------------------------
/img/singleton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/singleton.png
--------------------------------------------------------------------------------
/img/socar-myResult-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/socar-myResult-console.png
--------------------------------------------------------------------------------
/img/sof-ref-is-ref.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/sof-ref-is-ref.png
--------------------------------------------------------------------------------
/img/solved 1 result return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/solved 1 result return.png
--------------------------------------------------------------------------------
/img/sorting-algorithms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/sorting-algorithms.png
--------------------------------------------------------------------------------
/img/spring-mvc-dispatcherServlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/spring-mvc-dispatcherServlet.png
--------------------------------------------------------------------------------
/img/spring-mvc-lifecycle-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/spring-mvc-lifecycle-st.png
--------------------------------------------------------------------------------
/img/ssl-setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/ssl-setting.png
--------------------------------------------------------------------------------
/img/static-dynamic-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/static-dynamic-page.png
--------------------------------------------------------------------------------
/img/static-method-in-oracle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/static-method-in-oracle.png
--------------------------------------------------------------------------------
/img/strategy-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/strategy-example.png
--------------------------------------------------------------------------------
/img/strategy-pattern-structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/strategy-pattern-structure.png
--------------------------------------------------------------------------------
/img/stream-lazy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/stream-lazy.png
--------------------------------------------------------------------------------
/img/stream-worked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/stream-worked.png
--------------------------------------------------------------------------------
/img/stream-동작방식.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/stream-동작방식.png
--------------------------------------------------------------------------------
/img/sub-super-class.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/sub-super-class.png
--------------------------------------------------------------------------------
/img/submit-cancle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/submit-cancle.png
--------------------------------------------------------------------------------
/img/sync-processing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/sync-processing.png
--------------------------------------------------------------------------------
/img/sync_ex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/sync_ex.png
--------------------------------------------------------------------------------
/img/target-adding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/target-adding.png
--------------------------------------------------------------------------------
/img/target-sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/target-sort.png
--------------------------------------------------------------------------------
/img/template_pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/template_pattern.png
--------------------------------------------------------------------------------
/img/thread-currentThread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/thread-currentThread.png
--------------------------------------------------------------------------------
/img/thread-group.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/thread-group.gif
--------------------------------------------------------------------------------
/img/thread-native.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/thread-native.png
--------------------------------------------------------------------------------
/img/thread-runnable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/thread-runnable.png
--------------------------------------------------------------------------------
/img/thread-wake-3seconds-after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/thread-wake-3seconds-after.png
--------------------------------------------------------------------------------
/img/time-complexity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/time-complexity.png
--------------------------------------------------------------------------------
/img/transactional-based-aop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/transactional-based-aop.png
--------------------------------------------------------------------------------
/img/tryAdvance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/tryAdvance.png
--------------------------------------------------------------------------------
/img/vault-secret-backends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/vault-secret-backends.png
--------------------------------------------------------------------------------
/img/vault-storage-backends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/vault-storage-backends.png
--------------------------------------------------------------------------------
/img/webpack-error-module-not-found.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/webpack-error-module-not-found.png
--------------------------------------------------------------------------------
/img/wrapper-class-boxing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/wrapper-class-boxing.png
--------------------------------------------------------------------------------
/img/wrapper-class-st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/wrapper-class-st.png
--------------------------------------------------------------------------------
/img/wrapper-console-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/wrapper-console-result.png
--------------------------------------------------------------------------------
/img/wtf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/wtf.jpg
--------------------------------------------------------------------------------
/img/결합도.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/결합도.png
--------------------------------------------------------------------------------
/img/결합도가_높다.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/결합도가_높다.png
--------------------------------------------------------------------------------
/img/응집도.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/응집도.png
--------------------------------------------------------------------------------
/img/응집도가_높음.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/응집도가_높음.png
--------------------------------------------------------------------------------
/img/응집도가_약함.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/img/응집도가_약함.png
--------------------------------------------------------------------------------
/organization/Agile.md:
--------------------------------------------------------------------------------
1 | # 애자일 조직문화
2 | ## 👩🏻🎓 Agile Culture Making
3 | ### Agile 조직문화란?
4 |
5 | 기민한, 민첩한 이라는 의미로 사무환경에서는 **부서 간 경계를 허물고 팀원에게 의사 결정 권한을 부여해 신속한 업무**를 진행하는 방식을 뜻한다.
6 |
7 | ### Agile의 등장배경
8 | Agile은 본래 Software Developer 들이 Plan-Do-See 라는 관리 절차에 충실하게 프로젝트를 수행했지만, 고객사의 빈번한 수정요청 작업과 더불어 버그 하나를 잡기 위해서 결재를 기다려야 하는 현실 속에서 **"민첩하고 반응하고 신속하게 대응한다', '결재를 기다리지 않고도 현장 실무자가 프로토타입을 던져놓고 시행착오 방식으로 진행한다'** 라는 발상으로 시작됐다.
9 |
10 | ### Agile 경영방식의 중요성
11 | 어떻게 변화할지 모르는 **업계 트렌드나 경제흐름, 정치적 이슈 등 불확실한 미래에 발 빠르게 대응 할 수 있는 전략**이 필요하기 때문입니다.
12 |
13 | ### Agile 경영방식
14 | **1. 경계 없는 조직문화**
15 | > 애자일 조직을 형성하기 위한 첫걸음은 바로 **구성원들 간의 경계를 허무는** 것입니다.
16 | > 가까운 동료뿐만 아니라 자주 마주치기 어려운 직원들과도 **원활한 소통이 가능한 환경**을 마련해야 하는데요.
17 | >이러한 환경을 실현하기 위해서는 사내 동호회, 워크숍 등을 마련해 구성원들이 자연스럽게 만날 수 있도록 **활발한 의사소통의 장**을 마련해야 합니다.
18 |
19 | **2. 업무 마감 기한 설정**
20 | > 애자일 조직의 특징 중 하나는 **명확한 마감 시한을 갖는 것**입니다.
21 | > 빠른 대응력이 필요한 애자일조직은 상황이 어떻게 바뀔지 모르는 것에 대비하기 위해 제한된 시간을 두고 그 안에 무엇이든 만들어 내도록 독려한다고 합니다.
22 | > 구체적인 마감 기간은 평균적으로 프로젝트당 2주간의 데드라인으로 둔다고 합니다.
23 | > 업무 특성에 따라 기한이 달라질 수 있지만 **아무리 길어도 1개월을 넘기지 않는** 다는 게 애자일 조직이 갖추는 특징입니다.
24 |
25 | **3. 비주얼 플래닝**
26 | > 애자일하게 일하는 조직이 활용하는 또다른 방법은 **업무 상황을 도식화해 공유**한다는 것입니다.
27 | > 무슨 일을 해야 하는지, 현재 진행 상황은 어떤지 등을 모두가 볼 수 있는 형식에 담아 비주얼 플래닝(Visual Planning) 하는 것 입니다.
28 | > 업무가 시각화되면 불필요한 미팅이 줄어들고 일이 어떻게 진행되고 있는지 **개인에게 확인 할 필요가 없어지며 표로써 한눈에 알 수 있기 때문입니다.**
29 |
30 |
--------------------------------------------------------------------------------
/organization/AgileCulture.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jyeonjyan/TIL/3a9e3beb5e7672578e4d2b98a4ce5dca8495d7be/organization/AgileCulture.md
--------------------------------------------------------------------------------
/organization/startup-expression.md:
--------------------------------------------------------------------------------
1 | ## 스타트업 용어 정리
2 | > 🧑🏻💻 내가 취직할 스타트업에서의 사업적 소통과 지적 겸손함을 갖추기 위한 문서
3 |
4 | 1. 스타트업
5 | 1. 실리콘밸리에서 시작된 용어, 신생 창업기업을 의미. 기술과 아이디어를 가지고 있지만 시드머니가 부족한 경우가 많다.
6 |
7 | 2. 벤처기업
8 | 1. 첨단 기술 + 아이디어로 사업을 시작하는 창조적인 중소기업을 의미한다. 벤처기업육성에 관한 특별조치법에 따라 기술 및 경영혁신 능력이 우수한 중소기업 중 추가적 요건을 갖춘 기업을 정부에서 인증하는 것으로 구분지어진다. 세금 혜택이나 정부에서 주는 지원을 다방면으로 받을 수 있다.
9 |
10 | 3. 클라우드 펀딩
11 | 1. 투자가 필요한 개인, 단체, 기업이 각 네트워크를 활용하여 불특정 다수에게 투자를 받는다. 대부분 인터넷 중개 사이트를 통해 진행되며, 투자자들이 프로젝트를 골라 투자에 참여한다
12 | 2. 프로젝트에는 모금취지, 기간, 목표, 보상내용이 올라와 있으며, 모금 기간 동안 목표액에 달성하지 못하면 모금액은 투자자에게 돌려준다.
13 |
14 | 4. 엑셀러레이터
15 | 1. 스타트업이 빠르게 성장 궤도에 오를 수 있도록 초기 자금과 멘토링 지원 등을 하는 단체이다. 영리적인 목적을 가지고 기업가나 투자가가 직접 비용을 투자하여 자본을 공급한 대가로 지분을 받는다.
16 |
17 |
--------------------------------------------------------------------------------
/tobby/interests.md:
--------------------------------------------------------------------------------
1 | ## 관심사의 분리
2 | 미래를 준비하는 데 있어 가장 중요한 과제는 변화에 어떻게 대비할 것인가이다.
3 | 가장 좋은 대책은 변화의 폭을 최소한으로 줄여주는 것이다.
4 |
5 |
6 | > 두 명의 개발자에게 동일한 기능 변경을 요청했다고 하자.
7 | > 그런데 한 명은 단 몇 줄의 코드만 수정하고 그 변경이 나머지 기능에는 전혀 문제를 일으키지 않는다는 것까지 검증해주는데 5분이 걸렸다.
8 |
9 | > 다른 개발자는 동일한 기능을 변경하는데 5시간이 걸린데다.
10 | > 기존에 잘 동작하던 다른 기능에 오류를 일으킬지도 모른다는 새로운 불안감까지 일으켰다면 괴연 어떤 개발자가 더 미래의 변화를 잘 준비한 것일까?
11 |
12 |
13 |
14 | 잘 설계한 개발자는 **"분리"와 "확장"** 을 고려한 설계가 있었기 때문이다.
15 | 변화 한 번에 한 가지 관심에 집중돼서 일어난다면, 우리가 준비해야 할 일은 한 가지 관심이 한 군데에 집중되게 하는 것이다.
16 |
17 |
18 |
19 | 프로그래밍 기초 개념중에 **"관심사의 분리"** 라는게 있다.
20 | 이를 객체지향에 적용해보면, 관심이 있는 것끼리는 하나의 객체 안으로 또는 친한 객체로 모이게 하고, 관심이 다른 것은 가능한 한 따로 떨어져서 서로 영향을 주지 않도록 분리하는것이라고 생각할 수 있다.
21 |
22 | ## 중복 코드의 메소드 추출
23 | ```java
24 | public void add(User user) throws ClassNotFoundException, SQLException{
25 | // DB 연결 기능이 필요하면 getConnection() 메서드를 이용하게 한다.
26 | Connection c = getConnection();
27 | }
28 |
29 | private Connection getConnection() throws ClassNotFoundException, SQLException{
30 | Class.forName("com.mysql.jdbc.Driver");
31 | Connection c = DriverManager.getConnection(
32 | "asdfa","spring","book");
33 | return c;
34 | )
35 | }
36 | ```
37 |
38 | 이렇게 되면, 드라이버 클래스와 URL이 바뀌었다거나, 로그인 정보가 변경돼도 앞으로는 ``getConnection()`` 이라는 한 메소드의 코드만 수정하면 된다.
39 | 관심의 종류에 따라 코드를 구분해놓았기 때문에 한 가지 관심에 대한 변경이 일어날 경우 그 관심이 집중되는 부분의 코드만 고치면 된다.
40 |
41 | ## 상속을 통한 확장
42 | 1. 서브클래스에서 메서드를 필요에 의해 맞게 구현해서 사용가능 하도록 하는 방법을 ["템플릿 메소드 패턴"](./templatePattern.md) 이라고 한다.
43 |
44 | 2. 서브클래스에서 구체적인 오브젝트 메서드를 결정하게 하는 것을 "팩토리 메서드 패턴" 이라고 한다.
--------------------------------------------------------------------------------
/tobby/objectDi.md:
--------------------------------------------------------------------------------
1 | ## 오브젝트와 의존관계
2 | **스프링**
3 | * 스프링이 가장 많은 관심을 두는 대상은 오브젝트이다.
4 | * 스프링을 이해하려면 먼저 오브젝트에 깊은 관심을 가져야 한다.
5 | * 객체지향 설계의 기초와 원칙을 비롯해 되도록 지속적으로 개선해나가는 직업인 리팩토링, 오브젝트가 기대한 대로 동작하고 있는지를 효과적으로 검증하는 데 쓰이는 단위 테스트와 같은 오브젝트 설계와 구현에 관한 여러 가지 응용 기술과 지식이 요구됨.
6 |
7 |
--------------------------------------------------------------------------------