5 분 소요


JPQL

JPQL은 엔티티 객체를 조회하는 객체지향 쿼리다.
즉, 테이블을 대상으로 쿼리하는 것이 아닌, 엔티티 객체를 대상으로 쿼리한다.
SQL과 비슷한 문법을 가지며, JPQL은 결국 SQL로 변환된다.
JPA에서 제공하는 메소드 호출만으로 섬세한 쿼리 작성이 어렵다는 문제에서 탄생했다.

특징

  • 테이블이 아닌 객체를 검색하는 객체지향 쿼리
  • SQL을 추상화 했기 때문에 특정 벤더에 종속적이지 않다.
  • JPA는 JPQL을 분석하여 SQL을 생성한 후 DB에서 조회.


함수형 프로그래밍

함수형 프로그래밍은 부수 효과가 없는 순수 함수를 이용하여 프로그램을 만드는 것으로, 상태 변화와 가변 데이터를 멀리하는 프로그래밍 패러다임이다.
거의 모든 것을 순수 함수로 나누어 문제를 해결하는 기법으로, 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지 보수를 용이하게 해준다.

장점

  • 높은 수준의 추상화를 제공한다.
  • 더 나은 모듈화와 짧은 코드를 제공한다.
  • 개발 생산성을 높일 수 있다.
  • 가독성이 높은 코드를 작성하기 쉽다.
  • 부수효과를 제거할 수 있다.
  • 함수 단위의 코드 재사용이 쉽다.
  • 프로그램의 동작을 예측하기 쉽다.

단점

  • 수 많은 함수들을 파악하고, 유지 관리하기 힘들다.
  • 함수가 많아질 수록 함수를 조합하기 복잡해지며, 꾸준한 리팩토링이 필요할 수 있다.


Java11 사용 이유

Java8의 기능을 수용하면서 더 나은 라이브러리가 추가 되었고, 성능이 개선된 G1 GC를 사용하기 때문이다.
또한, Java11은 장기적인 지원이 보장된 버전이므로 앞으로도 유익한 기능이 나올 것이기 때문이다.

Java11의 Default GC는 G1 GC이다.

Java8 추가 기능

함수형 인터페이스

하나의 기능을 제공하는 단 하나의 추상 메소드를 정의하는 인터페이스.
단, 추상 메소드 외에 디폴트 메소드나 정적 메소드는 마음껏 사용할 수 있다.
@FunctionalInterface와 함께 쓰이며, 만약 추상 메소드가 여러 개라면 컴파일 타임에서 에러를 잡아낼 수 있다.
주요 함수형 인터페이스는 Consumer, Supplier, Function 등이 있다.

람다 표현식

메소드를 하나의 식으로 표현한 것을 말하며, 람다식은 함수의 이름이 없기 때문에 익명 함수라고도 부른다.
익명 함수는 메소드의 매개 변수로 전달되거나 메소드의 결과로 반환될 수 있는 특징이 있어서, 함수를 변수처럼 다룰 수 있다는 장점이 있다.
주로 함수형 인터페이스의 익명 객체를 대체하기 위해 람다식을 사용하며, 간결하고 부수 효과가 없는 코드를 만들어 낼 수 있게 된다.

Stream API

스트림은 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 내부 반복자이다.
스트림은 람다식으로 요소 처리 내용만 전달할 뿐, 반복은 컬렉션 내부에서 일어난다.
따라서, 개발자 입장에서 작성할 코드가 간결해진다.

Optional API

Java8에서는 Optional 클래스를 사용해 NPE(NullPointerException)를 방지할 수 있도록 도와준다.
Optional는 **null이 올 수 있는 값을 감싸는 Wrapper 클래스**로, 참조하더라도 NPE가 발생하지 않도록 도와준다.
Optional 클래스는 값이 null이더라도 바로 NPE가 발생하지 않으며, 클래스이기 때문에 각종 메소드를 제공해준다.

public final class Optional<T> {

    private final T value;

    ...
}

LocalDateTime API

LocalDate
Local 날짜 클래스로 날짜 정보만 필요할 때 사용.

// 로컬 컴퓨터의 현재 날짜 정보를 저장한 LocalDate 객체를 리턴
LocalDate currentDate = LocalDate.now();

// 파라미터로 주어진 날짜 정보를 저장한 LocalDate 객체를 리턴
LocalDate targetDate = LocalDate.of(2023, 07, 07);


LocalTime
Local 시간 클래스로 시간 정보만 필요할 때 사용.

// 로컬 컴퓨터의 현재 시간 정보를 저장한 LocalTime 객체를 리턴
LocalTime currentTime = LocalTime.now();

// 파라미터로 주어진 시간 정보를 저장한 LocalTime 객체를 리턴
// 4번째 매개변수는 nanoSecond로 선택 값이다.
LocalTime targetTime = LocalTime.of(12,33,35,22);


LocalDateTime
날짜와 시간 정보 모두가 필요할 때 사용.

LocalDateTime currentDateTime = LocalDateTime.now();


G1 GC

G1은 Garbage First의 약어로 Garbage만 있는 Region을 먼저 회수한다고 해서 붙여진 이름이다.
빈 공간 확보를 빨리 한다는 것은 급격히 할당률이 늘어나는 것을 방지하여 Old Generation을 비교적 한가하게 만들 수 있다.

CMS GC보다 효율적으로 동시에 Application과 GC를 진행할 수 있고, 메모리 Compaction 과정까지 지원하고 있다.

Compaction은 퍼포먼스 향상을 위해 참조되지 않은 객체를 제거하고 남은 객체를 묶는 작업이다.
묶음으로서 공간이 생기므로 새로운 메모리 할당 시 더 쉽고 빠르게 진행할 수 있다.

CMS GC

Concurrent Mark-Sweep(CMS) GC는 Application의 Thread와 GC Thread가 동시에 실행되어 STW를 최소화 하는 GC이다.
CMS GC는 Compaction을 지원하지 않는다.


동기, 비동기

metrix

Sync / Async는 호출된 함수의 종료를 호출한 함수가 처리하는지, 호출된 함수가 처리하는지의 차이다.

동기(Synchronous)

  • A함수가 B함수를 호출 할 때, B함수의 결과를 A함수가 처리하는 것.
  • 요청을 보내고 실행이 끝나면 다음 동작을 처리하는 방식
  • 순서에 맞추어 진행되기 때문에 제어하기 쉽다.
  • 여러가지 요청을 동시에 처리할 수 없어 효율이 떨어진다.
  • Ex) 콜센터 직원

비동기(Asynchronous)

  • A함수가 B함수를 호출 할 때, B함수의 결과를 B함수가 처리하는 것.(callback)
  • 요청을 보내고 해당 동작의 처리 여부와 상관없이 다음 요청이 동작하는 방식
  • 작업이 완료되는 시간을 기다릴 필요가 없기 때문에 자원을 효율적으로 사용할 수 있다.
  • 작업이 완료된 결과를 제어하기 어렵다.
  • Ex) 이메일

장단점

  • 동기
    • 장점 : 설계가 매우 간단하고, 직관적이다.
    • 단점 : 결과가 주어질 때 까지 아무것도 못하고 대기해야 한다.
  • 비동기
    • 요청에 따른 결과가 반환되는 시간 동안 다른 작업을 수행할 수 있다.
    • 동기식보다 설계가 복잡하다.


Blocking / Non-blocking은 호출된 함수가 호출한 함수에게 제어권을 넘겨주는지의 차이다.

Blocking

  • A함수가 B함수를 호출 할 때, B함수가 자신의 작업이 종료되기 전까지 A함수에게 제어권을 돌려주지 않는 것.

Non-blocking

  • A함수가 B함수를 호출 할 때, B함수가 제어권을 바로 A함수에게 넘겨주면서, A함수가 다른 일을 할 수 있도록 하는 것.


TCP와 UDP 차이점

TCP와 UDP는 둘 다 전송 계층에서 데이터를 보내기 위해 사용하는 프로토콜이다.
TCP는 연결형 서비스로 가상회선 방식을 제공하고, 높은 신뢰성을 보장하며 흐름 제어 및 혼잡 제어 기능을 제공한다.
UDP는 비연결형 서비스로 데이터그램 방식을 제공하고, 패킷에 순서 부여나 재조립등의 기능을 처리하지 않기 때문에 연속성이 중요한 서비스에 사용된다.


SQL Injection

SQL Injection이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL문을 주입하고, 실행되게 하여 DB가 비정상적인 동작을 하도록 조작하는 행위.

공격 종류 및 방법

논리적 에러를 이용한 Injection

논리적 에러를 이용한 SQL Injection은 가장 많이 쓰이고, 대중적인 공격 기법이다.

예시
SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'
위 쿼리문은 일반적으로 로그인 시 많이 사용되는 SQL 구문이며, 해당 구문에서 입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 다음과 같이 임의의 SQL 구문을 주입.

SELECT * FROM Users WHERE id = ' ' OR 1=1 -- AND password = 'INPUT2'
=> SELECT * FROM Users

OR 1=1 --라는 구문을 이용해 WHERE 절을 모두 참으로 만들고, –를 넣어줌으로 뒤의 구문을 모두 주석처리.

Union 명령어를 이용한 Injection

Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드이다.
정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다.

조건

  • Union하는 두 테이블의 컬럼 수가 같아야 한다.
  • 두 테이블의 데이터 형이 같아야 한다.

예시
SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%'
Board라는 테이블에서 게시글을 검색하는 쿼리문이다.

SELECT * FROM Board WHERE title LIKE '% UNION SELECT null,id,passwd FROM Users --%' ...
입력값으로 Union 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐져서 하나의 테이블로 보여지게 되고, 성공하면 사용자의 개인정보가 게시글과 함께 화면에 보여지게 된다.

Blind SQL Injection

DB로 부터 특정 값이나 데이터를 전달받지 않고, 단순히 참/거짓의 정보만 알 수 있을 때 사용한다.
예를 들어 로그인 폼에 SQL Injection이 가능하다고 가정했을 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보 등을 추출해 낼 수 있다.

대응 방안

Prepared Statement 구문 사용

쿼리의 문법 처리 과정이 미리 컴파일이 되어 있기 때문에, 외부 입력값으로 SQL 관련 구문이나 특수문자가 들어와도, 그것은 SQL 문법으로서 역할을 할 수 없다.

Error Message 노출 금지

공격자가 SQL Injection을 수행하기 위해서는 DB의 정보(테이블명, 컬럼명 등)가 필요하다.
DB 에러 발생 시 따로 처리를 해주지 않으면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환해 준다.
여기서 중요한 정보들이 노출될 수 있기 때문에, 사용자에게 보여줄 수 있는 페이지를 제작하는 것이 좋다.

댓글남기기