week 5 incheol - GANGNAM-JAVA/JAVA-STUDY GitHub Wiki
-
JAVA (๋ฐํจ์)
-
ํด์๋งต ์ถฉ๋ ํด๊ฒฐ๋ฐฉ๋ฒ(ํ์ธํ์)
hashcode % M ์ ํตํด์ ๋ฒํท์ ํฌ๊ธฐ๋ณด๋ค ์์ ์ธ๋ฑ์ค์ ์ ์ฅ์ ํ๋๋ก ํ๋ค. ๋ฐ๋ผ์ 1/Mํ๋ฅ ๋ก ์ถฉ๋์ด ๋ฐ์ํ๊ฒ ๋๋ค. ํด์๋งต ์ถฉ๋ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ํ์ ์ผ๋ก ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
Open Addressing์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ ค๋ ํด์ ๋ฒํท์ด ์ด๋ฏธ ์ฌ์ฉ ์ค์ธ ๊ฒฝ์ฐ ๋ค๋ฅธ ํด์ ๋ฒํท์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ ๋ฐฉ์์ด๋ค.
Separate Chaining์์ ๊ฐ ๋ฐฐ์ด์ ์ธ์๋ ์ธ๋ฑ์ค๊ฐ ๊ฐ์ ํด์ ๋ฒํท์ ์ฐ๊ฒฐํ ๋งํฌ๋ ๋ฆฌ์คํธ์ ์ฒซ ๋ถ๋ถ(head)์ด๋ค.
Java HashMap์์ ์ฌ์ฉํ๋ ๋ฐฉ์์ Separate Channing์ด๋ค. Open Addressing์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ ๋ ์ฒ๋ฆฌ๊ฐ ํจ์จ์ ์ด๊ธฐ ์ด๋ ค์ด๋ฐ, HashMap์์ remove() ๋ฉ์๋๋ ๋งค์ฐ ๋น๋ฒํ๊ฒ ํธ์ถ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ฒ๋ค๊ฐ HashMap์ ์ ์ฅ๋ ํค-๊ฐ ์ ๊ฐ์๊ฐ ์ผ์ ๊ฐ์ ์ด์์ผ๋ก ๋ง์์ง๋ฉด, ์ผ๋ฐ์ ์ผ๋ก Open Addressing์ Separate Chaining๋ณด๋ค ๋๋ฆฌ๋ค. Open Addressing์ ๊ฒฝ์ฐ ํด์ ๋ฒํท์ ์ฑ์ด ๋ฐ๋๊ฐ ๋์์ง์๋ก Worst Case ๋ฐ์ ๋น๋๊ฐ ๋ ๋์์ง๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ฉด Separate Chaining ๋ฐฉ์์ ๊ฒฝ์ฐ ํด์ ์ถฉ๋์ด ์ ๋ฐ์ํ์ง ์๋๋ก '์กฐ์ 'ํ ์ ์๋ค๋ฉด Worst Case ๋๋ Worst Case์ ๊ฐ๊น์ด ์ผ์ด ๋ฐ์ํ๋ ๊ฒ์ ์ค์ผ ์ ์๋ค(์ฌ๊ธฐ์ ๋ํด์๋ "๋ณด์กฐ ํด์ ํจ์"์์ ์ค๋ช ํ๊ฒ ๋ค).
Java 8 HashMap์์๋ Entry ํด๋์ค ๋์ Node ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ค. Node ํด๋์ค ์์ฒด๋ ์ฌ์ค์ Java 7์ Entry ํด๋์ค์ ๋ด์ฉ์ด ๊ฐ์ง๋ง, ๋งํฌ๋ ๋ฆฌ์คํธ ๋์ ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํ์ ํด๋์ค์ธ TreeNode๊ฐ ์๋ค๋ ๊ฒ์ด Java 7 HashMap๊ณผ ๋ค๋ฅด๋ค.
๋ฐ์ดํฐ์ ๊ฐ์๊ฐ ๋ง์์ง๋ฉด, Separate Chaining์์ ๋งํฌ๋ ๋ฆฌ์คํธ ๋์ ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
8๊ณผ 6์ผ๋ก 2 ์ด์์ ์ฐจ์ด๋ฅผ ๋ ๊ฒ์, ๋ง์ฝ ์ฐจ์ด๊ฐ 1์ด๋ผ๋ฉด ์ด๋ค ํ ํค-๊ฐ ์์ด ๋ฐ๋ณต๋์ด ์ฝ์ /์ญ์ ๋๋ ๊ฒฝ์ฐ ๋ถํ์ํ๊ฒ ํธ๋ฆฌ์ ๋งํฌ๋ ๋ฆฌ์คํธ๋ฅผ ๋ณ๊ฒฝํ๋ ์ผ์ด ๋ฐ๋ณต๋์ด ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
-
thread safe๋? ํด๊ฒฐ/ํํผ ๋ฐฉ๋ฒ?
-
java.util.concurrent ํจํค์ง์๋ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ๋ฐ์ดํฐ์ ์์์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํ API๋ฅผ ํ์ธ ํด๋ณผ ์ ์๋ค.
-
synchronized
public synchronized void ๋ฉ์๋ () { ๋ด์ฉ... } public void ๋ฉ์๋ () { ๋ด์ฉ... synchronized (this) { ๋๊ธฐํ๋ด์ฉ... } }
-
ReentrantLock
๊ธฐ์กด์ synchronized๋ ์ด๋ ๊ฒ ๋ฉ์๋์ ์ฒด๋ ๊ตฌ๊ฐ์ ๋ฌถ์ด์ ๋๊ธฐํ๋ฅผ ์์ผฐ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ReentrantLock ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์กฐ๊ธ์ ๋ฒ๊ฑฐ๋กญ๋๋ผ๋ ์์์ ๊ณผ ๋์ ์ ๋ช ๋ฐฑํ ๋ช ์ํ ์ ์์ต๋๋ค.
class SomeClass { private final ReentrantLock locker = new ReentrantLock(); public void SomeMethod () { locker.lock(); // ์ฐ๋ ๋์ ๋ฝ์ ๊ฒ๋๋ค.(๋๊ธฐํ์ ์์) try { ๋๊ธฐํ๋ด์ฉ๋ค... } catch (์ด๋ค์์ธ๋ค) { ํด๋น์์ธ์ฒ๋ฆฌ... } finally { locker.unlock(); // ์ฐ๋ ๋์ ๋ฝ์ ํ๋๋ค.(๋๊ธฐํ ๋์ง์ ) } } }
-
AtomicInteger
public class AtomicInteger extends Number implements java.io.Serializable { private volatile int value; public final int incrementAndGet() { int current; int next; do { current = get(); next = current + 1; } while (!compareAndSet(current, next)); return next; } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } }
๋ค๋ฅธ AtomicInteger ๋ฉ์๋ ๋ค๋ ๊ฑฐ์ ์ ์ฌํ ํจํด์ผ๋ก ๊ตฌํ๋์ด ์๋ค. ๋ํ ๋์ฌ๊ฒจ ๋ณผ ์ ์ volatile int value; ์ ์ธ๋ถ ์ธ๋ฐ voliatile๋ ๋ณ์์ ๊ฐ์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ์ฌ์ฉ๋๋ค. volatile ํค์๋๊ฐ ๋ถ์ด ์๋ ๊ฐ์ฒด๋ CPU์บ์๊ฐ ์๋ ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์์ ๊ฐ์ ์ฐธ์กฐํด์จ๋ค. ๊ทธ๋ ๋ค๋ฉด ๊ตณ์ด CAS์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํ์ง ์์๋ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ ์๋๊น? ๊ทธ๋ ์ง ์๋ค. volatile ํค์๋๋ ์ค์ง ํ๊ฐ์ ์ฐ๋ ๋์์ ์ฐ๊ธฐ์์ ์ ํ ๋, ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ์ฐ๋ ๋๋ ์ฝ๊ธฐ ์์ ๋ง ํ ๋ ์์ ์ฑ์ ๋ณด์ฅํ๋ค. ๊ทธ๋ฐ๋ฐ AtomicIntger๋ ์ฌ๋ฌ ์ฐ๋ ๋์์ ์ฝ๊ธฐ/์ฐ๊ธฐ ์์ ์ ๋ณํํ๋ค. ๊ทธ๋์ CAS์๊ณ ๋ฆฌ์ฆ์ด๋ผ๋ 2์ค์ ์์ ์ฅ์น๋ฅผ ์ค์นํด ๋์ ๊ฒ์ด๋ค.
-
-
ํํผ
- ๋ฐ์ดํฐ ๋ถ๋ณ์ฑ ํ๋ณด : ๋ชจ๋ ํ๋๋ฅผ final๋ก ์ ์ธ
- ๋ฐ์ดํฐ ์ฌ๋ณธ์ ํ์ฉ : Collections.unmodifiableList(list);
- Compare and Swap(CAS) ๋ฅผ ์ฌ์ฉํ๋ผ : Synchronized์ ๊ฐ์ ๋ช ์์ Lock์ ์ฌ์ฉํ๊ธฐ ๋ณด๋ค CAS๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฑ๋ฅํฅ์์ ๋์์ ์ค๋ค. Low Level์ Atomic ์ ๋ต์ ํด๋นํ๋ค. java.util.concurrent.atomic ํจํค์ง์๋ CAS๋ฅผ ์ ์ฉํ ๋ฉ์๋๊ฐ ๋ง์ด ์๋ค.
-
-
-
SPRING (์ ์ ํ)
-
n+1 ์ฟผ๋ฆฌ ๋ฌธ์ ๋?
- Join ๊ด๊ณ์์ ๋ฐ์ํ๋ ์ด์๋ก join๋ ๋ชจ๋ธ์ ์ฝ์ ๋ ํ๋์ ์ฟผ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ค๋๊ฒ ์๋ ์ฟผ๋ฆฌ์์ ๋ง๋ค์ด์ง ๋ฐ์ดํฐ์ ๊ฐฏ์(n)๋งํผ select ์ฟผ๋ฆฌ๋ฅผ ์ถ๊ฐ๋ก ๋ฐ์ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ค๊ฒ ๋๋ค.
- fetch.eager ์์ fetch.lazy ์ ๋ณ๊ฒฝํ๋ค๊ณ ํด์ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋ ์์ ์ด ๋ณ๊ฒฝ๋ ๋ฟ์ด์ง ์คํ๋๋ ์ฟผ๋ฆฌ์ ๊ฐฏ์๋ ๋ณํจ์ด ์๋ค.
- ์์ธ : jpaRepository์ ์ ์ํ ์ธํฐํ์ด์ค ๋ฉ์๋๋ฅผ ์คํํ๋ฉด JPA๋ ๋ฉ์๋ ์ด๋ฆ์ ๋ถ์ํด์ JPQL์ ์์ฑํ์ฌ ์คํํ๊ฒ ๋๋ค. JPQL์ SQL์ ์ถ์ํํ ๊ฐ์ฒด์งํฅ ์ฟผ๋ฆฌ ์ธ์ด๋ก์ ํน์ SQL์ ์ข ์๋์ง ์๊ณ ์ํฐํฐ ๊ฐ์ฒด์ ํ๋ ์ด๋ฆ์ ๊ฐ์ง๊ณ ์ฟผ๋ฆฌ๋ฅผ ํ๋ค.
- ํด๊ฒฐ๋ฐฉ์
-
fetch join - inner join : ์ง์ ์ฟผ๋ฆฌ ๋ฉ์๋์ ์ฌ์ฉํ JPQL์ ๋ช ์ํด์ฃผ๋ฉด์ fetch ํค์๋๋ฅผ ์ถ๊ฐํด์ค๋ค. (ํ์ด์ง api๋ฅผ ์ฌ์ฉํ ์ ์๋ค)
-
FetchMode.SUBSELECT
์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ N+1 ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค
@Entity class Member{ @Id @GeneratedValue private Long id; @org.hibernate.annotations.Fetch(FetchMode.SUBSELECT) @OneToMany(mappedBy = "member", fetch = FetchType.EAGER) private List<Order> orders = new ArrayList<>(); }
์๋์ ๊ฐ์ด ์คํ๋๋ค.
SELECT * FROM Member; SELECT * FROM Order_ WHERE MEMBER_ID IN( SELECT ID FROM Member )
์ฆ์๋ก๋ฉ์ผ๋ก ์ค์ ํ๋ฉด ์กฐํ์์ ์, ์ง์ฐ๋ก๋ฉ์ผ๋ก ์ค์ ํ๋ฉด ์ง์ฐ๋ก๋ฉ๋ ์ํฐํฐ๋ฅผ ์ฌ์ฉํ๋ ์์ ์ ์์ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ค.
๋ชจ๋ ์ง์ฐ๋ก๋ฉ์ผ๋ก ์ค์ ํ๊ณ ์ฑ๋ฅ ์ต์ ํ๊ฐ ํ์ํ ๊ณณ์๋ JPQL ํ์น ์กฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ถ์ฒ๋๋ ์ ๋ต์ด๋ค.
-
EntityGraph - left outer join : @EntityGraph ์ attributePaths์ ์ฟผ๋ฆฌ ์ํ์ ๋ฐ๋ก ๊ฐ์ ธ์ฌ ํ๋๋ช ์ ์ง์ ํ๋ฉด Lazy๊ฐ ์๋ Eager ์กฐํ๋ก ๊ฐ์ ธ์ค๊ฒ ๋๋ค.
- ๊ณตํต์ ์ผ๋ก ์นดํ ์์ ๊ณฑ(Cartesian Product)์ด ๋ฐ์ํ์ฌ Subject์ ์๋งํผ Academy๊ฐ ์ค๋ณต ๋ฐ์ํ๊ฒ
- Set์ ์ค๋ณต์ ํ์ฉํ์ง ์๋ ์๋ฃ๊ตฌ์กฐ์ด๊ธฐ ๋๋ฌธ์ ์ค๋ณต๋ฑ๋ก์ด ๋์ง ์์ต๋๋ค
- 2๋ฒ์งธ ๋ฐฉ๋ฒ์ distinct๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ณต์ ์ ๊ฑฐํ๋ ๊ฒ์ ๋๋ค
-
BatchSize
ํ์ด๋ฒ๋ค์ดํธ๊ฐ ์ ๊ณตํ๋
org.hibernate.annotations.BatchSize
์ด๋ ธํ ์ด์ ์ ์ด์ฉํ๋ฉด ์ฐ๊ด๋ ์ํฐํฐ๋ฅผ ์กฐํํ ๋ ์ง์ ๋ size ๋งํผ SQL์ IN์ ์ ์ฌ์ฉํด์ ์กฐํํ๋ค.@Entity class Member{ @Id @GeneratedValue private Long id; @org.hibernate.annotations.BatchSize(size = 5) @OneToMany(mappedBy = "member", fetch = FetchType.EAGER) private List<Order> orders = new ArrayList<>(); }
์ฆ์๋ก๋ฉ์ด๋ฏ๋ก Member๋ฅผ ์กฐํํ๋ ์์ ์ Order๋ฅผ ๊ฐ์ด ์กฐํํ๋ค.
@BatchSize
๊ฐ ์์ผ๋ฏ๋ก Member์ ๊ฑด์๋งํผ ์ถ๊ฐ SQL์ ๋ ๋ฆฌ์ง ์๊ณ , ์กฐํํ Member ์ id๋ค์ ๋ชจ์์ SQL IN ์ ์ ๋ ๋ฆฐ๋ค.SELECT * FROM ORDER_ WHERE MEMBER_ID IN( ?, ?, ?, ?, ? )
size
๋ IN์ ์ ์ฌ์์๋ ์ต๋ ์ธ์ ๊ฐ์๋ฅผ ๋งํ๋ค. ๋ง์ฝ Member์ ๊ฐ์๊ฐ 10๊ฐ๋ผ๋ฉด ์์ IN์ ์ด 2๋ฒ ์คํ๋ ๊ฒ์ด๋ค.๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ์ง์ฐ๋ก๋ฉ์ด๋ผ๋ฉด ์ง์ฐ๋ก๋ฉ๋ ์ํฐํฐ ์ต์ด ์ฌ์ฉ์์ ์ 5๊ฑด์ ๋ฏธ๋ฆฌ ๋ก๋ฉํด๋๊ณ , 6๋ฒ์งธ ์ํฐํฐ ์ฌ์ฉ ์์ ์ ๋ค์ SQL์ ์ถ๊ฐ๋ก ์คํํ๋ค.
hibernate.default_batch_fetch_size ์์ฑ์ ์ฌ์ฉํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด์ ๊ธฐ๋ณธ์ผ๋ก @BatchSize๋ฅผ ์ ์ฉํ ์ ์๋ค.
<property name="hibernate.default_batch_fetch_size" value="5" />
-
-
@ControllerAdvice, @ExceptionHandler์ ๋ํด ์ค๋ช ํ์์ค
@ControllerAdvice
์ปจํธ๋กค๋ฌ๋ฅผ ๋ณด์กฐํ๋ ํด๋์ค์ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ .
์ปจํธ๋กค๋ฌ์์ ์ฐ์ด๋ ๊ณตํต๊ธฐ๋ฅ๋ค์ ๋ชจ๋ํํ์ฌ ์ ์ญ์ผ๋ก ์ฌ์ฉํ๋ค.
@ExceptionHandler
์ปจํธ๋กค๋ฌ ๋ฉ์๋์ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ .
์ด๋ ธํ ์ด์ ์ธ์๋ก ์ ๋ฌ๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ค.
์ ๋ฌ๋ ์์ธํด๋์ค์ ํ์ฅ๋ ํด๋์ค๊น์ง ์ฒ๋ฆฌํ๋ค.
Spring Web MVC - Annotated Controllers - Exceptions
์๋์ ๊ฐ์ด ํด๋์ค๋ฅผ ์์ฑํ์๋ค๊ณ ๊ฐ์ ํ์.
@Controller public class SimpleController { // ...@ExceptionHandler public ResponseEntity<String> handle(IOException ex) { // ... } }
์์ ๊ฐ์ด ์์ฑ๋๋ฉด ํด๋น Controller์ ๋ฉ์๋์์ ๋ฐ์ํ IOException์ ์์ @ExceptionHandler๋ก ์ ์ธ๋ handle ๋ฉ์๋๋ฅผ ํตํด ์๋ฌ๊ฐ ์ฒ๋ฆฌ๋๋ค.
@ExceptionHandler({FileSystemException.class, RemoteException.class}) public ResponseEntity<String> handle(IOException ex) { // ... }
์์ ๊ฐ์ด @ExceptionHandler์ ๋์ Exception ๋ชฉ๋ก์ ์ ์ํ์ฌ ์ฒ๋ฆฌ ๋์์ธ Exception ์ ํ์ ์ข๋ ์ขํ ์ ์๋ค.
IOException ์ค FileSystemException๊ณผ RemoteException ์ ๋ํด์๋ง ํด๋น handle ๋ฉ์๋๊ฐ ๋์ํ๋ค.
@ExceptionHandler({FileSystemException.class, RemoteException.class}) public ResponseEntity<String> handle(Exception ex) { // ... }
์์ ๊ฐ์ด ๋์ Exception์ @ExceptionHandler๋ก ์ ์ํ๊ณ ์ผ๋ฐ์ ์ธ ์๋ฌ ์ ํ์ธ Exception์ด๋ ๋๋ ์์์ธ Throwable์ ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉํ ์๋ ์๋ค.
@Controller์ ์ ์๋ @ExceptionHandler๋ ํด๋น controller์์๋ง ๋์ํ๋ค.
๋ชจ๋ Controller์ ๋ํด ๋ฐ์ํ ์ ์ญ ์๋ฌ์ ๋ํด ์ฒ๋ฆฌํ๋ @ExceptionHandler๋ @ControllerAdvice์ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋๋ค.
@Controller @ControllerAdvice public class GlobalExceptionController { // ...@ExceptionHandler public ResponseEntity<String> handle(IOException ex) { // ... } }
์์ ๊ฐ์ด @ControllerAdvice๋ก ์ ์ธํ controller๋ด์ ์ ์๋ @ExceptionHandler๋ ๋ชจ๋ controller๋ฅผ ๋์์ผ๋ก ๋์ํ๋ค.
controller ๋์์ ์ขํ์ ์ง์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์๋์ฒ๋ผ ์ฌ์ฉํ๋ฉด ๋๋ค.
// @RestController๋ฅผ ์ฌ์ฉํ ๋ชจ๋ controller ๋์@ControllerAdvice(annotations = RestController.class) public class ExampleAdvice1 {} // ํด๋น ํจํค์ง ๋ด ๋ชจ๋ controller ๋์@ControllerAdvice("org.example.controllers") public class ExampleAdvice2 {} // ํด๋น ํด๋์ค ํ์๋ก ๊ตฌํ๋ controller ๋์@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class}) public class ExampleAdvice3 {}
-
-
Infra/์ด์ (๊น์งํ)
-
rest api method ์ ๋ํด์ ์ค๋ช ํ์์ค
-
http status code
-