타입 소거

목표 타입 소거의 의미를 이해한다. 타입 소거가 필요한 이유를 이해한다. 타입 소거의 의미 타입 파라미터에 대해서 컴파일 타임에만 타입 검사를 하고 런타임에는 타입에 대한 정보를 삭제하는 방식 아래와 같은 코드가 있다고 가정하면 public static <E> boolean containsElement(E [] elements, E element){ for (E e : elements){ if(e.equals(element)){ return true; } } return false; } 런타임에는 아래와 같이 동작한다. unbound 타입인 E가 Object 타입으로 치환되었다. public static boolean containsElement(Object [] elements, Object element){ for (Object e : elements){ if(e....

2024-09-15 · 2 min · 244 words

클래스의 모든 필드를 getter 없이도 직렬화

코드 리뷰를 하다가 새로운 사실을 알게 되었다. Jackson은 기본적으로 getter 메소드로 직렬화를 한다. 아래처럼 지정하면 클래스의 필드들을 기반으로 접근제어자 상관 없이 직렬화가 가능하다. OBJECT_MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

2024-09-15 · 1 min · 25 words

클라이언트가 서버에 갱신된 정보를 빠르게 가져오는 방법

이런 고민을 한 이유: HTTP의 한계 무상태성: 클라이언트의 상태를 기억하지 않기 때문에 클라이언트에게 갱신된 정보를 알려줄 수 없다. 비연결성: 1개의 리퀘스트로 부터 응답을 하면 연결이 끊어진다. Polling: 주기적으로 클라이언트가 request를 보내 새로운 정보를 갱신하는 방법 장점 구현이 단순하다. 단점 주기적으로 HTTP 연결을 맺고 끊는게 상당한 클라이언트와 서버 측에서 모두 큰 부담이 된다. 이를 어느 정도 해결하기 위해 전송하는 데이터 양을 줄이기 위해 ajax를 사용한다. Long Polling(HTTP/1.1): 클라이언트와 서버가 계속 연결을 맺고 끊는 것을 줄이기 위해서 만든 방법....

2024-09-15 · 2 min · 401 words

쿼리 파라미터가 여러 개인 경우 어떻게 처리할까

일반적으로 두 가지 방법을 사용한다. http://localhost:8080/api/foos?id=1,2,3 http://localhost:8080/api/foos?id=1&id=2 위의 두 예시모두 Spring MVC에서 자동으로 매핑시켜주기 때문에 걱정없이 사용할 수 있다. @GetMapping("/api/foos") @ResponseBody public String getFoos(@RequestParam List<String> id) { return "IDs are " + id; } 참고 자료 https://stackoverflow.com/questions/2602043/rest-api-best-practice-how-to-accept-list-of-parameter-values-as-input

2024-09-15 · 1 min · 37 words

쿠버네티스로 클러스터 구성하기

쿠버네티스 구성 방법 퍼블릭 클라우드 업체에서 제공하는 관리형 쿠버네티스 EKS(Amazon Elastic Kubernetes), AKS(Azure Kubernetes Services), GKE(Google Kubernetes Engine) 등이 있다. 구성이 이미 다 갖춰져 있고 마스터 노드를 클라우드 업체에서 관리하기 떄문에 학습용으로는 적합하지 않다. 설치형 쿠버네티스 Rancher, OpenShift 등이 있다. 하지만 유료라는 단점이 있다. 구성형 쿠버네티스 kubeadm, kops(Kubernetes Operations), KRIB(Kubernetes Rebar Integrated Bootstrap), kubespray 등이 있다. 사용하는 시스템에 쿠버네티스 클러스터를 자동으로 구성해준다. kubeadm이 가장 널리 알려져 있다. kubeadm은 사용자가 변경하기도 쉽고, 온프레미스와 클라우드를 모두 지원하며, 배우기도 쉽다....

2024-09-15 · 3 min · 441 words

코딩을 지탱하는 기술

프로그래밍 언어의 목적 프로그래밍 언어는 인간을 편하게 하기 위해 만들어졌다. 예전에는 케이블의 연결을 바꾸고(ENIAC), 테이프에 구멍을 뚫어서 데이터를 표현하는(EDSAC) 것을 통해 프로그램을 변경할 수 있었다. 이것은 사람이 프로그램을 읽거나 쓰기에는 어려웠다. 그 이후에 현재 우리가 사용하고 있는 것과 비슷한 프로그래밍 언어 FORTRAN이 고안되었다. 이렇게 프로그래밍 언어의 목적은 프로그래밍을 편리하게 하는 것이다. 하지만 이 편리함의 의미는 사람에 따라 다르기 때문에 현재에 수많은 언어가 존재하고 있는 것이다. 예를 들어, C++는 빠른 실행 속도를 중시하고 있지만, 결과적으로 언어 사양이 복잡해졌다....

2024-09-15 · 10 min · 2026 words

컬럼명 수정 SQL

ALTER TABLE user CHANGE name nickname VARCHAR(30) NULL; 바꿀 컬럼명 뒤에 타입도 함께 명시하지 않으면 에러가 난다는 점을 유의해야된다.

2024-09-15 · 1 min · 19 words

컨테이터 IP 확인하기

docker위에서 돌아가고 있는 WAS가 docker 위에 올라가 있는 DB에게 연결을 계속 실패하는 문제가 있었다. 분명 docker inspect 명령어로 확인한 IP 주소 값인데 왜 연결에 실패하는지 이해가 되지 않았다. docker를 사용하면 docker0라는 네트워크 인터페이스가 생긴다. docker에서는 이 네트워크 인터페이스에 bridge라는 네트워크 드라이버를 제공하고있다. 그래서 docker를 설치한 직후에 docker network ls 명렁어를 입력하면 아래와 같이 bridge 드라이버를 사용중인 네트워크를 볼 수 있다. 또한 아무 설정없이 컨테이너를 만들면 이 기본 bridge 네트워크에 연결하게 된다....

2024-09-15 · 1 min · 134 words

컨테이너로 이미지 만들기 및 Docker hub에 업로드

컨테이너로 이미지 만들기 docker commit [ContainerID] 이미지에 태그 붙이기 docker tag SOURCE_IMAGE[:TAG] TARcoGET_IMAGE[:TAG] 이미지 docker hub에 업로드 및 다운로드 docker push [OPTIONS] NAME[:TAG] docker pull [OPTIONS] NAME[:TAG] 참고 자료 https://galid1.tistory.com/324

2024-09-15 · 1 min · 30 words

최대 샤드 개수

배경 테스트 코드 실행 중에 ES에서 최대 샤드 개수를 초과해서 인덱스를 만들 수 없다는 오류가 발생했다. cluster.max_shards_per_node ES 클러스터 설정 값 중에 한 노드 당 만들 수 있는 최대 샤드 수가 있다. 클러스터 내에 있을 수 있는 (프라이머리 샤드 수) + (레플리카 샤드 수)의 최대는 cluster.max_shards_per_node * number of non-frozen data nodes 참고 자료 https://www.elastic.co/guide/en/elasticsearch/reference/current/misc-cluster-settings.html

2024-09-15 · 1 min · 55 words

지연 로딩

즉시 로딩과 지연 로딩 @Entity public class Member { @ManyToOne @JoinColumn(name = "TEAM_ID") private Team teams; // ... } 즉시 로딩(@ManyToOne(fetch = FetchType.EAGER)): Member라는 엔티티를 조회할 때 연관된 엔티티인 Team 도 같이 조회된다. 지연 로딩(@ManyToOne(fetch = FetchType.LAZY)): Member라는 엔티티를 조회할 때 Team을 조회하지 않다가, 실제로 사용할 떄 조회한다. ex) member.getTeam() 지연 로딩의 동작 방법 만약, 위 예시에서 team이 지연로딩()을 사용 중이라면 member.getTeam() 을 호출했을 때의 Team은 프록시 객체다. 그리고 이 프록시 객체는 실제 사용될 때 까지 로딩을 미룬다....

2024-09-15 · 3 min · 572 words

중위 함수

목표 중위 함수 구현 방법을 알아본다. infix 중위 함수로 만들고자 하는 함수 앞에 infix 키워드를 붙이면 된다. 단, 3가지 조건이 있다. 함수가 클리스에 구현되어 있거나, 특정 클래스의 확장 함수이다. 함수는 정확히 하나의 파라미터를 가진다. 함수 앞에 infix 키워드가 붙어있다. data class Point(val x: Int, val y: Int) { infix fun isEqualTo(other: Point): Boolean { return x == other.x && y == other.y } } Point(1, 2) isEqualTo Point(1, 2) 참고 자료 https://www....

2024-09-15 · 1 min · 72 words

주기적으로 특정 함수 실행시키기

아래의 함수로 구현할 수 있다. var intervalID = setInterval(func, [delay, arg1, arg2, ...]); 실행 주기는 ms 단위다. var intervalID = setInterval(myCallback, 500, 'Parameter 1', 'Parameter 2'); function myCallback(a, b) { // Your code here // Parameters are purely optional. console.log(a); console.log(b); } 주기 실행을 멈추려면 아래 함수를 사용하면 된다. clearInterval(intervalID)

2024-09-15 · 1 min · 50 words

정적 페이지 배포시 Cloudfront 캐시 지우기

새로 배포할 때마다 cloudfront에 캐싱 되어 있는 파일을 지워야된다면 invalidation을 생성하면된다. 하지만 여기서 주의할 점이 invalidation은 설정 값이 아니다. 배포할 때마다 매번 invalidation을 생성해서 무효화 해줘야된다. 우리는 이 또한 자동화 해주고싶어서 aws cli를 사용했다. aws cloudfront create-invalidation --distribution-id ${{ secrets.DISTRIBUTION_ID }} --paths "/index.html" "/bundle.js" 위의 명령어를 사용하려면 IAM에 CreateInvalidation 접근 권한이 필요하다. 우리의 경우 CU 코치님에게 요청을 해서 받을 수 있었다. 참고 자료 https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html

2024-09-15 · 1 min · 64 words

전역 에러 처리하기

목표 Vue 앱에서 처리하지 않은 에러를 전역적으로 처리하는 방법을 이해한다. app.config.errorHandler app.config.errorHandler에 catch하지 않은 에러의 global handler를 할당할 수 있다. app.config.errorHandler = (err, instance, info) => { // handle error, e.g. report to a service } 핸들링해줄 수 있는 함수들은 다음과 같다. Component renders Event handler Lifecycle hooks setUp() 함수 Watchers Coustom directive hooks Transition hooks 참고 자료 https://vuejs.org/api/application.html#app-config-errorhandler

2024-09-15 · 1 min · 59 words

자식 컴포넌트의 함수 호출하기

Ref를 사용하면 특정 DOM노드나 React 요소에 접근하는 방법을 제공해준다. Ref 생성하기 아래와 같이 React.createRef() 함수로 Ref를 생성한뒤, 원하는 DOM 노드의 프로퍼티로 Ref를 지정해주면된다. class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } } Ref에 접근하기 ref에 엘리먼트가 전달되었을 때, ref의 current라는 어트리뷰트에 담기게된다. const node = this.myRef.current; 그 뒤에는 해당 컴포넌트에 있는 함수를 호출 할 수 있다. class AutoFocusTextInput extends React....

2024-09-15 · 1 min · 96 words

자동 생성자

목표 @RequiredArgsConstructor가 동작하는 방식을 알아본다. @NoArgsConstructor, @RequireArgsConstructor, @AllArgsConstructor @NoArgsConstructor 파라미터가 없는 생성자를 만든다. final 필드가 있어서 불가능한 경우는 컴파일 오류가 발생한다. @NoArgsConstructor(force=true) 옵션을 줄 경우, 컴파일 오류가 발생하지 않고 모든 final 필드를 0, false, null로 초기화한다. @NonNull 이 붙어있는 어노테이션이 붙어있어도 검사하지 않으므로 유의해야된다. @RequiredArgsConstructor final 필드나 @NonNull 이 붙어있는 필드 중에 초기화 되지 않은 필드들을 파라미터로 가지는 생성자를 만든다. 이 경우에는 @NonNull 이 붙어있으면 널 검사를 하기 때문에, 생성자 파라미터에 null이 있으면 NullPointerException 이 발생한다....

2024-09-15 · 1 min · 127 words

입출력

Java에서 입출력시 InputStream과 OutputStream을 사용한다. 이 들은 각각 추상 클래스기 때문에 별도의 구현체를 사용한다. Byte Stream 데이터를 바이트 단위로 주고 받을 때 사용한다. InputStream BytesArrayInputStream: 바이트 배열을 읽기 위해서 내장된 버퍼를 사용한다. FileInputStream: 파일을 바이트 단위로 읽기위해서 사용한다. FilterInputStream: InputStream에 추가 기능을 사용하기 위해서 사용한다. 이는 다른 InputStream을 포함하고 있어야되면 단독으로 사용은 불가능하다. BufferedInputStream: 입력 성능을 개선하기 위해 사용한다. 특정 크기(기본값 8bytes)만큼의 버퍼를 할당한 후 데이터를 미리 읽고 저장한다. 이후 주가적인 읽기 작업이 필요하면 버퍼의 크기를 늘려 읽기를 실행시킨다....

2024-09-15 · 2 min · 321 words

인덱스 생성, 삭제, 조회 SQL 문

// 생성 ALTER TABLE 테이블명 ADD INDEX 인덱스명(컬럼명1, 컬럼명2, ...) // 삭제 ALTER TABLE 테이블명 DROP INDEX 인덱스명 // 조회 SHOW INDEX FROM 테이블명;

2024-09-15 · 1 min · 24 words

이터레이터, 제너레이터, yield

이터레이터(iterator) 이터레이터는 값을 차례대로 꺼낼 수 있는 객체다. 우리가 for 반복문을 사용할 때 요소를 하나씩 꺼내서 처리할 수 있게 되는데, 이터레이터를 사용했기 때문에 가능한 것이다. 어떤 클래스가 이터레이터이기 위해서는 다음 조건을 만족해야된다. __iter__ 메소드를 구현하되 자기 자신(self)을 반환한다. __next__ 메소드를 구현해서 next 내장 함수의 인자로 자신을 줬을 때 다음에 반환할 값을 정의해야된다. 더 이상 반환할 값이 없는 경우 __next__메소드는 StopIteration 예외를 일으키도록 한다. 이터러블(iterable) 말 그대로 ‘순회 가능한’이라는 뜻이다. for 문의 in 키워드 뒤에 올 수 있는 모든 값을 이터러블이다....

2024-09-15 · 2 min · 291 words