전체 글


기존에 배포한 프로젝트 도메인에 접속했는데, 갑자기 접속을 거부당했다.502..?이유가 뭘까? 분명 일주일 전에는 접속이 되었고, 아무것도 수정한 것이 없는데 왜?라는 생각이 들었다. 나는 Let's encrypt를 사용하였고 nginx를 리버스 프록시로 사용하고 있었다. 그래서 연결이 아예 거부되었기에 nginx 상태를 먼저 확인해 보았고..ubuntu@ip-172-31-36-50:~$ sudo systemctl status nginx● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: e..

직렬화: 객체 -> 바이트 스트림역직렬화: 바이트 스트림 -> 객체직렬화된 객체는 다른 VM에 전송하거나 디스크에 저장한 후 나중에 역직렬화할 수 있다. 직렬화를 통해 프로그래머가 어렵지 않게 분산 객체를 만들 수 있다는 취지였지만, 실상은 보이지 않는 생성자, API와 구현 사이의 모호해진 경계, 성능, 보안 등 그 대가가 컸다. 지금까지 경험한 바로는 단점이 더 컸다. 직렬화의 근본적인 문제는 공격 범위가 너무 넓고 지속적으로 넓어져 방어하기 어렵다는 점이다. 이는 역직렬화될 때, ObjectInputStream의 readObject 메서드가 호출되기 때문인데, 이 메서드는 클래스패스 안의 거의 모든 타입의 객체를 만들어 낼 수 있는, 마법 같은 생성자이기 때문이다. 가젯(gadget): 역직렬화 과..

지연 초기화 : 필드의 초기화 시점을 그 값이 처음 필요할 때까지 늦추는 방법. 최선의 조언은 "지연 초기화는 필요할 때까지는 하지 말라"이다. 지연 초기화는 양날의 검이다. 지연초기화하는 필드에 접근하는 비용이 커지기 때문이다. 실제로는 성능을 느려지게 할 수도 있다.public class LazyExample { private String data; public String getData() { if (data == null) { // 초기화 체크 data = "지연 초기화된 값"; } return data; }} 그럼에도 해당 클래스의 인스턴스 중 그 필드를 사용하는 인스턴스의 비율이 낮은 반면, 그 필드를 초기화하는 비용이 ..


What's Different? 진행중인 프로젝트에 선배포를 진행하기로 하였다.작업 상황을 실시간으로 확인하고 싶었기에 개발보다 인프라를 먼저 구축하기로 결정했다. 제일 먼저, DNS 주소를 싸게 구입했고(가비아에서 구입. AWS Route 53에서 구입할 수도 있다) , 이후 HTTPS를 적용하여야 했다.왜냐하면 실제로 웹을 오픈해서 계속 운영해나갈 계획이기에 HTTPS를 사용하여 신뢰성이 보장되고, 데이터 전달간에 안전성을 확보하기 위해서이다.이전에 진행한 팀프로젝트에서는 AWS Route 53, AWS Certificate Manager을 통해 HTTPS 설정을 진행했었다. 그때는 굉장히 AWS에 의존적인 개발이었다. EC2는 물론이고 CloudFront, RDS, Lambda, S3 등 다양한 설..

예외를 무시하기는 아주 쉬운데, 그러다가 끔찍한 참사로 이어질 수 있다. 마치 화재경보를 무시하는 수준을 넘어 아예 끄는 것과 같다. catch 블록을 비워두면 예외가 존재할 이유가 없어진다. 물론 예외를 무시해야 할 때도 있다. FileInputStream 을 닫을 때 처럼 읽기 전용일때, 파일의 상태를 변경할 일이 전혀 없으니 복구할 것이 없으며, 남은 작업을 중단할 이유도 없다. 하지만 혹시나 같은 예외가 여러 번 발생한다면 조사해보는 것이 좋을테니 로그로 남기는 것이 좋다. 예외를 무시하기로 했다면 catch 블록 안에 그렇게 결정한 이유를 주석으로 남기고 예외 변수의 이름도 ignored로 바꿔놓자. 빈 catch 블록으로 예외를 못 본 척 지나치면 어느 새 프로그램은 아무 상관 없는 곳에서 ..

검사 예외(checked exception)은 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 사용하여 정확히 문서화하자. 공통 상위 클래스 하나로 뭉뚱그려 선언하는 일은 삼가자.throws Exception이나 Throwable을 하면 안된다. 사용자에게 각 예외에 대처할 수 있는 힌트도 못주고 다른 예외들까지 삼켜버릴 수 있다. main() 메서드는 오직 JVM만이 호출하므로 Exception을 던지도록 선언해도 괜찮다. /** * @throws IllegalStateException */public void testMethod(String parameter) throws IllegalStateException { }비검사 예외(unchecked exception)..

자바의 데이터 타입1. 기본형: int, double, boolean 등2. 참조형: String, List, Integer, Double, Boolean 등각각의 기본 타입에 대응하는 참조 타입 = 박싱된 기본 타입 주된 차이 세 가지1. 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값 + 식별성을 가지고 있다. 즉 메모리 주소를 할당받는다.그러므로 박싱된 기본 타입의 두 인스턴스는 값이 같아도 서로 다르다고 식별될 수 있다.2. 기본 타입의 값은 언제나 유효한 반면 박싱된 기본 타입은 유효하지 않은 값, 즉 null을 가질 수 있다.3. 기본 타입이 박싱된 기본 타입보다 시간과 메모리 사용면에서 더 효율적이다. 문제 1.박싱된 기본 타입에 == 연산자를 사용하면 예상치 못한 에러가 발생할 수..

자바의 명명 규칙은 크게 철자, 문법 두 범주로 나뉜다. 철자1. 패키지와 모듈 이름은 각 요소를 점으로 구분하여 계층적으로 짓는다. 요소들은 모두 소문자 알파벳 혹은 (드물게) 숫자로 이뤄진다. 조직 바깥에서도 사용될 패키지라면 조직의 dns 이름을 역순으로 사용한다.(예시: com.google) 2. 클래스와 인터페이스의 이름은 하나 이상의 단어로 이뤄지며, 각 단어는 대문자로 시작한다. 널리 통용되는 줄임말을 제외하고는 단어를 줄여 쓰지 않도록 한다.3. 메서드와 필드 이름은 첫 글자를 소문자로 쓴다는 점만 빼면 클래스 명명 규칙과 같다. 4. 상수 필드는 모두 대문자로 쓰며 단어 사이는 밑줄로 구분한다. (NEGETIVE_INFINITY)5. 지역변수에서도 다른 멤버와 비슷한 명명 규칙이 적용된..

한 줄짜리 출력값 혹은 작고 크기가 고정된 객체의 문자열 표현을 만들때라면 괜찮지만, 많이 연결해야 한다면 성능 저하는 불가피하다. 문자열은 불변이라서 두 문자열을 연결할 경우 문자열 각각을 복사해서 더해야 함으로 문자열 n개를 잇는 시간은 n2에 비례한다. 성능을 높이고 싶으면 String 대신 StringBuilder를 사용하라.시간이 약 6배 빨라진다.StringBuilder는 메서드 체이닝 방식을 통해한 줄짜리 출력값 혹은 작고 크기가 고정된 객체의 문자열 표현을 만들때라면 괜찮지만, 많이 연결해야 한다면 성능 저하는 불가피하다. 문자열은 불변이라서 두 문자열을 연결할 경우 문자열 각각을 복사해서 더해야 함으로 문자열 n개를 잇는 시간은 n2에 비례한다. String 연결은 매번 새로운 객체를 생..