String의 hashCode()

Java의 String의 hashCode() 메소드는 같은 문자열이면 같은 값이 나온다. 하지만 반환값이 int기 때문에 오버플로우가 발생해서 음수가 나올 수 있다는 것도 충분히 고려해야된다. 만약 String의 hashCode를 이용해서 추가적인 작업을하는데 0부터 시작하길 원한다면 아래처럼 구현하면 된다. long avatarIndex = ((long) nickname.hashCode() - Integer.MIN_VALUE) % NUMBER_OF_AVATAR;

2024-09-15 · 1 min · 43 words

String을 뒤집는 방법

StringBuilder에 reverse 기능이 존재한다. String reversed = new StringBuilder(original).reverse().toString() 참고 자료 https://stackoverflow.com/questions/7569335/reverse-a-string-in-java

2024-09-15 · 1 min · 12 words

String을 LocalDate로 변환하기

DateTimeFormatter 로 문자열의 날짜 형식을 지정하고 파싱하면된다. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/MM/yyyy"); String date = "16/08/2016"; //convert String to LocalDate LocalDate localDate = LocalDate.parse(date, formatter); 참고 자료 https://mkyong.com/java8/java-8-how-to-convert-string-to-localdate/

2024-09-15 · 1 min · 27 words

String으로 원하는 Enum 찾기

Enum에 valueOf() 메서드를 이용하면 된다. 참고 자료 https://stackoverflow.com/questions/604424/how-to-get-an-enum-value-from-a-string-value-in-java

2024-09-15 · 1 min · 8 words

String안에 특정 문자의 마지막 인덱스 찾기

abc.txt.jpg 같은 파일이름을 파싱할 때, 확장자를 jpg로 구하기 위해서 ‘.‘문자의 마지막 인덱스 위치를 알아야 됐다. fileName.lastIndexOf(FILE_EXTENSION_DELIMITER); Java에 String의 메소드로 lastIndexOf라는 메소드가 있어서 쉽게 구현할 수 있었다.

2024-09-15 · 1 min · 26 words

Stream을 collection으로 만든 후 추가 적인 작업이 필요한 경우

passengers.stream() .map(name -> new Person(name)) .collect(Collectors.collectingAndThen(Collectors.toList(), Bus::new)); collectingAndThen()메소드를 활용하면 된다. 참고 자료 https://stackoverflow.com/questions/52382157/continue-mapping-after-stream-collect

2024-09-15 · 1 min · 13 words

stream에서 findFirst(), findAny() 사용시 NPE

배경 null 값을 가지고 있는 stream에서 findFirst() 메서드를 호출하니 NullPointerException이 발생했다. 원인 공식 문서를 읽어보니 선택된 요소가 null이면 NullPointerException이 발생한다. 비어있는 Optional이 반환되는 경우는 stream이 비어있는 경우만 해당된다. 참고 자료 https://docs.oracle.com/javase/10/docs/api/java/util/stream/Stream.html#findFirst()

2024-09-15 · 1 min · 31 words

Stream groupingBy

어떤 객체의 List가 있을 때, 객체의 특정 필드값을 기준으로 묶는 과정이 필요했다. 그 때, stream의 groupingBy 을 사용하면된다. 예를들어, 블로그 포스트를 타입별로 묶고싶은 경우 아래 예시를 보면된다. class BlogPost { String title; String author; BlogPostType type; int likes; } enum BlogPostType { NEWS, REVIEW, GUIDE } Map<BlogPostType, List<BlogPost>> postsPerType = posts.stream() .collect(groupingBy(BlogPost::getType)); 참고 자료 https://www.baeldung.com/java-groupingby-collector

2024-09-15 · 1 min · 55 words

state, props

state와 props 둘 다 react의 구성요소인 컴포넌트를 렌더링하기 위한 정보를 담고 있다. state는 컴포넌트 안에서 관리되는 반면, props는 컴포넌트에게 정보를 전달하는 용도로 사용한다. setState() setState() 함수를 이용해서 state의 값을 변경하면 컴포넌트가 리렌더링된다. setState() 함수는 비동기로 처리되기때문에, 이 함수를 호출했다고 바로 state가 변경될거라고 생각하면 안된다. state의 이전값을 기준으로 값을 변경하고 싶다면 아래와 같이 함수를 전달하는 방식으로 구현해야된다. this.setState((state) => { // 중요: 값을 업데이트할 때 `this.state` 대신 `state` 값을 읽어옵니다. return {count: state....

2024-09-15 · 1 min · 78 words

SSH 접근을 위한 public private key 생성하기

ssh-keygen 이라는 명령어를 통해서 생성할 수 있다. ssh-keygen 위와 같이 아무를 옵션없이 키 쌍을 생성하면, ~/.ssh/id_rsa.pub 라는 파일에 생성된다. -t 옵셩능 사용하여 알고리즘과 크의 크기를 지정할 수도 있다. ssh-keygen -t rsa -b 4096 해당 키를 사용할 서버의 ~/.ssh/authorized_keys에 퍼블릭 키를 추가하면 된다. 참고 자료 https://m.blog.naver.com/sehyunfa/221737099486

2024-09-15 · 1 min · 45 words

Squash Merge 문제점

git squash는 conflict가 발생할 확률이 높다. sqaush merge로 병합을 해도 실제로는 병합이 아닌 새로운 커밋으로 만들어지기 때문에 merge한 브랜치와 conflict가 발생한다. https://stackoverflow.com/questions/11797904/git-merge-squash-and-recurring-conflicts

2024-09-15 · 1 min · 22 words

Sqrt Decomposition

문제 상황 처음에 segment tree를 이용해, 배열에 공통적인 변화량을 기록했다. 하지만, 이후에 주어진 범위 내에서 최대 값을 구해야되는 문제가 나왔다. 범위 내의 최대값을 구하기 위해서는 결국 segment tree의 모든 leef node를 탐색해야되므로 O(n)이 걸린다. 해결 방법 배열을 n개의 그룹으로 나누어서 공통적인 변화량을 기록한다. 배열의 크기는 n^(0.5)가 된다. 이렇게 하면 값을 수정할 때도 O(n^(0.5)) 가 걸리고, 최대값을 구할 때도 O(n^(0.5))의 시간 복잡도로 탐색을 하게된다. 참고 자료 https://kesakiyo.tistory.com/22

2024-09-15 · 1 min · 66 words

SQL에서 JOIN ~ ON과 WHERE 의 실행 순서

SQL문을 실행하면 일반적으로 아래와 같은 순서로 진행된다고 일고 있을 것이다. 1. FROM 2. ON 3. JOIN 4. WHERE 5. GROUP BY 6. WITH CUBE or WITH ROLLUP 7. HAVING 8. SELECT 9. DISTINCT 10. ORDER BY 11. TOP 하지만 이것은 논리적 처리 순서이다. SQL 문을 실행시키면 쿼리 옵티마이저가 인덱스를 사용할 수 있도록 JOIN과 WHERE의 순서를 바꿔서 처리한다. 실제 처리 순서와 논리적 순서가 다르다는 것을 이해할 필요가 있다. SELECT programmer.exercise, count(1) as count FROM hospital INNER JOIN covid ON covid....

2024-09-15 · 1 min · 128 words

SQL 튜닝 전에 알아야 될 용어

MySQL 구조 MySQL의 SQL 튜닝을 하기 전에 MySQL가 어떤 구조로 동작하는지 알 필요가 있다. MySQL Connectors를 통해 SQL문을 보내게되면 간략히 아래와 같은 과정을 거친다. Parser를 통해 MySQL 엔진에서 문법 에러가 있는지, DB에 존재하는 테이블을 대상으로 SQL문을 작성했는지 검사한다. Optimizer를 통해 요청한 데이터를 빠르고 효율적으로 찾아가는 전략적 계획을 만든다. 계획을 토대로 스토리지 엔진에 위치한 데이터를 찾는다. 찾은 데이터에서 불필요한 부분을 필터링하고 필요한 연산을 수행한 뒤에 사용자에게 반환한다. 스토리지 엔진 InnoDB, MyISAM, Memory 등과 같은 스토리지 엔진은 사용자가 요청한 SQL 문을 토대로 DB에 저장된 디스크나 메모리에서 필요한 데이터를 가져오는 역할을 한다....

2024-09-15 · 6 min · 1082 words

SQL 첫걸음

데이터베이스와 SQL 데이터베이스 데이터베이스: 데이터란 컴퓨터 안에 기록되어 있는 숫자를 의미하며, 이러한 데이터의 집합을 데이터베이스라고한다. 데이터베이스는 일반적으로 데이터센터의 서버에서 운용하지만 개인용 컴퓨터나 휴대용 기기에 내장되어 있기도 하다. 데이터베이스를 효율적으로 관리하는 소프트웨어를 데이터베이스 관리 시스템, 약자로 DBMS라 부른다. DBMS의 사용 목적은 다음과 같다. 생산성: 시스템을 구축할 때 검색, 추가, 삭제, 갱신과 같은 기본 기능부터 구현할 필요가 없어진다. 기능성: DBMS는 데이터베이스를 다루는 기능을 많이 제공한다. 복수 유저의 요청에 대응하거나, 대용량의 데이터를 저장하고 고속으로 검색하는 기능을 제공하기도 한다....

2024-09-15 · 13 min · 2648 words

Spring의 Thread pool

목표 Thread pool의 사용 목적을 이해한다. Spring boot에서 Tomcat의 Thread pool 설정 방법을 이해한다. Thread Pool DB, 웹 서버 등의 프로그램에서 요청이 도착할 떄마다 새 스레드를 생성하는 방법은 문제점이 있다. 요청을 처리할 때마다 스레드를 생성하고 삭제하는 것은 많은 시간과 시스템 리소스를 사용한다. 너무 많은 요청이 오면, 동시에 너무 많은 스레드가 생성되어 시스템 리소스가 부족해질 수 있다. 스레드 수를 제한할 필요가 있다. 이 문제를 해결하기 위해서 이전에 미리 생성된 스레드를 재사용하기 위한 Thread pool을 사용한다....

2024-09-15 · 2 min · 241 words

Spring으로 WebSocket 시작하기

Spring으로 WebSocket 시작하기(STOMP) Maven 의존성 추가 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>5.2.2.RELEASE</version> </dependency> 최신 버전은 여기서 또한 JSON 사용하여 메시지를 전달 하려면 Jackson 의존을 추가해야된다. Spring Boot의 경우에는 추가할 필요 없을 것으루 추정된다. <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.10.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.2</version> </dependency> Spring에서 WebSocket 활성화 AbstractWebSocketMessageBrokerConfigurer 클래스를 상속하고 @EnableWebSocketMessageBroker 어노테이션을 붙여준다. @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config....

2024-09-15 · 3 min · 476 words

Spring에서 Redis를 이용해 캐싱 구현하는 법

Spring에서 Redis 서버로 캐싱하는 방법은 2가지 방법이 있다. 기본적인 동작 확인만 목표로 하기 때문에 자세한 설정 방법은 생략한다. 어노테이션을 사용하는 방법 의존성 추가 implementation 'org.springframework.boot:spring-boot-starter-data-redis' Config에 @EnableCaching 추가 @SpringBootApplication @EnableCaching public class Application { ... } Entity에 Serializable 구현 Redis에서 데이터를 바이트 스트림으로 저장하기 위해서 필요하다. @Entity public class User implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; private String email; private Integer age; public User() { super(); } public User(Integer id, String name, String email, Integer age) { super(); this....

2024-09-15 · 2 min · 261 words

SpringApplicationEvent

목표 SpringApplicationEvent 가 무엇인지 알아본다. SpringApplicationEvent 의 사용법을 알아본다. SpringApplication.run() @SpringBootApplication public class AccountCoreApplication { public static void main(String[] args) { SpringApplication.run(AccountCoreApplication.class, args); } } Spring Boot를 사용하면 main 메서드에 다음과 같은 함수를 호출하는 것을 볼 수 있다. run 메서드를 호출하면 SpringApplication 생성자를 호출하는 것을 확인할 수 있다. SpringApplication 생성자를 호출하면 ApplicationListener를 로드하여 등록하게 된다. ApplicationListener 관심이 있는 이벤트에 대한 ApplicationListener를 ApplicationContext에 등록하면 ApplicationEvent가 그에 따라 필터링되고, 일치하는 이벤트에 대해서만 Listener가 호출이 된다....

2024-09-15 · 1 min · 149 words

Spring 이벤트 처리

도메인 간의 복잡한 의존성을 제거하기 위해서 Spring의 이벤트를 이용할 수 있다. 이벤트를 사용하기 위해서는 3가지를 사용해야된다. 참고로, Spring Framework 4.2부터 지원하는 어노테이션 방법을 다룬다. 이벤트 클래스 이벤트 퍼블리셔 이벤트 리스너 이벤트 클래스 이벤트에 데이터를 저장하기 위한 클래스로 자유롭게 클래스를 선언하면 된다. public class MenuRegisteredEvent { private final Menu menu; public MenuRegisteredEvent(final Menu menu) { this.menu = menu; } public Menu getMenu() { return menu; } public Long getMenuGroupId() { return menu....

2024-09-15 · 2 min · 236 words