무작위 정수 하나를 생성하고 싶다고 해봅시다. 값의 범위는 0부터 명시한 수 사이입니다. 아주 흔히 마주치는 문제로, 많은 프로그래머가 다음과 같은 짤막한 메서드를 만들곤 합니다. static Random rnd = new Random(); static int random(int n) { return Math.abs(rnd.nextInt()) % n; } 괜찮은 듯 보여도 문제를 세 가지나 내포하고 있습니다. 위 코드의 문제점 [1]. n이 그리 크지 않은 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복된다. [2]. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환된다. n 값이 크면 이 현상은 더 두드러집니다. 다음 코드는 무작위 수를 백만개를 생성한 다음, 그 중 중간 값보다 작..
아이템 45에서 이야기했듯, 스트림이 제격인 작업이 있고 반복이 제격인 작업이 있습니다. 다음은 전통적인 for 문으로 컬렉션을 순회하는 코드입니다. for (Iterator i = c.iterator(); i.hasNext(); ) { Element e = i.next(); } 그리고 다음은 전통적인 for 문으로 배열을 순회하는 코드입니다. for (int i = 0; i < a.length; i++) { ... // a[i]로 무언가를 한다. } 이 관용구들은 while 문보다는 낫지만(아이템 57) 가장 좋은 방법은 아닙니다. 반복자와 인덱스 변수는 모두 코드를 지저분하게 할 뿐 우리에게 진짜 필요한 건 원소들뿐입니다. 더군다나 이처럼 쓰이는 요소 종류가 늘어나면 오류가 생길 가능성이 높아집니다...
이번 아이템에는 개별 아이템으로 두기 애매한 API 설계 요령들을 모아 놓았습니다. 이 요령들을 잘 활용하면 배우기 쉽고, 쓰기 쉬우며, 오류 가능성이 적은 API를 만들 수 있습니다. [1]. 메서드 이름을 신중히 짓자. 항상 표준 명명 규칙(아이템 68)을 따라야 합니다. 이해할 수 있고, 같은 패키지에 속한 다른 이름들과 일관되게 짓는 게 최우선 목표입니다. 🐻 클린 코드에서도 이와 같은 이야기가 언급됩니다. 그 다음 목표는 개발자 커뮤니티에서 널리 받아들여지는 이름을 사용하는 것입니다. 긴 이름은 지양합시다! 🐻 클린 코드에서는 긴 이름이어도 명확하게 의미를 전달하는 게 중요하다고 말합니다. 상황에 따라서 개발자가 선택을 하면 될 것 같습니다. 애매하면 자바 라이브러리의 API 가이드를 참조합시다..
자바는 안전한 언어입니다. 네이티브 메서드를 사용하지 않으니 C, C++ 같이 안전하지 않은 언어에서 흔히 보는 버퍼 오버런, 배열 오버런, 와일드 포인터 같은 메모리 충돌 오류에서 안전합니다. 자바로 작성한 클래스는 시스템의 다른 부분에서 무슨 짓을 하든 그 불변식이 지켜집니다. 메모리 전체를 하나의 거대한 배열로 다루는 언어에서는 누릴 수 없는 강점입니다. 하지만 아무리 자바라 해도 다른 클래스로부터의 침범을 아무런 노력 없이 다 막을 수 있는 건 아닙니다. 그러니 클라이언트가 여러분의 불변식을 깨뜨리려 혈안이 되어 있다고 가정하고 방어적으로 프로그래밍해야 합니다. 실제로도 악의적인 의도를 가진 사람들이 시스템의 보안을 뚫으려는 시도가 늘고 있습니다. 평범한 프로그래머도 순전히 실수로 여러분의 클래스..
주류 언어 중, 동시성 프로그래밍 측면에서 자바는 항상 앞서갔습니다. 처음 릴리스된 1996년부터 스레드, 동기화, wait/notify를 지원했습니다. 자바 5부터는 동시성 컬렉션인 java.util.concurrent 라이브러리와 Executor 프레임워크를 지원했습니다. 자바 7부터는 고성능 병렬 분해 프레임워크인 fork-join 패키지를 추가했습니다. 그리고 자바 8부터는 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원했습니다. 이처럼 자바로 동시성 프로그램을 작성하기가 점점 쉬워지고는 있지만, 이를 올바르고 빠르게 작성하는 일은 여전히 어려운 작업입니다. 동시성 프로그래밍을 할 때에는 안전성(safety)과 응답 가능(liveness) 상태를 유지하기 ..
원소 시퀀스, 즉 일련의 원소를 반환하는 메서드는 수없이 많습니다. 자바 7까지는 이런 메서드의 반환 타입으로 Collection, Set, List 같은 컬렉션 인터페이스 혹은 Iterable이나 배열을 썼습니다. 이 중 가장 적합한 타입을 선택하기란 그다지 어렵지 않았습니다. 기본은 컬렉션 인터페이스입니다. for-ecah 문에서만 쓰이거나 반환된 원소 시퀀스가 주로 (contains(Object) 같은) 일부 Collection 메서드를 구현할 수 없을 때는 Iterable 인터페이스를 썼습니다. 반환 원소들이 기본 타입이거나 성능에 민감한 상황이라면 배열을 썼습니다. 그런데 자바 8이 스트림이라는 개념을 들고 오면서 이 선택이 아주 복잡한 일이 되어버렸습니다. 원소 시퀀스를 반환할 때는 당연히 스..
스트림 API는 다량의 데이터 처리 작업(순차or병렬)을 돕고자 자바 8에 추가되었습니다. 자바 8에 추가된 기술 [5] Stream 자바 8에는 다양한 기술들을 살펴보려고 하는데, 그 다섯 번째는 Stream이다. 데이터를 담고 있는 저장소(컬렉션)이 아니다. 연속된 데이터를 처리하는 operation의 모임이라고 생각하면 된다. 스트 kkoon9.tistory.com 이 API가 제공하는 추상 개념 중 핵심은 두 가지입니다. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻합니다. 스트림 파이프라인은 이 원소들로 수행하는 연산 단계를 표현하는 개념입니다. 스트림의 원소들은 어디로부터든 올 수 있습니다. 대표적으로는 컬렉션, 배열, 파일, 정규표현식 패턴 매처(matcher), 난수 생성기, 혹은 다..
자바가 람다를 지원하면서 API를 작성하는 모범 사례도 크게 바뀌었습니다. 예컨대 상위 클래스의 기본 메서드를 재정의해 원하는 동작을 구현하는 템플릿 메서드 패턴의 매력이 크게 줄었습니다. 이를 대체하는 현대적인 해법은 같은 효과의 함수 객체를 받는 정적 팩터리나 생성자를 제공하는 것입니다. 이 내용을 일반화해서 말하면 함수 객체를 매개변수로 받는 생성자와 메서드를 더 많이 만들어야 합니다. 이 때 함수형 매개변수 타입을 올바르게 선택해야 합니다. LinkedHashMap을 생각해봅시다. 이 클래스의 protected 메서드인 removeEldestEntry를 재정의하면 캐시로 사용할 수 있습니다. 맵에 새로운 키를 추가하는 put 메서드는 이 메서드를 호출하여 true가 반환되면 맵에서 가장 오래된 원..
- Total
- Today
- Yesterday
- 테라폼
- 알고리즘
- Kotlin
- 디자인패턴
- 코테
- MSA
- kotest
- Spring
- 이팩티브 자바
- 백준
- JPA
- AWS
- C++
- Olympiad
- Effective Java
- 이펙티브 자바
- node.js
- 프로그래머스
- BOJ
- 객체지향
- 디자인 패턴
- 클린 아키텍처
- Algorithm
- Spring Boot
- kkoon9
- Java
- 정규표현식
- 클린 코드
- BAEKJOON
- programmers
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 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 |