JAVA

    Not Synchronized SimpleDateFormat

    SimpleDateFormat을 사용해서 Date를 String으로 format하거나 String을 Date로 파싱할 때 사용한다. public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd"); @SneakyThrows public static void main(String args[]) { Date parse = sdf.parse("2021-07-24"); String format = sdf.format(new Date()); System.out.println(parse); System.out.println(format); } 출력 결과 Sun Jan 24 00:07:00 KST 2021 2021-14-18 특히 계속 사용되..

    클린코드 9장 (클래스), 10장 (시스템), 11장(창발성), 12장(동시성)

    클래스 내부에서 동작하는 변수나 유틸리티는 protected로 선언하여 테스트에 사용하기도 한다. 클래스에 기본 규칙은 작게 만드는 것. 많을수록 클래스에 대한 책임이 너무 커진다. SPR을 지키기 위해 클래스가 너무 많아지면 사용에 더 어렵다고 우려할 수 있으나 하나의 여러 책임을 가지고 있는 클래스를 사용하는 것 보다 더 직관적 이므로 사용하기 더 편하다. 클래스 내부에 인스턴스 변수가 많아 진다는건 결국 클래스 내부에 함수와 인스턴스 변수들 사이에 응집도가 높아진다는 뜻이다. 이럴 수록 클래스를 분리해야 한다는 걸 의미한다. 긴 함수를 쪼갠다 → 작은 함수 여러 개로 만든다. → 몇몇 변수와 몇몇 함수만 사용 되는 경우가 보이면 클래스로 쪼갠다. 특정 기능이 변경 될 때 마다 코드가 변경되어야 하는..

    클린코드 7장(경계), 8장 (단위 테스트)

    경계 Map과 같은 공개된 인터페이스를 사용할 때 2가지 문제가 있다 1. 전달되는 map에 clear와 같은 삭제 명령어가 있어서 전달해주는 쪽에서 알지 못하고 지워지는 이슈가 있을 수 있다. 2. 전달된 Map 형태가 generic 하게 전해 졌어도 받는 쪽에서 Map map 등으로 받아 버린다면 캐스팅을 해서 사용하는 등의 문제나 변경의 소지가 크다. 또한 Map의 사용 방식이 변경된다면 이를 해결하기 위해 모든 부분에서 수정되어야 하는 문제가 있다. 그래서 이를 해결하기 위해서 Map에 사용 되는 Value 값의 객체에서 Map을 품어서 쓰는 방식으로 캡슐화하여 사용하기도 한다. public classs Sensors { private Map = new HashMap(); public Sensor..

    클린코드 5장(객체와 자료구조), 6장 (오류처리)

    객체와 자료구조 객체에서 자료를 세세하게 공개하는 것 보다 추상화를 통해 표현하는 것이 더 좋다. 객체는 동작을 공개하고 자료를 숨긴다. 복잡한 시스템을 짜다보면 새로운 함수가 아니라 새로운 자료타입이 필요한 경우가 발생하는데 이 때는 클래스와 객체 지향 기법이 적합하다. 하지만 새로운 함수가 필요하다면 절차지향 코드와 자료구조 형태가 더 적합한 코드이다. 오류처리 오류를 일일히 처리하는 것보다 차라리 예외를 던저버리는게 더 깔끔하다. 확인된 예외를 처리하기 위해서 하위 메소드에서 throws를 하게되면 상위 메소드에서 이 예외에 대한 명시가 되어야 하기 때문에 하위의 예외 때문에 상위 메소드가 수정되어야 하는 불상사가 발생하기 때문에 수정에 닫혀 있어야 하다는 OCP규칙을 위반한 것이다. 예외에 의미있..

    클린코드 3장 (함수), 4장 (주석)

    함수 - 함수를 만드는 기본 규칙은 작게 만드는 것! - 함수 내부에 if 문 등의 1단이나 2단 그 이상의 중첩 구조가 발생되면 안된다. - 함수의 활동은 한가지 그 이상을 하지마라. - switch문에 다음과 같이 한가지 작업만 해야한다는 SRP 이론과 코드의 변경이 있으면 안된다는 OCP 규칙을 위반한다. 이를 해결하기 위해서는 다형성을 이용해서 해결해야 한다. // 문제 코드 public int calEmployeePay(Employee e) { switch (e.type) { case SALARIED: return calculateSalariedPay(); case HOURLY: return calculateHourlyPay(); case ..... } } // 변경 내용 public inter..

    클린코드 1장(깨끗한 코드), 2장 (의미있는 이름)

    깨끗한 코드 태도 나쁜 코드는 생산성을 떨어트리고 갈수록 생산성 0로 수렴하게 만든다. 일정에 쫓겨서 만든 나쁜 코드를 나중에 고치려는 습관은 버려라. 르블랑의 법칙 대로 나중은 결코 오지 않는다. 핑계될 것 없다 모두 개발자 탓이다. 시간이 없어서 만든 잘못된 코드는 결국 일정을 빠르게 앞당기는 것이 아니라 결국 그 잘못된 코드로 일정을 지연시킨다. 깨끗한 코드란? 논리가 간단해야 한다. 의존성이 줄어 유지보수가 쉬워야 한다. 성능이 최적화 되어 있어야 한다. 오류는 확힐 하게 처리해야 한다. 많은 일을 하지말고 한가지 잘하는 일을 잘하는 코드를 만들어라. 테스트 케이스가 없는 코드는 깨끗한 코드가 아니다. 중복이 없다. 코드를 최대한 줄인다. 지속적으로 나빠지는 코드를 개선한다. 결론 백날 좋은 코드..

    모던 자바 인 액션 내용 정리

    포킹 자바 8에서 추가된 스트림 api에서 데이터를 필터링, 추출, 그룹화 등의 기능을 진행할 수 있다. 이러한 동작들을 병렬화 할 수 있어 여러 cpu에서 작업을 분산해서 처리할 수 있다. 이런 작업을 포킹 단계라고 한다. 함수형 인터페이스 - 하나의 추상메서드를 가지고 있는 함수형 인터페이스지만 상속을 받은 인터페이스는 추상메서드를 하나만 가지고 있다고 하여도 함수형 인터페이스가 아니다. - 디폴트 메소드가 아무리 많아도 추상 메소드가 하나이면 함수형 인터페이스이다. - @FunctionalInterfeace 애노테이션을 붙이면 함수형 인터페이스가 아닌 경우 컴파일 에러를 발생 시킬 수 있다. 람다에서 지역변수를 final로 제약하는 이유 람다에서 지역변수가 final로 사용되는지 궁금한데 이는 인터..

    Java 메모리 구조 및 GC 알고리즘 정리

    자바 메모리 구조는 1.8 이후로 일부분 바뀌었다. 이 부분에 대한 정리를 다시 하고 싶었고 GC 알고리즘에 대한 종류와 상세 내용을 정리하고 싶었다. 그럼 이 두 가지 사항에 대해 가볍게 정리해보자. Java 메모리 구조 Method Area 프로그램이 실행되는 도중에 아직 사용되지 않은 클래스들의 코드는 new를 통해 클래스의 인스턴스가 생성되면 JVM Method Area에 인스턴스 변수, 메스드 코드, 클래스 변수등을 저장한다. 해당영역은 모든 쓰레드 사이에서 공유되고 static 키워드로 생성된 변수 또한 저장을 Runtime Constant Pool 영역에 저장한다. 실 데이터를 저장하는 것이 아니라 레퍼런스만 저장하며 실제 데이터는 Heap 영역에 저장한다. JVM Language stack..

    백준 4673번 셀프 넘버

    1 ~ 10000까지의 숫자중에 셀프 넘버가 아닌 데이터를 noSelfNumber에 집어넣고 loop를 순회하면서 selfNumber 여부를 체크하면 된다. 간단한 문제이다. https://www.acmicpc.net/problem/4673 4673번: 셀프 넘버 문제 셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다. 양의 정수 n이 주어졌을 때, 이 수를 시작해서 n, d(n), d(d(n)), d(d(d(n))), ...과 같은 무한 수열을 만들 수 있다. 예를 들어, 33으로 시작한다면 다음 수는 33 + 3 + 3 = 39이고, 그 다..

    DFS로 미로 탈출하기

    최단거리 알고리즘을 공부하면서 예전해 만들었었던 미로 찾기를 다시한번 해봤다. 초년생때 이런문제가 어려웠는데 다시해보니 크게 어렵지는 않은것 같다. DTO package dto; /** * Maze 블록의 정보를 보관하는 DTO * * @author rokki * */ public class MazeBlock { private int x; // x 좌표 private int y; // y 좌표 private int count; // 카운트 public MazeBlock(int x, int y, int count) { this.x = x; this.y = y; this.count = count; } public int getX() { return x; } public void setX(int x) { th..

    백준 4936 - 섬의개수

    결국은 순회하면서 하는 DFS를 했는데 다음번에는 DP 또는 그래프 문제를 좀 많이 풀어 보고 싶다. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126import java.util.*; public class Main { public static void main(String[..

    백준 알고리즘 2583 - 영역 구하기

    백준 알고리즘 2583번 영역구하기 문제는 DFS를 사용해서 구현해봤다. 문제지를 보자마자 읽기 싫어졌지만 읽어보면 되게 단순하게 많이 접해봤던 문제인거 같다. https://www.acmicpc.net/problem/258312345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612..

    백준 1929번 소수 구하기 문제

    일반적으로 소수 구하는 방식으로 진행하면 시간이 너무 걸려서 에러가 발생한다. 그래서 고민하던 중에이런 생각이 났다. 모든 수는 자신의 제곱근 이상의 수로 나눠지지 않기 때문에 자신의 제곱근까지 2이상의 자연수로 나눠지는지 판단하면 된다고 생각했다. 그 결과 된다.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556import java.math.BigDecimal;import java.util.ArrayList;import java.util.List;import java.util.Scanner; public class Main { public static void main(..

    [공유] 자바 유료화 관련 글 공유

    자바 유료화 관련해서 궁금해서 알아보던중 좋은 글을 작성해주신 분들이 있어서 공유합니다. 결론적으로 개인 개발환경에서 Oracle JDK를 사용하는건 상관없고 솔루션같이 상업적으로 사용 되는 부분에서는 OpenJDK를 사용하면 된다는 건가...아직도 잘 모르겠다. 시간이 지나면 답이 나오겠지.http://jsonobject.tistory.com/395 http://dev.zepinos.com/phame/post/view/2/oraclejdk_%EC%9D%98_%EC%9C%A0%EB%A3%8C%ED%99%94_%EA%B7%B8%EB%9E%98%EC%84%9C_java_%EB%8A%94_%EB%A7%9D%ED%96%88%EB%8B%A4/

    백준 알고리즘1032 명령프롬프트 문제

    문제입력된 파일 리스트를 보고 공통적으로 사용될 수 있는 Regex를 찾아서 출력하는 문제이다. 코드 코드는 간단하게 처음입력받은 파일명을 기준으로 잡고 추가로 들어오는 나머지 파일명들과 다른 부분에 대해서 모두 ?로 바꿔버렸다. 12345678910111213141516171819202122232425262728293031323334353637import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 파일 개수 입력 int wordCnt = sc.nextInt(); // 첫 번째 파일이름 char[] creteria = sc.next()..

    백준 알고리즘 11650 - 좌표 정렬하기

    문제 입력된 좌표를 정렬해서 보여주는 문제이다. 코드 좌표를 담는 하나의 DTO 객체를 만들어서 comparable을 정의해서 사용해도 되나 좀 다르게 해보고 싶었다. 각 x좌표를 키로 사용하는 map을 만들고 각 x좌표마다 y좌표들을 담는 리스트가 존재한다. y좌표값이 채워질때는 정렬이 된 상태로 삽입된다. insertSort 메소드는 ATM 알고리즘에서 사용했던 것 가져왔다. 그리고 Map을 출력할 때는 Key를 기준으로 정렬한 후 forEach를 사용하여 정렬한다. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354import java.util.*; public class ..

    백준 알고리즘 11399 ATM 문제

    문제 이번 알고리즘 문제는 최소 ATM 사용시간을 구하는 문제이다. 주어진 사람마다 ATM 사용시간이 주어진다. 이 사용시간에 따라 어떻게 사람이 서있을 때 빠르게 모두 ATM 을 사용할 수 있는지 구하는 문제이다. 각 사람마다 걸리는 시간을 모두 더해서 가장 최소의 시간이 나오게 하는 구현하는게 목표이다. 가장 빠르게 모두 인출이 끝나기 위해서는 사용시간이 가장 작은 사람 부터 큰 순서대로 서서 인출을 해야한다. 왜냐하면 뒤에 있는 사람이 인출하는데 걸리는 시간은 결국 앞사람이 사용한 시간의 누적값이기 때문이다. 코드소요시간 별로 오름차순으로 정렬한 후 에 합을 구하면 된다. 그러기 위해서 모든 데이터를 입력받고나서 가장 시간 복잡도가 낮은 퀵정렬을 사용하면하면 되지만 그냥 데이터가 삽입되는 순간에 삽..

    Iterator 그리고 Iterable에 대해 정리

    Java8의 Stream에 map 기능을 사용하다가 이런문제를 겪었다. Iterable과 Iterator 정확한 정리를 하지 않고 무턱대고 사용하다보니 발생한 문제였다. 정확하게 집고 넘어가기 위해 정리해보자. Iterator Iterator는 자바 1.2에 발표된 인터페이스이다. hasNext, next 등을 통해 현재 위치를 알 수 있고 다음 element가 있는지를 판단하는 기능등에 대한 명세를 제공한다. 이를 사용하기 위해서는 Iterator 인터페이스의 내용을 직접 구현해야 한다. 대게 Collection 인터페이스를 사용하는 클래스의 경우 별도의 Iterator를 구현하여 사용하고 있다. 밑에 Iterable을 설명하면서 정리해보자. 123456789101112public interface I..

    static method와 Override hiding 대한 정리

    static 메소드를 자기고 있는 클래스를 상속받은 자식 클래스에서 그 static 메소드를 override 할 수 있을까? 안될거 알지만 한번 확인해보고 싶었다. 먼저 static method를 가지고 있는 Parent을 만들었다. 123456789101112/** * 부모 클래스 */static class Parent { public static void getData() { System.out.println("부모 getData"); } public void method() { System.out.println("부모 method"); }}Colored by Color Scriptercs 그리고 이를 상속하는 Child 클래스를 만들어보자.123456789101112/** * 자식 클래스 */sta..

    백준 1094 막대기 문제

    문제 내용 https://www.acmicpc.net/problem/1094소스코드자세한 소스는 참고 https://github.com/weduls/algorithm/tree/master/%EC%8B%9C%EB%AE%AC%EB%A0%88%EC%9D%B4%EC%85%98/%EB%A7%89%EB%8C%80%EA%B8%B0 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import java.util.Scanner;import java.util.Stack;import java.util.stream.IntStream; public cl..

    백준 알고리즘 4150번 피보나치 수 문제

    저번에 공부한 BigInteger를 응용하여 알고리즘 문제를 풀어보자. 이번문제는 피포나치 수열을 해결하는 문제이다. 저번에 포스팅 했었던 피보나치 수열을 구하는 방법은 재귀와 DP 그리고 반복문이 있다. 이번 문제는 반복문을 사용하여 구해보자. 위에 문제를 보면 데이터의 결과 크기가 Long의 범위를 벗어난다. 그렇기 때문에 데이터를 담기위해서 BigInteger를 사용하였다. 생각보다 문제는 간단하나 여러가지 경우를 정리 할 수 있었서 좋았다. 1234567891011121314151617181920212223242526272829303132333435363738394041package test; import java.math.BigInteger;import java.util.ArrayList;imp..

    Java의 거대 정수를 담을 수 있는 BigInteger

    대학교 학창시절에 BigInteger만들기를 자료구조 시간에 C로 만들어 본적이 있다. 그리고 실질적으로 실무에서는 Long값을 벗어난 데이터를 담아서 사용해본적이 없어 자바의 BigInteger라는 객체가 존재하는지 몰랐다. 매주 진행하는 알고리즘 스터디에서 문제를 풀다가 Long값 이상의 데이터가 필요해서 찾다가 사용하게 되었다. 몇 가지 정리해보자. BigInteger 객체 생성 방법 팩토리 메서드와 기존 constant 객체로써 제공하는 방법으로 BigInteger객체를 만들 수 있다.12345678910// ConstantBigInteger zero = BigInteger.ZERO;BigInteger one = BigInteger.ONE;BigInteger ten = BigInteger.TEN;..

    [공유] 시간 복잡도와 공간복잡도 정리

    시간복잡도와 공간복잡도 관련하여 많이 잊어먹어서 정리된 사이트를 공유합니다. https://joshuajangblog.wordpress.com/2016/09/21/time_complexity_big_o_in_easy_explanation/

    재귀 문제점과 꼬리 재귀와의 함수 비교

    재귀함수는 자기 자신을 호출하는 방식으로 다양하게 사용된다. 재귀함수에는 일반재귀와 꼬리 재귀가 있는데 나는 둘 다 사용해온것 같은데 정확한 명칭과 사용방법에 대해서는 제대로 알지 못하는 것 같아 정리하게 되었다. 코드도 짧고 간결한 장점이 있다. 하지만 결국에는 함수를 계속 호출하는 방식이기에 함수가 끝나고 돌아가야할 위치에 대해 스택에 기록된다. 계속 함수가 호출되어 스택 영역의 최대 이상의 크기를 넘어가게 되면 Stack over flow가 발생한다. 편리함을 찾다가 더 위험한 상황이 초래된다. 그리고 성능적으로도 문제가 있다. 피보나치 수열의 예시를 확인해보자.12345private static int factorial(int n) { if (n == 1) return n; return n * f..

    백준 6603번 로또 문제 풀이

    매주 진행중인 알고리즘 공부 중 오늘은 백준 6603번 DFS와 백트래킹 문제를 풀어보자. #문제 https://www.acmicpc.net/problem/6603#풀이과정사용자로 부터 로또번호를 생성할 번호의 개수 k를 입력받고 입력받은 k개의 숫자를 이용하여 로또를 오름차순으로 6개짜리 배열을 만들어 출력해야한다. 처음에 문제를 보자마자 재귀를 써야겠다는 생각은 하였지만 백트래킹을 써야하는지는 감이 오지 않아서 고민을 많이 했다. 시작점을 0번째 부터 로또를 딱 만들수 있는 크기인 k - 5번까지 사용하는 반복문을 만들어서 배열을 만든다. 그리고 findLottoNum 메소드에 현재 인덱스와 만들고 있는 String값을 전달해준다. 그럼 현재 인덱스 바로 앞에 위치할 숫자를 구해서 String에 붙혀..

    백준 알고리즘 10988번 문제 팰린드롬 문제 풀기

    팰린드롬은 단어를 앞뒤로 거꾸로 했을 때 동일한 단어를 이야기한다. 코드가 아주 간단하다.입력받은 String 길이의 반만큼 반복문을 돌면서 앞과 뒤가 맞는지 체크하고 앞에서오는 인덱스 i와 뒤에서 오는 인덱스 j가 서로 교차하는 순간까지 서로 다르지 않으면 1을 반환하고 체크하던 도중에 한부분이라도 같지 않으면 0을 반환하면 된다.자세한 코드는 아래 또는 github에서 확인 가능하다. 12345678910111213141516171819202122232425262728293031323334package test; import java.util.Scanner; public class WedulPlindrom { public static void main(String args[]) { Scanner sc..

    피보나치 수열 재귀, DP, loop 방법으로 구현하고 차이 확인

    피보나치 수열을 이용한 재귀 프로그래밍은 대학교 1학년때 처음 재귀를 구하면서 접했었다. 당시에는 재귀의 예제로써 피보나치와 팩토리얼함수를 구현하는 것으로 소개되었다.하지만 시간복잡도에 대해 다시 공부하던 중 우리가 배웠던 피보나치 수열의 재귀는 좋은 방식이 아니라는 것을 알게되었다. 피보나치 수열의 3가지 방식에 대해 구현해보고 차이를 느껴보자. 우선 피보나치 수열은 현재 값을 구하기위해서는 이전의 값(n-1)과 그 더 이전의 값(n-2)을 더하면서 구한다.N = (n - 2) + (n -1)0, 1, 1, 2, 3, 5, 8, 13, 21, 34........ 1) 재귀방식재귀로 구현하는 방식은 가장 익숙한 방법이지만 매번 구할 때 마다 처음까지 가야하는 가장 안좋은 BigO(2^n)의 시간 복잡도를..

    백준 알고리즘 2167 2차원 배열의 합 DP 알고리즘으로 풀기 (JAVA)

    알고리즘 문제를 계속해서 연습해야겠다고 생각한 시점에서 백준 알고리즘 2차원 배열문제를 풀어보기로 했다. 문제는 간단하게 말하면 2차원 배열이 주어졌을 때, 특정 i, j 위치에서 x, y위치 까지의 value들의 합을 구하는 문제이다. 나는 특정 알고리즘을 생각하지 않고 단순하게 접근해서 array에 value를 다 넣어놓고 1,1에서 2, 3 까지 value를 구하라고 하면 1,1에서 2,3까지 반복문을 돌면서 value를 다 더했었다. 하지만 그렇게 하는게 아니라 DP 알고리즘을 사용해야 한다고 한다. 우선 자세한 문제는 백준 홈페이지에서 확인하시면 된다. https://www.acmicpc.net/problem/2167 그리고 먼저 말했던 단순하게 접근한 코드는 다음과 같다. 1 2 3 4 5 6..

    규칙 74 - Serializable 인터페이스를 구현할 때는 신중하라.

    클래스 선언부에 implements Serializable를 붙히면 간단하게 직렬화 가능 객체를 만들수 있다. 그렇기 때문에 개발자 입장에서는 Serializable을 붙혀서 직렬화 기능을 만드는 것이 간단하다고 생각할 수 있다. 여기서 먼저 직렬화에 대해서 간단한 예제를 보고 가자. import java.io.Serializable; public class Student implements Serializable { private static final long serialVersionUID = 1L; public Student(String name, int number, int height) { this.name = name; this.number = number; this.height = heigh..

    규칙 73 - 스레드 그룹은 피하라.

    스레드 그룹(thread group)은 원래 applet을 격리시켜 보안문제 해결할 목적으로 만들어졌으나 성공하지 못했다. 그러면 이런 스레드 그룹은 왜 남아있는가? 아예 쓸곳이 없는가? 그렇지는 않다. 스레드 기본연산을 여러 스레드에 동시에 적용할 수 있도록 하는 기능을 가지고 있다. 하지만 대부분이 deprecated 되었다. 결론을 이야기하자면 이미 다 페기가 되어버린 기능이다. 그렇기 때문에 신경쓸 것 없이 사용하지 말아야한다. 출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1)