UTF-8이 UTF-16보다 나은 점
- 영문/ASCII 비중이 큰 데이터에 매우 효율적
- UTF-8은 ASCII(0~127)를 1바이트로 표현 → 로그, 프로토콜 헤더, JSON 키 등에서 이점이 큼
- 저장/전송 관점에서 사실상 표준
- 웹(HTTP), JSON, 대부분의 텍스트 파일/CLI 환경에서 UTF-8이 기본값인 경우가 많음
- 한글은 UTF-16이 유리할 때도 있음
- 한글: UTF-8은 보통 3바이트, UTF-16은 보통 2바이트
- 다만 “영문/ASCII가 섞인” 현실 데이터에서는 UTF-8이 전체적으로 유리한 경우가 많음
- 정리
- “ASCII 위주/혼합 텍스트 + 표준 호환성” 때문에 UTF-8이 실무에서 기본 선택이 되는 경우가 많다
2의 보수(2’s complement) 구하는 법
- 모든 비트를 반전(1’s complement)한 뒤 +1
- 예: 8비트에서
0000 0101(5)의 음수 표현- 반전:
1111 1010 - +1:
1111 1011→-5
- 반전:
자바에서 기본으로 외부와 인터페이스하는 데이터 용량 단위는?
- byte(바이트) 단위
- 네트워크 소켓, 파일, 스트림 I/O의 기본 단위는 바이트 배열(
byte[]) - 문자 기반 처리는
Reader/Writer로 감싸서 인코딩(UTF-8 등) 을 적용하는 구조가 일반적
- 네트워크 소켓, 파일, 스트림 I/O의 기본 단위는 바이트 배열(
예)
InputStream in = socket.getInputStream(); // byte 단위
Reader r = new InputStreamReader(in, StandardCharsets.UTF_8); // 문자 단위로 변환
외부와 통신할 때 버퍼 사이즈는 몇이 좋은가?
- 너무 작으면: 읽기/쓰기 호출(시스템 콜) 횟수가 늘어 오버헤드 증가
- 너무 크면: 동시 연결/요청이 많을 때 메모리 사용량 증가 → GC 압박/OOM 위험
- 실무 기본값으로는 4KB~8KB가 무난
- 파일시스템 블록/메모리 페이지(환경에 따라 4KB 등)와 맞추면 효율이 좋은 경우가 많음
- 현실적인 권장
- 시작점: 8KB(8192) 또는 16KB
- 트래픽/지연/메모리 상황에 따라 측정 후 조정 (특히 대용량 전송은 32KB~64KB도 흔함)
TCP와 UDP 차이
TCP
- 연결 지향(3-way handshake)
- 신뢰성 보장: 재전송, 순서 보장, 중복 제거
- 흐름/혼잡 제어 포함
- 사용 예: HTTP/HTTPS, DB 연결, 파일 전송 등
UDP
- 비연결 지향
- 신뢰성/순서 보장 없음(필요하면 애플리케이션 레벨에서 구현)
- 오버헤드가 작고 지연이 낮을 수 있음
- 사용 예: DNS, VoIP, 게임, 일부 스트리밍/브로드캐스트 등
네트워크 예외 정리 (Java)
java.net.UnknownHostException
- DNS/호스트 해석 실패
- 예: 존재하지 않는 도메인, 잘못된 호스트명
google.gogo같은 도메인이 해석되지 않음
java.net.ConnectException: Connection refused
- 대상 서버에 도달은 했지만, 해당 포트에서 연결을 받아주지 않음
- 서버 프로세스가 해당 포트를 리슨하지 않음
- 방화벽/보안 정책이 RST로 거절하는 경우
- OS가 보통 TCP RST로 응답 → Java에서 refused 예외
(OS 기본 타임아웃 기반) java.net.ConnectException: Operation timed out
- 연결 시도에 대한 응답이 끝내 오지 않음
- 라우팅 문제, 방화벽 드랍(drop), 대상 장애 등
- 일부 환경에서는 connect timeout이
ConnectException으로 올라오기도 함
(권장) java.net.SocketTimeoutException: Connect timed out
Socket#connect(address, timeout)으로 명시적 연결 타임아웃을 걸었는데 시간 초과
Socket socket = new Socket();
socket.connect(new InetSocketAddress("192.168.1.250", 45678), 1000); // 1초 connect timeout
java.net.SocketTimeoutException: Read timed out
- 연결은 됐지만 응답이 지정 시간 내에 안 옴
- 기본값이 “무한 대기”에 가까운 경우가 있어 반드시 설정 권장
Socket socket = new Socket();
socket.connect(new InetSocketAddress(host, port), 1000);
socket.setSoTimeout(2000); // read timeout 2초
왜 read timeout이 중요한가?
- 외부 연동(C사) 한 곳이 느려지면, 그쪽을 기다리는 스레드가 누적되어 스레드 풀 고갈 → 전체 장애로 번질 수 있음
(주문 서버 → 결제사 A/B 정상, 결제사 C 지연 → 주문 서버 스레드가 C에서 묶임)
Reflection과 어노테이션
Reflection이란?
- 런타임에 클래스/메서드/필드 정보를 조회하고 동적으로 호출/접근하는 기능
- 프레임워크, DI 컨테이너, 직렬화/역직렬화, 테스트 도구 등에서 활용
어노테이션과의 연관성
- 어노테이션은 “메타데이터”이고, Reflection은 그 메타데이터를 읽어 동작을 바꾸는 수단
- 특히 어노테이션이
@Retention(RUNTIME)이면 런타임에 Reflection으로 조회 가능- 예: Spring이
@Component,@Transactional,@RequestMapping등을 스캔 → 빈 등록/프록시 생성/라우팅 구성
- 예: Spring이
간단 예:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Audit {}
class Service {
@Audit
public void pay() {}
}
// 런타임에 어노테이션 존재 여부 확인
Method m = Service.class.getMethod("pay");
boolean audited = m.isAnnotationPresent(Audit.class);
주의점(간단)
- Reflection은 성능 비용/캡슐화 침해/보안 이슈가 될 수 있어 남용은 피하고,
- 반복 호출 구간은 캐싱하거나(메타데이터 캐시), 대안(코드 생성, MethodHandle 등)을 고려한다.
'김영한의 실전 자바 - 고급 1편' 카테고리의 다른 글
| 김영한의 실전 자바 - 고급 1편(총 정리) (0) | 2026.01.26 |
|---|---|
| 김영한의 실전 자바 - 고급 1편(Executor) (0) | 2025.01.13 |
| 김영한의 실전 자바 - 고급 1편(동시성 컬렉션) (0) | 2025.01.11 |
| 김영한의 실전 자바 - 고급 1편(CAS) (1) | 2025.01.11 |
| 김영한의 실전 자바 - 고급 1편(생산자 소비자 문제: Object - wait/notify, ReentarantLock - await/signal, BlockingQueue) (1) | 2025.01.08 |