크리스마스 이브를 맡아 간단한 Java/CS 관련 문제를 풀어보는 게임을 진행하였습니다. 게임을 진행하면서 몰랐던 내용들과 알았지만 키워드의 뜻을 제대로 인지하지 않아 작성하지 못한 문제들이 있었습니다. 이에 대한 내용을 정리합니다.
super
class Parent {
void display() {
System.out.println("부모 클래스");
}
}
class Child extends Parent {
void display() {
// 부모 클래스의 생성자를 호출
super();
// 부모 클래스의 display() 호출
super.display();
// 부모 클래스의 필드에 접근
super.fieldName
System.out.println("자식 클래스");
}
}
finally
try {
// 예외가 발생할 수 있는 코드
int result = 10 / 0;
} catch (Exception e) {
// 예외 처리
System.out.println("예외 발생!");
} finally {
// 항상 실행되는 코드
System.out.println("finally 블록 실행");
}
StringBuilder & StringBuffer
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString(); // "Hello World"
implements
interface Animal {
void sound();
void move();
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println("멍멍!");
}
@Override
public void move() {
System.out.println("네 발로 걷기");
}
}
데이터를 저장하고 처리하기 위한 자료구조 클래스들의 집합입니다.
개념
사용 이유
주요 인터페이스 & 클래스
특정한 키를 통해 값을 빠르게 조회할 수 있는 구조를 제공합니다.
사용 이유
// 1. 선언
HashMap<String, Integer> map = new HashMap<>();
// 2. 데이터 추가 및 수정
map.put("A", 1); // 키가 "A"인 값에 1 저장
map.putIfAbsent("A", 10); // "A"키가 없을 때만 10 저장
int value = map.getOrDefault("B", 0);// "B"키 조회, 없으면 기본값 0
// 3. 존재 여부 확인
if (map.containsKey("A")) { ... } // "A"키 존재 여부 확인
if (map.containsValue(1)) { ... } // 값 1 존재 여부 확인
// 4. 삭제
map.remove("A"); // "A"키 삭제
map.clear(); // 전체 삭제
// 5. 값 변경하기 (다양한 방법)
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Kim", 80);
// 5-1. 일반적 방식
if (scores.containsKey("Kim")) {
scores.put("Kim", scores.get("Kim") + 10);
}
// 5-2. compute 활용 (람다 사용)
scores.compute("Kim", (key, oldVal) -> oldVal + 10);
// 5-3. 키가 있을 때만 변경 (computeIfPresent)
scores.computeIfPresent("Kim", (key, oldVal) -> oldVal + 10);
// 6. 크기 확인
int size = map.size();
boolean isEmpty = map.isEmpty();
같은 값이 2번 이상 등장하는 것을 허용하지 않고, 각 요소는 유일한 값을 지닌 자료구조입니다.
사용 이유
// 1. 선언
HashSet<String> set = new HashSet<>();
// 2. 데이터 추가 및 삭제
set.add("A"); // 요소 "A" 추가 (중복 요소는 추가되지 않음)
set.remove("A"); // "A" 삭제
set.clear(); // 모든 요소 삭제
// 3. 데이터 확인
boolean exists = set.contains("A"); // "A"가 존재하는지 확인
int size = set.size(); // Set의 크기 확인
boolean empty = set.isEmpty(); // 비었는지 확인
// 4. 집합 연산
Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();
// 합집합: set1에 set2의 요소 모두 추가
set1.addAll(set2);
// 교집합: set1과 set2에 모두 있는 요소만 남김
set1.retainAll(set2);
// 차집합: set1에서 set2의 요소 제거 (set1 - set2)
set1.removeAll(set2);
어노테이션은 자바 코드에 메타 데이터를 추가하여 코드에 특별한 의미를 부여하거나, 컴파일러와 런타임에 특정 동작을 트리거하기 위해 사용됩니다.
Lombok 라이브러리
주요 Lombok Annotation
@Getter, Setter@ToStringtoString() 메서드를 자동으로 생성합니다.@NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor@Slf4jLogger 객체를 자동으로 생성합니다.서버에서 실행되어 클라이언트의 요청을 처리하고, 그 결과를 동적으로 생성하여 응답하는 자바 프로그램입니다.
자바 웹 애플리케이션에서 특정 URL 요청에 대한 비즈니스 로직을 실행하는 핵심입니다.
역할
jakarta.servlet.HttpServlet 클래스를 상속받아 구현합니다.서블릿 컨테이너
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 요청 정보는 필요없으므로 요청 정보를 꺼내지는 않습니다.
// 비즈니스 로직 또한 따로 없으므로 작성하지 않습니다.
resp.setContentType("text/plain; charset=UTF-8"); // 응답 정보 타입 설정
resp.getWriter().print("hello"); // Response 객체에 응답 정보인 'hello'를 담아줍니다.
}
서블릿의 문제점
HttpServletRequest, HttpServletResponse 와 같은 서블릿 API에 직접적으로 의존합니다. 이로 인해 웹 환경 밖에서 단위 테스트를 수행하기가 매우 까다로워 집니다.MVC
서블릿이 혼자 모든 것을 처리하던 문제를 해결하기 위해 애플리케이션의 코드를 세 가지 역할로 명확하게 나누는 설계 방식입니다.
SSR & CSR
프론트 컨트롤러 패턴
어댑터 패턴
// HandlerAdapter 인터페이스 (공통 인터페이스)
public interface HandlerAdapter {
boolean supports(Object handler); // 처리 가능 여부 판단(boolean)
ModelAndView handle( // 어떻게 처리할 것인지에 대한 로직
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception;
}
// Controller 구현 1 (HandlerAdapter를 implements)
public class RequestMappingHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof HandlerMethod; // @RequestMapping 메서드인지 확인
}
@Override
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// @Controller 방식으로 처리
return invokeHandlerMethod((HandlerMethod) handler, request, response);
}
}
// Controller 구현 2 (HandlerAdapter를 implements)
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof Controller;
}
@Override
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// Controller 인터페이스 방식으로 처리
return ((Controller) handler).handleRequest(request, response);
}
}
DispatcherServlet

@Controller
public class HelloController {
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("message", "Hello, Spring!");
return "hello"; // view
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello Page</title>
</head>
<body>
<h1 th:text="${message}">(메시지가 보여지는 곳)</h1>
</body>
</html>