System.out.println 이 아닌 SLF4J, Logback 등을 이용한 logger를 사용해야 하는 이유에 대해 알아보자

 

대충 요약 : 그냥 System.out.println 쓰지 말고 logger를 써라

 

 

3줄 요약 

System.out은 속도가 느리다.

System.out은 로깅 레벨을 조절할 수 없다.

logger 는 별도의 기능들을 더 제공한다.

 

자세히.

1. 속도

System.out 은 내부 버퍼링과, 멀티 쓰레드 등의 환경에 따라 로그를 모아서 출력하는 등의 상황이 발생한다. 물론 logger 또한 내부 버퍼링이 있지만 성능 최적화가 조금 더 잘 되어있다 

(자세히 : 링크 TODO )

System.out.println("sysout");
System.err.println("syserr");

logger.trace("LOG TRACE");
logger.debug("LOG DEBUG");
logger.info( "LOG INFO");
logger.warn( "LOG WARN");
logger.error("LOG ERROR");

 

2. 로그 레벨 조절

System.out.println (혹은 System.err.println) 은 로그 레벨을 조절할 수 없는 반면

logger는 기본적으로 5개의 로그 레벨을 지원하므로 필요에 따라 다양하게 쓸 수 있으며 이 로그 레벨을 별도의 어플리케이션 코드를 바꾸지 않고 외부에서 설정을 바꿔서 로그 레벨 조절이 가능하다. 이를 활용하여 특정 상황에 맞는 로그를 출력할 수 있다.

 

3. 로그 파일 관리

추가로 수많은 로그가 남는 시스템에서는 로그 파일 크기로 인해 서비스 장애가 발생할 수 있는데

logger에서는 날짜별 로그파일 분리, 파일 크기별 로파일 분리 등을 지원한다.

 

 

 

logger 사용의 올바른 예시

아래의 코드에서 위 두줄과 아래 코드 방식마다 결과의 차이가 있을까? 결론부터 말하자면 "차이가 있을 수 있다." 이다.

String name = "Chris";
String id = "chris1108";

// 1. noncompliant
logger.info("name = " + name);
logger.debug("id = " + id);

// 2. compliant 
if ( logger.isInfoEnabled() ) {
	logger.info("name = " + name);
}
if ( logger.isDebugEnabled() ){
	logger.debug("id = " + id);
}

// 3. compliant 
logger.info("name = {}", name);
logger.debug("id = {}", id);

먼저 1번을 보자

로그 레벨이 DEBUG 일 경우에는 문제가 발생하지 않고 DEBUG 보다 높은 INFO, WARN, ERROR 일 경우에 문제가 발생한다.

java의 연산 순서상 logger.debug 함수로 String을 전달하기 전에 "id = " + id 연산을 처리하게 된다.

log 내부에서는 로그 레벨이 INFO 이기 때문에 별다른 로그 출력을 하지 않게 되겠지만 결과적으로 "id = " 와 id를 더하는 연산은 쓸모없는 냥비가 되는 셈이다.

 

그래서 아래의 2,3번 방법을 사용할 수 있다.

로그 레벨이 DEBUG 일 경우에만 "id = " + id 연산을 하게 하여 불필요한 연산을 줄일 수 있다.

 

여기서 더 나아가 3번의 방법을 사용하면

logger 내부에 "id = {}" 와 id 두 개의 String 을 parameter로 전달하고 내부에서 필요할 경우에만 연산을 처리해 주고 코드의 가독성 또한 높일 수 있다.

오타였음.

Content-Type: text/html 
가 없으면 html로 보여지지 않는 것이 당연

@@
예상 질문 질의응답 모음
Java 면접
Spring 면접

■ 객체지향이란? 

프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법입니다

 

■ 객체지향 프로그래밍의 장점

코드 재사용이 용이 => 남이 만든 클래스를 가져와서 사용가능
유지보수가 쉬움 => 절차지향 프로그래밍은 일일이 찾아 수정해야하는 반면에 해당하는 부분만 수정하면됨
대형 프로젝트에 적합 => 클래스 단위로 모듈화 시켜서 개발가능

 

■ 객체 지향적 설계 원칙

SRP(Single Responsibility Principle) : 단일 책임 원칙 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
OCP(Open-Closed Principle) : 개방-폐쇄 원칙 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
LSP(Liskov Substitution Principle) : 리스코프 치환 원칙 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
ISP(Interface Segregation Principle) : 인터페이스 분리 원칙 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
DIP(Dependency Inversion Prinsiple) : 의존 역전 원칙 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.

 

■ 객체지향 프로그래밍 키워드

추상화 : 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 공통의 속성이나 기능을 묶어 이름을 붙이는 것
캡슐화 : 기능과 특성의 모음을 "클래스"라는 "캡슐"에 넣어서 분류해서 넣는 이 캡슐화다.
상속 :상속은 부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게하고 기능의 일부분을 변경해야 할 경우 상속받은 자식클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것이다. 다중 상속은 불가하다.
다형성 : 하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것이다.즉, 오버라이딩(Overriding), 오버로딩(Overloading)이 가능하다는 얘기다.
오버라이딩 : 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는 것.
오버로딩 : 같은 이름의 함수를 여러 개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 다르게 호출할 수 있게 하는 것.

 

■ 제네릭

제네릭(Generic)은 클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정되는 것을 의미한다.

■ 컬렉션 클래스에서 제네릭을 사용하는 이유를 설명하세요

컬렉션 클래스에 저장되는 인스턴스 타입을 제한하여 런타임에 발생할 수 있는 잠재적인 모든 예외를 컴파일 타임에 잡아 낼 수 있어서 사용합니다.

 

■ 데드락 개념, 해결방법

둘 이상의 스레드가 lock을 획득하기 위해 기다리는데, 이 lock을 잡고 있는 스레드도 똑같이 다른 lock을 기다리면서 서로 블락상태에 놓이는 것을 말한다
우선순위를 선정해 자원을 선점하도록 하는 것과 공유 불가능한 상호 배제 조건을 제거하는 것이 있다.

 

■ JVM 역할

자바 컴파일러가 .java 파일을 컴파일 하면, .class라는 자바 바이트코드로 변환시켜줍니다. 이때 바이트 코드가 기계어가 아니기 때문에 운영체제에서 바로 실행을 못하는데 이때 운영체제가 이해할 수 있도록 해석해주는 것이 JVM입니다.
컴파일 -> 바이트 코드 -> 기계어 이런식으로 중간에 바이트 코드 과정이 있기 때문에 속도와 메모리에서 단점이 될 수 있다.
JVM을 사용하면 운영체제에 상관없이 같은 코드를 사용할 수 있습니다.

 

■ Object

객체(Object)란, 소프트웨어 세계에 구현할 대상
클래스의 인스턴스 라고도 부른다. OOP 관점에서 클래스의 타입으로 선언되었을 때 객체라고 부른다.
객체는 현실 세계에 가깝고, 인스턴스는 소프트웨어 세계에 가깝다.

 

■ 클래스

연관되어 있는 변수와 메서드의 집합
클래스란, 객체를 만들어 내기 위한 설계도 혹은 틀

 

■ 인스턴스

객체를 소프트웨어에 실체화 하면 그것을 인스턴스 라고 부른다.
OOP의 관점에서 객체가 메모리에 할당되어 실제 사용될 때 인스턴스 라고 부른다.
객체는 클래스의 인스턴스이다.

 

■ 인스턴스화

클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화(instantiate) 라고 한다.
어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스(instance) 라고 한다.

 

■ String, StringBuffer, StringBuilder 차이점이 무엇인가요

첫번째 차이점은 String은 불변하다는 특징을 가지고 있어서 수정을 하지못하고 새로운 String 인스턴스가 생성되고 전에 있던 String은 GC에 의해 사라지게 된다. 그래서 좋은 성능을 기대하기는 힘들다. (String 불변, StringBuffer, StringBuilder 가변)
StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전하다는 점(thread-safe) 입니다. 참고로 String도 불변성을 가지기때문에 마찬가지로 멀티쓰레드 환경에서의 안정성(thread-safe)을 가지고 있습니다.
반대로 StringBuilder는 동기화를 지원하지 않기때문에 멀티쓰레드 환경에서 사용하는 것은 적합하지 않지만 동기화를 고려하지 않는 만큼 단일쓰레드에서의 성능은 StringBuffer 보다 뛰어납니다

 

■ 프로세스란?

운영체제로부터 시스템 자원을 할당받는 작업의 단위
하나의 프로세스는 크게 코드영역(code), 데이터 영역(date), 스택 영역(stack), 힙 영역(heap) 4가지로 이루어져 있습니다.

■ 스레드란?

한 프로세스 내에서 동작되는 여러 실행의 흐름, 프로세스 하나에 자원을 공유하면서 일련의 과정을 여러 개를 동시에 실행 시킬 수 있다.
멀티프로세스
장점 : 안정성이 높다 (독립된 구조기 때문에)
단점 : 여러 프로세스를 왔다갔다 하는 컨텍스트 스위칭으로 인한 성능저하
멀티쓰레드
장점 : 응답시간 단축, 자원소모 감소
단점 : 미묘한 시간차나 변수 공유함으로써 오류 발생 가능

■ 자바 람다 관련 함수형 프로그래밍

함수형 프로그래밍은 명령형이 아닌 선언적 방식으로 구현되며 흐름 제어를 명시적으로 기술하지 않고 프로그램 로직이 표현된다는 것을 의미한다.
람다는 함수의 구조로 되어있고 -> 와 같이 화살표 형태의 기호를 이용해 매개변수를 함수 바디로 전달하는 형태

@@ TODO 명령형 vs 선언적 방식의 구현

■ 가비지컬렉션이란?

C/C++ 언어와 달리 자바는 개발자가 명시적으로 객체를 해제할 필요가 없습니다. 자바 언어의 큰 장점이기도 합니다. 사용하지 않는 객체는 메모리에서 삭제하는 작업을 Gargabe Collection(GC)라고 부르며 JVM에서 GC를 수행합니다.

■ 자바 컬렉션 List, set, map에 대한 설명

List : 순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.
Set : 순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않는다.
Map : 키, 값으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며 키의 중복을 허용하지 않으나 값의 중복은 허용한다.

■ 테스트 코드에 대한 설명??

단위테스트를 사용하면 좋은점은 개발 초기에 문제를 발견할 수 있다.

'Java' 카테고리의 다른 글

logger를 사용하자  (0) 2023.02.16
wildfly jboss 서버 아이디 이름 확인  (0) 2022.01.20
Spring Batch embedded tomcat  (0) 2020.07.28
java.lang.NoClassDefFoundError: sun/misc/BASE64Encoder  (0) 2020.01.28
Map 선언 초기화 동시에  (0) 2019.10.24

인텔리제이 설치 전 마지막으로 될지도 모르는 정리

 

 

노란색 : 개인 설정으로 비활성화 해둠

파란색 : 개인 설정으로 추가해서 사용하는것들

 

단축키 설명 추가 설명
F3 Open Declaration 선언한 곳으로 이동. interface 존재 시 interface 로 이동
     
     
Ctrl + 1 Quick Fix  
Ctrl + D Line delete  
Ctrl + H Search  
Ctrl + L Go to Line  
Ctrl + M 전체 화면   
Ctrl + W Tab close  
Ctrl + F3 Open Implementation 구현한 곳으로 이동. interface 구현한 곳 있을 경우 구현한 곳으로 이동
Ctrl + F6 Toggle Tab Ctrl tab 으로 변경시켜둠
Ctrl + F7 Toggle View  
Ctrl + F8 Toggle perspective  
Ctrl + Numpad_- 코드 접기  
Ctrl + Numpad_+ 코드 펼치기   
Ctrl + Numpad_* 코드 전체 접기  
Ctrl + Numpad_/ 코드 전체 펼치기  
Ctrl + Space bar 자동 완성  
     
Ctrl + Alt + 1 Select Editor  
Ctrl + Alt + 2 Select Console  
Ctrl + Alt + 3 Select Project Explorer  
Ctrl + Alt + 4 Select jUnit  
Ctrl + Alt + 5 Select Search  
Ctrl + Alt + H Search Call Hiearchy  
Ctrl + Alt + 위 / Ctrl + Alt + 아래 Line 복사 여러 Line 복사 가능.
Drag 상태 아닌 cursor 상태에서도 가능
     
Ctrl + / 혹은 Ctrl + Shift + C 해당 줄 주석  
     
Ctrl + Shift + O 불필요한 import 삭제 Eclipse 에서는 프로젝트 내 전체에 이 명령어 주는것 없는걸로 알고 있음
Ctrl + Shift + R Open Resource *.java 파일 외 모든 파일 열 수 있음
Ctrl + Shift + T Open Type *.java 파일 열때 사용. *.java 외 파일 열때는 Open Resource
Ctrl + Shift + W Close all tab  
Ctrl + Shift + 좌 / Ctrl + Shift + 우
음절(??) 단위로 선택하며 이동  
     
Alt + F5 Update Maven Project Alt + F4 를 누르지 않게.. 조심..하자...
Alt + 위 / Alt + 아래 Move Line 여러 라인 select 되어 있어도 가능
Drag 상태 아닌 cursor 상태에서도 가능
움직이면 자동으로  inline 맞춰줌
Alt + 좌 / Alt + 우 Backward History / Forward History 이전 / 이후 파일 열기 
닫은 파일도 다시 열린다
     
     
Alt + Shift + A Block 선택 모드 / 일반 선택 모드 토글  
Alt + Shift + L  Extract local variable  
Alt + Shift + M Extract Method 선택한 부분을 Method 로 추출
Alt + Shift + R Rename  변수명 , 함수명 , 클레스명, 패키지명 등 변경
Alt + Shift + S Source 우클릭 > Soruce 와 동일
Alt + Shift + T Refactor 우클릭 > Refactor 와 동일
각종 Extract  수행 가능
Extract as method
Extract as variable(local , constant)
Extract interface, superclass, 등
Alt + Shift + Z Surround with 우클릭 > Surround with 와 동일.
try catch 묶을때 ,

Alt + Shift + 좌 / Alt + Shift + 우 variable (??) 단위로 선택 xml 파일에서는 먹히지 않는다.
Alt + Shift + D, J Debug as java application  
Alt + Shift + D, T Debug as jUnit test  
Alt + Shift + X, J Run as java application  
Alt + Shift + X, T Run as jUnit test  
     

 

su - 아이디 -c "명령어"

해당 아이디의 비밀번호를 알아야 함 

예 ) su - 아이디 -c "cd /home/chris1108 && cat test.log"

 

sudo -u 아이디 명령어

현재 계정에 sudo 권한있으면 가능

"를 붙이면 안됨...

예 ) sudo -u 아이디 cat /home/chris1108/test.log

 

 

'Linux' 카테고리의 다른 글

linux 리눅스 바로가기 만들기  (0) 2023.05.04

Ctrl Shift C 블록 선택 활성화

Ctrl Shift N 블록 선택 비활성화 ( 일반 선택 ) 

 

 

'DB' 카테고리의 다른 글

H2 Database 생성하기  (0) 2023.07.08

wildfly에서 jboss를 통해 하나의 deployment 를 여러 서버에 올렸을 경우 java 에서 어느 서버인지 확인하는 법

String result1 = System.getProperty("jboss.node.name");
String result2 = System.getProperty("jboss.server.name");
System.out.println(result1);
System.out.println(result2);

결과

hostName1:server01-1
server01-1

 

'Java' 카테고리의 다른 글

logger를 사용하자  (0) 2023.02.16
Java 면접 예상질문 질의응답  (0) 2023.01.31
Spring Batch embedded tomcat  (0) 2020.07.28
java.lang.NoClassDefFoundError: sun/misc/BASE64Encoder  (0) 2020.01.28
Map 선언 초기화 동시에  (0) 2019.10.24

Toby's spring 공부 도중 해당 Exception 발생

 

java.lang.Exception: Unexpected exception, expected<org.springframework.dao.DataIntegrityViolationException> but was<java.lang.NoClassDefFoundError>
	at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.NoClassDefFoundError: org/springframework/dao/DuplicateKeyException
	at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:811)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:867)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:875)
	at springbook.user.dao.UserDaoJdbc.add(UserDaoJdbc.java:86)
	at springbook.test.UserDaoTest.duplicateKey(UserDaoTest.java:135)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:21)
	... 21 more
Caused by: java.lang.ClassNotFoundException: org.springframework.dao.DuplicateKeyException
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	... 37 more

해결 방안

<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.3.13</version>
</dependency>

추가 

+ Recent posts