전체 글

전체 글

    [LLM] 응답 시간이 정해져 있을 때 - 5 초 안에 답해야 하는 챗봇 만들기

    5 초 안에 답해야 하는 챗봇을 만들려면 어떤 기술을 써야 할까.응답 속도가 제한된 환경에서는 모델의 출력 속도를 조절하거나 스트리밍 방식을 활용해야 한다.1. 일반 텍스트 생성response = client.chat.complete(request);전체 응답을 한 번에 받아야 할 때 이 방법을 쓴다.사용자가 내용을 다 읽은 후 다음 동작을 취할 수 있게 해준다.단, 5 초 안에 완료되지 않으면 사용자가 이탈할 위험이 크다.2. 스트리밍 응답client.chat.stream(request).forEach(System.out::println);문자 하나하나를 실시간으로 보내며 화면에 띄운다.전체 응답이 5 초 걸려도 첫 단어를 0.5 초 만에 보여준다.사용자가 기다리는 느낌을 줄여주는 가장 효과적인 방식이..

    [Java] List, Set, Map 차이

    Java Collections Framework 에는 List, Set, Queue, Deque 등의 Collection 계열과 별도의 Map 계열이 있으며, Map 은 Collection 의 하위 인터페이스가 아니다.순서가 중요하면 List 를 쓴다.1. ListList list = new ArrayList();list.add("A");list.add("B");System.out.println(list); // [A, B]순서를 완벽하게 유지하는 자료구조다.중복된 값을 저장할 수 있다.인덱스를 통해 원소에 접근할 수 있지만 성능은 구현체에 따라 다르다. ArrayList 의 인덱스 접근은 O(1)이지만 LinkedList 는 최악의 경우 O(n)이다.순서가 중요한 경우나 중복이 필요한 경우에 쓴다.Ar..

    [CS] 뮤텍스(Mutex)와 세마포어(Semaphore) 차이

    뮤텍스와 세마포어는 공유 자원을 보호하는 도구다.두 가지 모두 스레드 간 경쟁을 막아준다.하지만 내부 동작 방식과 용도가 다르다.1. 뮤텍스 기본 개념ReentrantLock lock = new ReentrantLock();lock.lock();try { // 임계 영역 작업 수행} finally { lock.unlock();}뮤텍스는 최대 하나의 스레드만 접근할 수 있게 막는다.한 번 잠그면 다른 스레드는 대기 상태로 들어간다.잠금 해제 시 대기 중인 스레드가 우선순위를 얻는 방식은 구현에 따라 달라질 수 있다.임계 영역을 보호할 때 주로 사용된다.단일 자원을 독점적으로 사용할 때 적합하다.2. 세마포어 기본 개념Semaphore sem = new Semaphore(2);sem.acquire..

    [Java] equals() 를 재정의하면 hashCode() 도 재정의해야 하는 이유

    객체는 기본값을 쓰면 주소로 비교된다.내용이 같아도 다른 개체로 인식된다.equals() 를 재정의하면 반드시 hashCode() 도 같이 고쳐야 한다.1. 기본 동작 이해하기class Person { String name;}Person a = new Person();a.equals(b); // 주소 비교로 falseObject의 기본 equals()는 ==와 마찬가지로 두 참조가 동일한 객체를 가리키는지 비교한다.내용이 같아도 주소가 다르면 false 가 된다.equals()를 재정의하지 않으면 기본 equals()는 객체의 동일성을 비교하지만, 필드를 직접 비교하는 등의 별도 코드로 내용 비교를 할 수 있다.2. hashCode() 의 역할Map map = new HashMap();Person ..

    [JPA] 즉시 로딩 (EAGER) 과 지연 로딩 (LAZY) 차이

    엔티티의 관계 필드를 조회할 때 언제 데이터를 가져올지 정하는 정책이다.즉시 로딩은 관련 데이터를 바로 함께 가져오는 방식이다.지연 로딩은 실제 필요할 때까지 관련 데이터를 나중에 가져오는 방식이다.1. 즉시 로딩 (EAGER)@ManyToOne(fetch = FetchType.EAGER) private Department dept;엔티티를 조회하는 순간 관계된 데이터를 같이 가져온다.EAGER는 관계 데이터의 로딩 시점을 정하는 정책이며, JOIN이나 단일 쿼리 실행을 보장하지 않는다. 구현체와 조회 방식에 따라 JOIN 대신 추가 SELECT로 관계 데이터를 가져올 수 있다.관계 필드를 바로 쓸 때 편리하지만 불필요한 데이터가 포함될 수 있다.대형 테이블이 많을 경우 성능 저하와 메모리 사용량 증가를..

    [Spring] @RequestParam 과 @PathVariable 차이

    @RequestParam 은 URL 의 쿼리 스트링에 값을 담는다.예를 들어 ?name=홍길동 처럼 파라미터가 붙는 방식이다.반면 @PathVariable 는 URL 경로 자체에 변수를 넣는다./users/{id} 에서 {id} 위치에 값을 채우는 방식이다.쿼리 스트링은 여러 개를 동시에 받을 수 있다.경로 변수는 URL 구조에 딱 맞는 값만 들어간다.1. @RequestParam@GetMapping("/search")public String search(@RequestParam String query) { return "검색 결과: " + query;}이 코드는 GET 요청 시 ?query=스프링 을 받는다.쿼리 스트링은 여러 파라미터를 나열할 수 있다.예를 들어 ?query=스프링&sort=as..

    [CS] TCP 와 UDP 차이

    TCP 와 UDP 는 인터넷 통신의 두 가지 핵심 프로토콜이다.두 프로토콜은 목적지가 같지만 동작 방식과 사용처가 완전히 다르다.1. 연결 유무Socket tcp = new Socket(); // 연결 필요DatagramSocket udp = new DatagramSocket(); // 연결 불필요TCP 는 통신 전에 반드시 연결을 맺고 끊는다.연결이 없으면 데이터 전송 자체가 불가능하다.UDP 는 연결 없이 바로 데이터를 날려버린다.빠른 응답이 필요할 때 UDP 가 유리한 이유다.안정성이 최우선이라면 TCP 를 선택해야 한다.2. 데이터 신뢰성byte[] tcpData = "파일 전체".getBytes(); // 순서 보장byte[] udpData = new byte[1500]; // 순서 무관TCP ..

    [Java] 추상 클래스와 인터페이스 차이

    추상 클래스는 어떤 기능을 구현할지 정의하는 템플릿이다.인터페이스는 외부에서 사용할 수 있는 기능의 약속을 담는다.1. 구조적 차이public abstract class Animal {}추상 클래스는 extends 키워드로 하나만 상속받을 수 있다.인터페이스는 implements 키워드를 통해 여러 개 구현할 수 있다.클래스의 경우 변수나 생성자를 직접 정의해서 사용할 수 있다.2. 메서드 구현 방식abstract void eat(); // 추상메서드만 가능void sleep() {} // 일반메서드 가능추상 클래스는 추상메서드와 일반 메서드를 모두 정의할 수 있다.인터페이스는 자바 8 이전에는 추상메서드만 존재했다.자바 8 이후 default 와 static 메서드가 추가되어 변경되었다.3. ..

    [HTTP] GET 과 POST 의 차이

    HTTP 의 두 주요 메서드인 GET 과 POST 는 어떤 차이가 있을까?GET 은 서버에 데이터를 요청하는 용도로, POST 는 서버로 데이터를 전송할 때 쓴다.1. 데이터 위치GET /search?q=카트라이더POST /api/logindata: {"id":"user","pw":"1234"}GET 은 URL 에 파라미터를 붙여 데이터를 보낸다.POST 는 HTTP 헤더와 구분되는 요청 본문(Body)에 데이터를 담아 전송한다.URL 에 데이터가 들어가면 주소창에 그대로 표시된다.POST 는 화면에 노출되지 않아 보안상 유리한 편이다.2. 데이터 길이 제한// GET 은 브라우저마다 한계가 있다.GET /search?q=매우긴문장+여러개... // 에러 발생 가능// POST 는 헤더 설정으로 길이를 ..

    [Spring] @Component, @Service, @Repository 차이

    스프링 빈을 등록할 때 어떤 어노테이션을 써야 할지 고민된다면 이 글을 보자.컴포넌트 스캔으로 자동으로 감지하는 기본 스테레오 타입들이다.1. @Component@Componentpublic class MyBean {}모든 스프링 빈을 등록할 때 쓸 수 있는 가장 일반적인 어노테이션이다.특정 역할을 명시하지 않고 단순히 객체를 관리할 때 사용한다.컨테이너가 이를 스캔해서 빈으로 등록하고 의존성 주입을 처리한다.2. @Service@Servicepublic class UserService {}비즈니스 로직이 포함된 서비스 계층을 정의할 때 쓴다.기능적 의미는 @Component 와 동일하지만 코드 가독성을 높여준다.팀원들이 어떤 클래스가 비즈니스 역할을 하는지 한눈에 알 수 있다.3. @Repository..

    [Database] 인덱스를 만들었는데 안 타는 경우

    인덱스를 만들었음에도 불구하고 쿼리가 느린 이유는 무엇일까?인덱스는 검색 속도를 높이기 위한 자료 구조지만 모든 조건에서 효과가 있는 것은 아니다.1. select * 사용 시SELECT * FROM users WHERE id = 1;select * 를 쓰면 인덱스 스캔 이후 전체 행을 가져와야 한다.이때 DB 는 인덱스 대신 테이블 전체를 읽는 방식인 Table Scan 을 선택할 수 있다.필요한 컬럼만 명시적으로 선택해야 인덱스를 효율적으로 활용할 수 있다.2. 함수 적용 시SELECT * FROM users WHERE YEAR(reg_date) = 2023;컬럼에 함수를 적용하면 인덱스를 직접 사용할 수 없게 된다.DB 는 먼저 모든 행을 가져와서 함수 계산 후 필터링해야 하기 때문이다.함수 대신 ..

    [JavaScript] var, let, const 차이

    자바스크립트에서 변수를 선언할 때 무엇을 써야 할지 고민되는가? var, let, const의 핵심 차이는 스코프와 재할당 가능 여부에 있다. 상황에 맞는 적절한 키워드를 선택하는 것이 버그를 줄이는 첫걸음이다.1. 변수의 유효 범위: 스코프(Scope)var는 함수 레벨 스코프를 가진다. 함수 내부에서 선언된 변수만 지역 변수로 인정하며, if문이나 for문 같은 블록 내부에서 선언해도 외부에서 접근이 가능하다. 반면 let과 const는 블록 레벨 스코프를 따른다. 중괄호 `{}`로 둘러싸인 모든 블록을 기준으로 유효 범위가 결정된다.if (true) { var varVariable = 'I am var'; let letVariable = 'I am let'; const constVariable..