이 토마토 문제는 골드5 문제로 실버 단계에서 풀던 bfs 공식 으로 풀리지가 않았다. 기존 bfs의 공식이라 함은 for문을 돌아서 1을 찾은 다음 바로 큐에 담고 방문체크를 한 다음에 bfs를 돌리는 것인데 똑같이 이렇게 푸니 절대로 풀리지 않는 문제가 있었다. 기존 풀이 코드 for (int i = 0; i < mapZ; i++) { for (int j = 0; j < mapY; j++) { for (int k = 0; k < mapX; k++) { if (map[i][j][k] == 1 && !isVisited[i][j][k]) { isVisited[i][j][k] = true; bfs(i, j, k); } } } } 직면한 문제와 해결 방법 만약 입력이 아래 처럼 주어졌을 때 밑에 1을 찾아 바..
DB에서 데이터를 조회하는 것은 애플리케이션 서버 안에서 실행되는 메서드 보다 비교도 안될 정도로 시간 비용이 많이 든다. 그래서 DB에서 데이터를 조회하는 것을 최소화하는 것이 성능 최적화의 중요 요점이라고 볼 수 있다. JPA 동작원리 애플리케이션 내에서 EntityManager는 EntityManagerFactory 객체에서 만들어지는데 EntityManagerFactory객체는 한개만 있고 EntityManager는 여러개 만들어 낸다. EntityManager는 한개의 트랜잭션을 가질 수 있다. EntityManager가 관리하는 트랜잭션 내에서 애플리케이션 성능을 높이기 위해 영속성 컨텍스트라는 개념이 나온다. 영속성 컨텍스트란 JPA 내부 동작 방식을 이해하려면 영속성 컨텍스트를 이해해야 하..
@Entity 사용 유의사항 1. @Entity를 매핑해서 사용할 클래스는 기본생성자는 필수다(public 또는 protected 생성자) JPA 구현체들은 클래스의 인스턴스를 생성할 때 기본 생성자를 필요로 한다. 기본 생성자가 없으면 JPA 구현체가 클래스의 인스턴스를 생성할 수 없다. 또한 JPA는 성능 최적화를 위해 프록시 패턴을 사용하는데 프록시 객체를 생성하는데 기본 생성자가 필요하다. 2. Final 클래스, enum, interface, inner 클래스에는 사용할 수 없다. Final 클래스는 상속이 안되므로 프록시 객체를 생성하지 못한다. 3. DB에 저장할 필드에 final을 사용하면 안된다. JPA는 엔티티를 영속성 컨텍스트에서 관리하고 데이터베이스와 상호 작용할 때 필드의 값을 ..
버전및 세팅 Springboot 3.0.2 DB: embadded H2 자바: 17 plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' } UUID 적용 사유 아래 처럼 id를 Long 타입으로 주고 글이 하나 생길때마다 하나씩 늘어나는 방식으로 줬다면 글이 총 몇개있는지 파악할 수 있다. 전체 개수가 몇개인지 파악되는 것을 꺼려할수도 있기 때문에 id를 암호화 하거나 UUID로 변경해야 한다. @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatabl..
https://www.acmicpc.net/problem/2178 2178번: 미로 탐색 첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다. www.acmicpc.net 이 문제는 (1,1) 위치에서 (N,M) 위치로 가는데 최소 칸수를 구하는 문제이다. 최단 경로 문제는 BFS 를 사용하면 된다고 생각하면 된다. BFS는 갈 수 있는 인접한 경로를 모두 방문하기 때문에 최초 방문된 시점이 출발 노드점에서 갈 수 있는 가장 빠른 경로이기 때문이다. 그래서 이문제도 BFS로 풀면 된다. 최단경로 문제는 BFS로 푼다는 걸 공식처럼 생각하면 된다. 시간 복잡도는 인접 행렬을 사용할거기 때문에 N, ..
Stream은 Java8에서 처음 도입 되었으며, stream은 연속된 데이터들을 처리할 수 있는 기능의 모음이다. stream 작업은 아래 그림과 같이 stream 파이프라인(pipeline)으로 구성되는데 1개의 소스(Array, Collection 등)과 0개이상의 중간 작업과 마지막 1개의 종료 작업으로 끝이 난다. Strem 특징 1. 스트림 소스 생성 종료 작업은 1개만, 중간연산은 여러개 가능하다. 스트림 소스 생성과 종료 작업은 1개만 있을수 있어서 중간 작업과 같이 여러개 있을 수 없다. 만약 한개의 스트림 파이프라인에서 종료 작업을 여러번 하면 에러가 난다. 그리고 중간 작업을 여러번 한다고 해서 원본 소스 데이터를 변경하지 않는다. 2. 지연 연산(LAZY Evaluation) 또한 ..
제네릭스 사용 이유 제네릭스를 알려면 우선 타입변수를 알아야 한다. 타입변수는 일반적으로 제네릭스를 사용하는 ArrayList, Set 등 컬렉션에서 볼 수 있는데, 아래 보이는 가 타입 변수다. 제네릭스를 사용하지 않으면 모든 형태의 데이터를 담을수 있게 Object로 되어 있어야 하고 데이터를 사용하려면 Object의 데이터를 꺼내서 형변환이 필요하고, 또 다른 타입의 데이터를 넣었을때 형변환해서 사용하기 전까지 알수가 없다. List list = new ArrayList(); list.add("hello"); String s = (String) list.get(0); 하지만 제네릭스를 사용하면 형변환 할필요가 없고, 데이터를 add 하는 시점에서 데이터 타입이 String이 아니라면 에러가 난다. ..
로컬 스토리지는 key : value 쌍으로 이루어져 있는 데이터 이며, Value는 JSON 형태를 이루고 있는 문자열 이여야 한다. 스토리지를 사용할 때 로컬 스토리지와 세션 스토리지를 사용하는데 로컬 스토리지는 웹브라우저를 닫아 세션이 끊겨도 데이터가 영구적으로 보관된다. 그래서 중요한 데이터는 저장하지 않는다. 로컬 스토리지와 세션 스토리지의 데이터를 보려면 개발자 도구 -> Application에서 확인 할 수 있다. [로컬 스토리지 적용 이유] 회사에서 로컬스토리지를 이용한 이유는 리스트에서 열을 이동하고 검색을 하거나 다시 리스트를 불러 올때도 열이 이동된 상태로 유지되게 해달라는 요청 때문이였다. 먼저 위와 같이 Status 열을 오른쪽으로 옮길수 있어야 되는데 이 옵션은 reorderab..
스프링을 이해하는데 POJO(Plain Old Java Object)를 기반으로 스프링 삼격형이라는 애칭을 가진 IoC/DI, AOP, PSA라고 하는 스프링 3대 프로그래밍 모델에 대한 이해가 필수다. IoC/DI 이해와 전략 패턴 IoC(Inversion of Control)는 제어의 역전 DI(Dependency Injection) 의존성 주입 이라고 한다. 의존 관계라는 것은 프로그래밍에서 new 객체 생성을 뜻한다. 아래 소스를 보면 Car 클래스에서 생성자를 통해 tire 객체를 new 로 생성해서 필드에 주입한다. 이 과정에서 Car 클래스는 Tire 클래스에 의존한다 라는 뜻이 된다. public class Car { Tire tire; public Car() { tire = new Kor..
BFS(Breadth First Search, BFS)는 주로 최단거리나 최단 시간등 목표 상태에 도달할 수 있는 가장 빠른 경로를 탐색하는데 활용된다. 왜냐하면 BFS는 인접한 노드들에 대해서 모두 방문을 하기 때문에 방문한 시점이 가장 최단 경로의 시점이기 때문이다. BFS 문제 풀이 순서 1. input 단계에서 방문 체크 isVisited 배열과 , 방문 경로 map의 배열, 방문체크 dy, dx 배열을 만든다 2. for문을 돌아서 map에서 방문 위치를 찾아낸다. 3. 찾은 위치를 Queue에 넣고, 방문 체크를 한다. 4. Queue에서 뽑은 map위치에서 방문 경로를 뒤진다. 5. 방문 경로에서 조건에 맞으면 Queue에 넣는다. Queue가 다 비워질때 까지 계속 방문 경로를 뒤지고 조건..
OCP - 개방 폐쇄 원칙 소프트웨어 엔티티(클래스, 모듈, 함수 등)는 확장에 대해서는 열려 있어야 하지만 변경에 대해서는 닫혀 있어야 한다. by 로버트 C. 마틴 위 말을 의역하면 "자신의 확장에는 열려 있고, 주변의 변화에 대해서는 닫혀 있어야 한다" 이렇게 된다. 말만 들으면 이해하기 어렵지만 이 원칙을 지킨 디자인 패턴중 대표적으로 어댑터 패턴이 있다. 즉 어댑터 패턴을 이해하면 OCP를 이해할 수 있다. 어댑터 패턴(Adapter Pattern) 어댑터를 번역하면 변환기(converter)라고 할 수 있다. 대표적으로 110V 인터페이스를 -> 220V 인터페이스로 변환해준 어댑터를 생각하면 쉽다. 위 처럼 서로 다른 두개의 인터페이스가 연결이 가능하게끔 해주는 것이고, 이것을 프로그래밍화 ..
SOLID 원칙 객체지향 설계 OOD(Object Oriented Design)의 정수라고 할 수 있는 5원칙이 집대성 됐는데 바로 이것이 SOLID 이다. SOLID는 아래 5가지 원칙의 앞 머리 알파벳을 따서 부르는 이름이다. SRP(Single Responsibility Principle): 단일 책임 원칙 OCP(Open Closed Principle): 개방 폐쇄 원칙 LSP(Liskov Substitution Principle): 리스코프 치환 원칙 ISP(Interface Segregation Principle): 인터페이스 분리 원칙 DIP(Dependency Inversion Principle): 의존 역전 원칙 위 원칙들은 응집도(High Cohesion)는 높이고, 결합도(Loose ..
* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.