문제

두 정수 A와 B를 입력받은 다음, A/B를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

출력

첫째 줄에 A/B를 출력한다. 절대/상대 오차는 10-9 까지 허용한다.


단순하게 나누어서 a / b 로 출력을 하면 틀렸다는 결과를 얻게 된다.

자리 값을 생각하지 않아서 나온 결과이다. 

C++에서는 아래의 코드가 필요하다.

cout << fixed; // 소수점을 고정시키겠다.

cout.precision(9); // 9자리까지 표현할 것이다 ( 10번째자리에서 반올림)

 

반대로 해제하려면 아래의 코드가 필요하다.

cout.unsetf(ios::fixed); // 소수점 고정을 해제하겠다.

 

#include <iostream>


using namespace std;

int main()
{
	double a, b;

	cin >> a >> b;

	cout << fixed;

	cout.precision(9);

	cout << a / b << endl;
}

문제

두 정수 A와 B를 입력받은 다음, A-B를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

출력

첫째 줄에 A-B를 출력한다.


백준 1000번 문제와 마찬가지로

튜토리얼 같은 문제! 백준을 처음 입문하면서

입출력 방식을 테스팅 해보기 좋은 예제라고 생각한다.

#include <stdio.h>
int main()


{
	int a, b;

	scanf("%d %d",&a, &b);
	
	if (0<a<10 && 0<b<10){
		printf("%d", a - b);
	}
	
}

문제

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

출력

첫째 줄에 A+B를 출력한다.

 


백준 알고리즘의 입문을 위한 문제라고 생각한다.

튜토리얼 같은 문제이므로 코드 설명은 패스!

#include <stdio.h>
int main()


{
	int a, b;

	scanf("%d %d",&a, &b);
	
	if (0<a<10 && 0<b<10){
		printf("%d", a + b);
	}
	
}

문제

어떤 동물원에 가로로 두칸 세로로 N칸인 아래와 같은 우리가 있다.

이 동물원에는 사자들이 살고 있는데 사자들을 우리에 가둘 때, 가로로도 세로로도 붙어 있게 배치할 수는 없다. 이 동물원 조련사는 사자들의 배치 문제 때문에 골머리를 앓고 있다.

동물원 조련사의 머리가 아프지 않도록 우리가 2*N 배열에 사자를 배치하는 경우의 수가 몇 가지인지를 알아내는 프로그램을 작성해 주도록 하자. 사자를 한 마리도 배치하지 않는 경우도 하나의 경우의 수로 친다고 가정한다.

입력

첫째 줄에 우리의 크기 N(1≤N≤100,000)이 주어진다.

출력

첫째 줄에 사자를 배치하는 경우의 수를 9901로 나눈 나머지를 출력하여라.


경우의 수를 3가지로 나누어 생각해볼 수 있다.

1) n번째 줄에 사자가 왼쪽에 있는경우 

n-1번째 줄의 오른쪽 칸에 사자가 있거나 + 양쪽 칸에 사자가 모두 없는 경우

DP[i][1] = (DP[i - 1][0] + DP[i - 1][2])

 

2) n번째 줄에 사자가 오른쪽에 있는경우 

n-1번째 줄의 왼쪽 칸에 사자가 있거나 + 양쪽 칸에 사자가 모두 없는 경우

DP[i][2] = (DP[i - 1][0] + DP[i - 1][1])

 

3) n번째 줄에 사자가 없는 경우 

n-1번째 줄에 왼쪽 오른쪽 모두 사자가 없는 경우 + 왼쪽에 있는 경우 + 오른쪽에 있는 경우

D[DP[i][0] = (DP[i - 1][0] + DP[i - 1][1] + DP[i - 1][2])

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

// BOJ_1309
// 동물원
// DP
public class Main {

	static int N;
	static int DP[][];

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());

		N = Integer.parseInt(st.nextToken());

		int[][] DP = new int[N + 1][3];

		DP[1][0] = 1;
		DP[1][1] = 1;
		DP[1][2] = 1;

		for (int i = 2; i <= N; i++) {
			DP[i][0] = (DP[i - 1][0] + DP[i - 1][1] + DP[i - 1][2]) % 9901;
			DP[i][1] = (DP[i - 1][0] + DP[i - 1][2]) % 9901;
			DP[i][2] = (DP[i - 1][0] + DP[i - 1][1]) % 9901;
		}
		System.out.println((DP[N][0] + DP[N][1] + DP[N][2]) % 9901);
	}
}

| final, finally, finalize 차이점

 

1. final

 

final은 사용되는 문맥에 따라 다르다.

변수에 적용하면 : 해당 변수의 값은 변경이 불가능해진다. 상수가 되기 때문

변수의 참조에 적용하면 : 참조 변수가 힙 내의 다른 객체를 가리키도록 변경할 수 없다.

 

메서드에 적용하면 : 해당 메서드를 상속받는 하위 클래스에서 오버라이딩 할 수 없다.(상속받는 하위 클래스에서도 변경이 되지 않아야 하는 메서드의 경우 final을 붙이면 된다.)

 

클래스에 적용하면 : 해당 클래스를 다른 클래스가 상속받을 수 없다. 즉, final 클래스의 하위 클래스를 정의할 수 없다. ->이건 언제 쓰는 걸까??

 

 

 

2. finally

 

finally는 try-catch 블록 뒤에 둘 수 있는 선택적인 블록인데 try-catch문이 끝나기전에 항상 꼭 실행되어야하는 로직이 있을 경우 finally절에 두면된다.

try-catch블록과 함께 사용되며 예외가 던져지더라도 항상 실행될 코드를 지정하기 위해 사용된다. finally블록은 try와 catch블록이 전부!!! 실행된 후, 그리고 제어 흐름이 원래 지점으로 돌아가기 전에 실행된다.(코드 확인할 것)

 즉, 보통 뒷 마무리 코드를 작성하는데 사용된다.

(DB연결을 하거나 I/O 스트림을 열었을때 다 사용하거나면 닫아주는 작업 등)

public class TryEx {

    public static String lem(){
        System.out.println("lem");
        return "return from lem";
    }// lem()
     
    public static String foo(){
        int x = 0; 
        int y = 5;
         
        try{
            System.out.println("start try");
            int b = y/x;
            System.out.println("end try");
            return "returned from try";
        }catch(Exception e) {
            System.out.println("catch");
            // catch문 실행 된 후(return문 까지 실행 된 후) finally문 실행된 후 마지막 catch문의 return 값이 반환된다.
            return lem() + " | returned from catch";
        }finally{
            System.out.println("finally");
        }
    }// foo()
     
    public static void bar(){
        System.out.println("start bar");
        String v = foo();
         
        System.out.println(v);
        System.out.println("end bar");

    }// bar()
     
    public static void main(String[] args){
        bar();
    }// main()
     
}// class
/*
 *      try 블럭을 실행하다가 예외를 만나면 catch 블럭으로 간 후, catch블럭이 실행된다. 이때 catch블럭의 return문까지 모두 다 실행 된 후, 
 *      finally블럭이 실행 된 다음에서야 return이 이루어지는 것을 확인할 수 있다.
 *      즉, finally 블럭은 try 블럭이 종료되는 순간 실행된다. 만약 try블럭 안에 return문을 넣더라도 finally블록은 try 블록이 종료되는
 *      순간 실행된다. try블럭에서 return | continue | break 문을 실행하거나 예외를 던진다거나해도 실행되는 것이다.
 * 
 *      단,  try/catch 블록 수행 중에 가상머신이 종료되거나
 *          try/catch를 수행하고 있던 쓰레드가 죽어버리면 finally블럭이 실행되지 않는다.
 * */

 

 

 
<결과>
start bar
start try
catch
lem
finally
return from lem | returned from catch
end bar
 
=>    즉, 코드 수행 순서가
  try문 실행-> 예외 발생 -> catch문 실행( return문에 있는 코드 까지 모두 실행) -> finally문 실행 -> return 수행
 
 
 

Q) Java의 finally 블록은 try-catch-finally의 try블록 안에 return 문을 넣어도 실행되나?

A) try 블럭을 실행하다가 예외를 만나면 catch 블럭으로 간 후, catch블럭이 실행된다. 이때 catch블럭의 return문까지 모두 다 실행 된 후, finally블럭이 실행 된 다음에서야 return이 이루어지는 것을 확인할 수 있다.

즉, finally 블럭은 try 블럭이 종료되는 순간 실행된다. 만약 try블럭 안에 return문을 넣더라도 finally블록은 try 블록이 종료되는 순간 실행된다. try블럭에서 return | continue | break 문을 실행하거나 예외를 던진다거나해도 실행되는 것이다.

 

단, try/catch 블록 수행 중에 가상머신이 종료되거나

 

  try/catch를 수행하고 있던 쓰레드가 죽어버리면 finally블럭이 실행되지 않는다.

 

 
 
3. finalize()
 
finalize() 메서드는 java garbage collector가 더 이상의 참조가 존재하지 않는 객체를 발견한 순간 호출하는 메서드다. 즉 더이상 사용되지 않는 객체가 있을때 메모리 낭비를 막기 위해서 garbage collector가 이 객체를 없애버리는데 이때 해당객체의 finallize 메서드를 호출해서 없앤다. 이 finallize()는 java.lang.Object클래스로 부터 상속받아 모든 클래스의 객체가 가지고 있는 메서드다. 즉, 만약 객체가 삭제되기 직전에 실행되어야 하는 로직같은게 있으면 Object 클래스에 정의된 finalize() 메서드를 오버라이딩하여 정의할 수 있다. 
 
하지만!! finalize()는 언제 호출될지 알 수 없기 때문에, finalize()를 오버라이딩 했다고해서 여기에 의존하는 방식의 코딩은 좋은 방법은 아닐 수 있다.

 

BufferedReader, BufferedWriter를 활용한 빠른 입출력

 

BufferedReader/BufferedWriter는 Buffer에 있는 IO 클래스입니다. 입력된 데이터가 바로 전달되지 않고 중간에 버퍼링이 된 후에 전달되됩니다. 출력도 마찬가지로 버퍼를 거쳐서 간접적으로 출력장치로 전달되기에 시스템의 데이터처리 효율성을 높여주며 버퍼스트림을InputStreamReader / OutputStreamWriter를 같이 사용하여 버퍼링을 하게 되면 입출력 스트림으로부터 미리 버퍼에 데이터를 갖다 놓기 때문에 보다 효율적인 입출력이 가능합니다.

▶BufferedReader 

Java를 처음 접하시는 분들이 주로 받는 입력방식은 Scanner입니다. Scanner를 통해 입력을 받을경우 Space Enter를 모두 경계로 인식하기에 입력받은 데이터를 가공하기 매우 편리합니다. 하지만 그에비해 BufferedReader는 Enter만 경계로 인식하고 받은 데이터가 String으로 고정되기때문에 입력받은 데이터를 가공하는 작업이 필요할경우가 많습니다. Scanner에 비해 다소 사용하기 불편하죠. 하지만 많은 양의 데이터를 입력받을경우 BufferedReader를 통해 입력받는 것이 효율면에서 훨씬 낫습니다. 입력시 Buffer 메모리줌으로써 작업속도 차이가 많이납니다.

 

BufferedReader 사용법

BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); //선언 
String s = bf.readLine(); //
String int i = Integer.parseInt(bf.readLine()); //Int

 선언은 위에 있는 예제와 같이 하시면 됩니다. 입력은 readLine();이라는 메서드를 활용하시면 되는데요. 여기서 주의할점이 두가지가 있습니다. 첫번째는 readLine()시 리턴값을 String으로 고정되기에 String이 아닌 다른타입으로 입력을 받을려면 형변환을 꼭 해주어야한다는 점입니다. 두번째는 예외처리를 꼭 해주어야한다는 점입니다. readLine을 할때마다 try & catch를 활용하여 예외처리를 해주어도 되지만 대개 throws IOException을 통하여 작업합니다.

 

Read한 데이터 가공

StringTokenizer st = new StringTokenizer(s); //StringTokenizer인자값에 입력 문자열 넣음 
int a = Integer.parseInt(st.nextToken()); //첫번째 호출 
int b = Integer.parseInt(st.nextToken()); //두번째 호출  
String array[] = s.split(" "); //공백마다 데이터 끊어서 배열에 넣음

 Read한 데이터는 Line단위로만 나눠지기에 공백단위로 데이터를 가공하려면 따로 작업을 해주어야하는데요. 위의 두가지 방법이 대표적입니다. 첫번째 방법으로는 StringTokenizer에 nextToken()함수를 쓰면 readLine()을 통해 입력받은 값을 공백단위로 구분하여 순서대로 호출할 수 있습니다. 두번째방법으로는 String.split()함수를 활용하여 배열에 공백단위로 끊어서 데이터를 넣고 사용하는 방식입니다.

 

▶BufferedWriter 

일반적으로 출력을할때 System.out.println(""); 방식을 사용하고는 합니다. 적은양의 출력일 경우 성능차이가 미미하겠지만 많은 양의 출력에서는 입력과 마찬가지로 Buffer를 활용해주시는것이 좋습니다.

 

BufferedWriter 사용법

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));//선언 String s = "abcdefg";//출력할 문자열 bw.write(s+"\n");//출력 bw.flush();//남아있는 데이터를 모두 출력시킴 bw.close();//스트림을 닫음

BufferedWriter 의 경우 버퍼를 잡아 놓았기 때문에 반드시 flush() / close() 를 반드시 호출해 주어 뒤처리를 해주어야합니다. 그리고 bw.write에는 System.out.println();과 같이 자동개행기능이 없기때문에 개행을 해주어야할 경우에는 \n를 통해 따로 처리해주어야합니다.

 

주요 Method

메서드명   기능
 BufferedReader(Reader rd)  rd에 연결되는 문자입력 버퍼스트림 생성
 BufferedWriter(Writer wt)   wt에 연결되는 문자출력 버퍼스트림 생성​
 int read()  스트림으로부터 한 문자를 읽어서 int 형으로 리턴
 int read(char[] buf)  문자배열 buf의 크기만큼 문자를 읽어들임.  읽어들인 문자 수를 리턴
 int read(char[] buf, int offset, int length)  buf의 offset위치에서부터 length 길이만큼 문자를 스트림으로부터 읽어들임​
 String readLine()  스트림으로부터 한 줄을 읽어 문자열로 리턴​​
 void mark()   현재우치를 마킹, 차 후 reset() 을 이용하여 마킹위치부터 시작함
 void reset()   마킹이 있으면 그 위치에서부터 다시시각, 그렇지 않으면 처음부터 다시시작
 long skip(int n)  n 개의 문자를 건너 뜀
 void close()  스트림 닫음
 void write(int c)  int 형으로 문자 데이터를 출력문자스트림으로 출력
 void write(String s, int offset, int length)  문자열 s를 offset 위치부터 length 길이만큼을 출력스트림으로 출력
 void write(char[] buf, int offset, int length)  문자배열 buf의 offset 위치부터 length 길이만큼을 출력스트림으로 출력​​​
 void newLine()  줄바꿈 문자열 출력
 void flush()   남아있는 데이터를 모두 출력시킴.
 

 

쿠키와 세션을 이용한 자동 로그인 방식에 대해서 정리해 보겠습니다.


[    1. 쿠키와 세션이란?    ]


: 쿠키와 세션은 매우 유사하면서도 다른 특징을 지니고 있는데요.

- 공통점 : 사용자의 정보(데이터)를 저장할 때 이용된다.

- 차이점 : 

- 쿠키 : 1) 사용자의 로컬에 저장되었다가 브라우저가 요청시 왔다갔다하게 됨(보안에 취약)

     2) 세션과 달리 여러 서버로 전송이 가능함

     3) 세션이 브라우저 단위로 생성되어 브라우저 종료시 사라지는데 반해, 쿠키는 유효시간 설정을 할 수 있음. ex) 7일

- 세션 : 1) 서버에 데이터를 저장하여 쿠키에 비해 보안에 안전함

     2) 브라우저 단위로 생성됨 => 익스플로러를 켜고 크롬을 켜고 하면 각각 2개의 세션이 생성되는 것


[    2. why 쿠키와 세션을 이용한 로그인 처리를 하게 될까?    ]


: 세션은 위에서 설명한대로 기본 단위가 "웹 브라우저"입니다. 따라서, 웹 브라우저 종료시 소멸하게 되죠...

  그에 반해 쿠키는 사용자 PC에 저장되기 때문에 서버 요청시 전달되는 동안 네트워크 상에서 보안상 취약할 수는 있지만 유효시간을

  길게 설정할 수 있어 브라우저가 종료되는 것과 별개로 7일 30일 등 기간을 길게 설정할 수 있습니다.

  하지만, 

  그렇다고 쿠키에 로그인할 사용자의 정보를 담고 있는다면 정말 정말 너무 너무 보안상 취약할 것을 알 수 있겠죠?

  따라서, 자동 로그인을 구현할 때에는 "< 세션과 쿠키를 동시에 사용하는 것 >"이 바람직하다고 생각합니다.


[    3. 세션과 쿠키를 이용한 자동 로그인 구현에 대한 개요    ]


: 사용자가 로그인 폼에서 로그인을 할 당시, 자동로그인을 설정하겠다는 CheckBox를 클릭할 경우 사용자의 정보를 저장시키고 유효

기간을 설정한다는 것 까지는 알겠는데 그럼 도대체 어떤 사용자의 정보를 저장시켜 놓아야할까요?


먼저, 사용자가 로그인에 성공한 경우! -> 세션에 사용자 객체(UserVO)를 저장시켰었는데 앞에서 이 객체를 쿠키에 저장시킨다면, 굉장히 보안상 취약합니다. 비밀번호, 아이디 그 외 정보까지 UserVO에 들어 있었죠...

따라서, 로그인에 성공했을 때 사용자 DB 테이블에 sessionId와 유효시간 속성에 값을 지정하는 겁니다. 그리고 쿠키에는 세션Id를

넣어 놓는거죠... 그리고 "인터셉터"에서 해당 쿠키값이 존재하면 사용자 DB 테이블 내에서 유효시간 > now() 즉, 유효시간이 아직 

남아 있으면서 해당 세션 Id를 가지고 있는 사용자 정보를 검색해 해당 사용자 객체를 반환하는 겁니다.


당연히, 쿠키가 유효시간이 다되면 해당 자동완성 기능은 동작하지 않게 되고 다시 쿠키를 사용하겠다는 선택을 했을 때 동작하게 되겠죠

그럼, 다음으로 코드상에서 직접 한번 알아 봅시다.





출처: https://rongscodinghistory.tistory.com/3 [악덕고용주의 개발 일기]

WARN : org.springframework.web.context.support.XmlWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'boardDAOSpring': Unsatisfied dependency expressed through field 'jdbcTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.JdbcTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'boardDAOSpring': Unsatisfied dependency expressed through field 'jdbcTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.JdbcTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1378)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)

at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:701)

at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:667)

at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:715)

at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:590)

at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:529)

at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:169)

at javax.servlet.GenericServlet.init(GenericServlet.java:158)

at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1124)

at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1079)

at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:971)

at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4829)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5143)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1432)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1422)

at java.util.concurrent.FutureTask.run(Unknown Source)

at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)

at java.util.concurrent.AbstractExecutorService.submit(Unknown Source)

at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)

at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1432)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1422)

at java.util.concurrent.FutureTask.run(Unknown Source)

at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)

at java.util.concurrent.AbstractExecutorService.submit(Unknown Source)

at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)

at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:261)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:801)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.startup.Catalina.start(Catalina.java:695)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)

at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.JdbcTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1644)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1203)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)

... 52 more



xml에서 bean 다 해줬고,, maven 여러번 재설정해보고

어노테이션 다 확실하게 해줬고.. 무슨 오류인지 내일 다시한번해보자


>>>

WebInfo 폴더 밑에 있는 web.xml 에서


설정이 겹치는 부분이 있었다.. 바로해결완료


Spring Framework 관련 질문

1. 스프링 프레임워크란?

  • 자바 앤터프라이즈 개발을 편리하게 해주는 경량급 오픈소스 애플리케이션 프레임워크

  • POJO기반의 Enterprise Application 개발을 쉽고 편하게 할 수 있도록 한다.

  • Java Application을 개발하는데 필요한 하부구조를 포괄적으로 제공하기때문에 개발자는 Application 개발에 집중할 수 있다.

  • 대한민국 공공기간의 웹 서비스 개발시 사용을 권장하고 있는 전자 정부 표준 프레임워크의 기반 기술이다.

2. Container란?

  • 컨테이너는 보통 instance의 Life Cycle을 관리하며, 생성된 인스턴스에게 추가적인 기능을 제공하도록 하는 것이다. 다시 말해, 컨테이너란 작성한 코드의 처리과정을 위임받은 독립적인 존재라고 생각하면 된다.

  • 컨테이너는 적절한 설정만 되어있다면, 누구의 도움없이도 프로그래머가 작성한 코드를 스스로 참조한 뒤 알아서 객체의 생성과 소멸을 컨트롤 해준다.

3. IOC란?

  • IoC(Inversion of Control)이란, 객체의 생성부터 Life Cycle 관리까지 모든 객체에 대한 제어권이 바뀐 것을 의미 합니다. 또는 제어권한이 다른 대상에게 위임하는 것입니다. (여기서 다른 대상은 Servlet과 같은 Bean을 관리해주는 container)

  • 이 방식은 대부분의 프레임워크에서 사용하는 방법으로, 개발자는 필요한 부분을 개발해서 끼워넣기의 형태로 개발하고 실행하게 됩니다. 프레임워크가 이러한 구조를 가지기 때문에 개발자는 프레임워크에 필요한 부품을 개발하고 조립하는 방식의 개발을 하게 된다.

4. Framework와 Library의 차이?

  • IoC의 개념이 적용되었나의 차이

  • 라이브러리를 사용하는 애플리케이션 코드는 애플리케이션 흐름을 직접 제어한다. 단지 동작하는 중에 필요한 기능이 있을 때 능동적으로 라이브러리를 사용할 뿐이다.

  • 반면에 프레임워크는 거꾸로 애플리케이션 코드가 프레임워크에 의해 사용된다. 보통 프레임워크 위에 개발한 클래스를 등록해두고, 프레임워크가 흐름을 주도하는 중에 개발자가 만든 애플리케이션 코드를 사용하도록 만드는 방식이다.

5. DI (Dependency Injection)

  • DI 란?

    • Dependency Injection은 Spring Framework에서 지원하는 IoC의 형태이다.

    • DI는 클래스 사이의 의존관계를 Bean 설정 정보를 바탕으로 컨테이너가 자동적으로 연결해주는 것을 말한다. 개발자들은 제어를 담당할 필요없이 Bean 설정 파일에 의존관계가 필요하다는 정보만 추가해주면 된다.

    • 컨테이너가 실행 흐름의 주체가 되어 Application 코드의 의존관계를 주입해주는 것

  • 의존성이란?

    • 현재 객체가 다른 객체와 상호작용하고 있다면 다른 객체들을 현재 객체의 의존이라 한다.

  • 의존성이 위험한 이유

    • 하나의 모듈이 바뀌면 의존하고 있는 다른 모듈까지 변경되어야 한다.

    • 테스트 가능한 어플을 만들 때 의존성이 있으면 유닛테스트 작성이 어렵다.

    • 유닛테스트의 목적 자체가 다른 모듈로부터 독립적으로 테스트하는 것을 요구한다.

  • DI의 특징

    • 'new'를 사용해 모듈 내에서 다른 모듈을 초기화하지 않으려면 객체 생성은 다른 곳에서 하고, 생성된 객체를 참조하면 된다.

    • 의존성 주입은 IoC 개념을 바탕으로 한다. 클래스가 외부로부터 의존성을 가져야한다.

  • DI가 필요한 이유

    • 클래스를 재사용 할 가능성을 높이고, 다른 클래스와 독립적으로 클래스를 테스트 할 수 있다.

    • 비즈니스 로직의 특정 구현이 아닌 클래스를 생성하는데 매우 효과적

  • DI의 세가지 방법

    • Contructor Injection : 생성자 삽입

    • Method(Setter) Injection: 메소드 매개 변수 삽입

    • Field injection : 맴버 변수 삽입

6. AOP란 ?

  • Aspect Oriented Programming 관점 지향 프로그래밍의 약자

  • 기존의 OOP에서 기능별로 class를 분리했음에도 불구하고, 여전히 로그, 트랜잭션, 자원해제, 성능테스트, 등 처럼 공통적으로 반복되는 중복코드 ( 횡단 관심사 ) 가 나오는 단점을 해결하고자 나온 방식

  • 개발코드에서는 비지니스 로직에 집중하고 실행시 비지니스 로직 앞, 뒤 등 원하는 지점에 해당 공통 관심사를 수행할 수 있게 함으로써 중복 코드를 줄일 수 있는 방법

7. POJO란?

  • 번역하면 '평범한 구식 자바 객체', 즉 Framework Interface나 class를 구현하거나 확장하지 않은 단순한 클래스.

  • 특징

    • Java에서 제공하는 API 외에 종속되지 않음

    • 특정 규약, 환경에 종속되지 않음

  • 환경에 종속되지 않는 것의 장점

    • 코드의 간결함 (비즈니스 로직과 특정 환경/Low 레벨 종속적인 코드를 분리하므로 단순)

    • 비즈니스 로직과 특정 환경이 분리되므로 단순함

    • 자동화 테스트에 유리 (환경 종속적인 코드는 자동화 테스트가 어렵지만, POJO는 테스트가 유연)

8. DAO란?

  • DB에 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 객체를 말한다.

  • DB에 접근을 하기 위한 로직과 비즈니스 로직을 분리하기 위해서 사용한다.

9. VO란?

  • 계층간 데이터 교환을 위한 자바빈즈를 말한다.

    (여기서 말하는 계층은 Controller, View Business, Persistent Layer)

  • 일반적인 VO는 로직을 가지고 있지 않은 순수한 데이터 객체이며, 속성과 그 속성에 접근하기 위한 getter, setter 메소드만 가진 클래스이다.

  • DTO 라고도 불린다.

10. JDBC란?

  • Java Data Base Connection의 약자로 JAVA 언어를 통해 데이터 베이스에 접근 할 수 있는 프로그래밍

11. Mybatis란 ?

  • 객체, 데이터베이스, 매퍼 자체를 독립적으로 작성하고 DTO에 해당하는 부분과 SQL실행결과를 SQL문등에 매핑해서 사용할 수 있도록 지원

  • 스프링이나 JDBC를 통해 작업하던 dao에 관련된 작업은 모두 sql문이 자바 소스상에 위치했었으나 이제 sql문은 설정파일로 관리한다.

  • 설정파일로 분리되면 변경되거나 했을때 설정파일만 건드리면 되므로 유지보수에 좋다. 또한, 매개변수나 리턴타입으로 매핑되는 모든 DTO에 관련된 부분도 모두 설정파일에서 작업한다

12. MVC 패턴에 대해 설명해보세요

MVC란?

- 객체지향프로그래밍에서, MVC란 사용자 인터페이스를 성공적이며 효과적으로 데이터 모형에 관련 시키기 위한 방법론 또는 설계 방식중 하나이다. MVC방식은 자바, Smalltalk,

- MVC 패턴은 목적 코드의 재사용에 유용한 것은 물론, 사용자 인터페이스와 응용프로그램 개발에 소요되는 시간을 현저하게 줄여주는 형식이라고 많은 개발자들이 평가하고 있다.

MVC 구성요소

Model - 소프트웨어 응용과 그와 관련된 고급 클래스 내의 논리적 데이터 기반 구조를 표**현**. 이 목적 모형은 사용자 인터페이스에 관한 어떠한 정보도 가지고 있지 않다.

View - 사용자 인터페이스 내의 구성요소들을 표현(사용자에게 보여지는 화면)

Controller - Model과 View를 연결하고 있는 클래스를 대표, Model과 View 내의 클래스들 간 정보 교환하는데 사용.

Spring MVC 처리 순서**

  1. 클라이언트(Client)가 서버에 어떤 요청(Request)을 한다면 스프링에서 제공하는 DispatcherServlet 이라는 클래스(일종의 front controller)가 요청을 가로챈다.

  2. (web.xml에 살펴보면 모든 url ( / )에 서블릿 매핑을하여 모든 요청을 DispatcherServlet이 가로채게 해둠(변경 가능))

  3. 요청을 가로챈 DispatcherServlet은 HandlerMapping(URL 분석등..)에게 어떤 컨트롤러에게 요청을 위임하면 좋을지 물어본다. (servlet-context.xml에서 @Controller로 등록한 것들을 스캔해서 찾아준다.)

  4. 요청에 매핑된 컨트롤러가 있다면 @RequestMapping을 통하여 요청을 처리할 메서드에 도달한다.

\4. 컨트롤러에서는 해당 요청을 처리할 Service를 주입(DI)받아 비즈니스로직을 Service에게 위임한다.

\5. Service에서는 요청에 필요한 작업 대부분(코딩)을 담당하며 데이터베이스에 접근이 필요하면 DAO를 주입받아 DB처리는 DAO에게 위임한다.

\6. DAO는 mybatis(또는 hibernate등) 설정을 이용해서 SQL 쿼리를 날려 DB의 정보를 받아 서비스에게 다시 돌려준다.

(이 때 보통 VO(dto)를 컨트롤러에서 부터 내려받아 쿼리의 결과를 VO에 담는다. (mybatis의 resultType)

\7. 모든 로직을 끝낸 서비스가 결과를 컨트롤러에게 넘긴다.

\8. 결과를 받은 컨트롤러는 Model객체에 결과물 어떤 view(jsp)파일을 보여줄 것인지등의 정보를 담아 DispatcherServlet에게 보낸다.

\9. DispatcherServlet은 ViewResolver에게 받은 뷰의 대한 정보를 넘긴다.

\10. ViewResolver는 해당 JSP를 찾아서(응답할 View를 찾음) DispatcherServlet에게 알려준다.

(servlet-context.xml에서 suffix, prefix를 통해 /WEB-INF/views/index.jsp 이렇게 만들어주는 것도 ViewResolver)

\11. DispatcherServlet은 응답할 View에게 Render를 지시하고 View는 응답 로직을 처리한다.

\12. 결과적으로 DispatcherServlet이 클라이언트에게 렌더링된 View를 응답한다. -->

기업이라면 침입탐지시스템(Intrusion Detection System, IDS)를 사용해 네트워크를 모니터링하고 의심스러운 활동을 신고하거나 잠재적인 악성 트래픽을 자동으로 막아야 한다. 이번 기사에서는 5가지 최고의 오픈소스 IDS를 살펴보자.

Credit: Getty Images Bank

사이버보안 전문가로서 공격자가 네트워크에 액세스하는 것을 막으려고 노력하지만 모바일 기기, 분산된 팀, IoT(Internet of Things)의 등장으로 기하급수적으로 늘어난 경계를 보호하는 것은 쉽지 않다. 불편한 진실은 공격자가 가끔은 내부에 들어올 것이라는 점과 이 공격을 발견하는 데 오래 걸릴수록 데이터 유출 비용은 증가한다는 것이다. 강력한 사고 대응 계획의 일환으로 견고한 IDS를 사용함으로써 침해의 잠재적 피해를 줄일 수 있다.

IDS는 일반적으로 2가지로 분류할 수 있다. 알려진 악의적인 트래픽 패턴과 경고를 검색하는 시그니처 기반의 IDS가 있으며, 시그니처가 아닌 표준과의 편차를 표시하기 위한 기준선을 보는 비정상 행위 기반의 IDS가 있다.

데이터와 시스템을 보호하려면 내부 서버에서 데이터센터, 퍼블릭 클라우드 환경에 이르기까지 네트워크에 IDS를 배포하는 것이 중요하다. IDS는 내부자 위협과 하루종일 넷플릭스 스트리밍을 즐기거나 페이스북 메신저를 통해 채팅하는 등의 직원의 태만 행동을 적발할 수 있다. 다행히도 살펴볼 만한 오픈소스 IDS가 많이 있으며, 그 가운데 5가지를 알아보자.

1. 스노트(Snort)
스노트는 IDS의 사실상 표준으로 매우 가치있는 도구다. 이 리눅스 유틸리티는 배포하기 쉽고 침입 시도와 로깅에 대한 네트워크 트래픽을 모니터링하고 침입 시도가 탐지됐을 때 특정 행동을 수행하도록 구성할 수 있다. 가장 널리 배포된 IDS 도구 가운데 하나이며, 침입 방지 시스템(Intrusion Prevention System, IPS) 역할도 한다. 

스노트는 1998년으로 거슬러 올라간다. 그리고 매우 활동적이고 유익한 커뮤니티가 큰 지원을 제공한다. 여기에는 GUI와 관리 콘솔이 없지만 스노비(Snorby)나 베이스(Base)와 같은 다른 오픈소스 툴을 사용하면 그 차이를 좁힐 수 있다. 스노트가 제공하는 높은 수준의 사용자 정의는 많은 조직에게 좋은 선택지가 된다.

스노트를 사용하고 싶지 않다면 수리카타(Suricata)가 강력한 대안이다.

2. 브로(Bro)
트래픽을 일련의 이벤트로 변환하는 분석 엔진으로 구동되는 브로는 의심스러운 시그니처와 비정상적 행위를 탐지할 수 있다. 브로 스크립트(Bro-Script)를 사용하면 정책 엔진에 대한 작업을 만들 수 있으므로 더 많은 작업을 자동화하려는 사람이라면 누구에게나 효용성이 있다. 

예를 들어, 이 도구는 네트워크에 있는 의심스러운 파일을 자동으로 다운로드하고 분석을 위해 보내고, 문제가 되는 것이 발견되면 관련 사용자에게 알리고, 소스를 블랙리스트에 올리고, 다운로드한 기기를 종료할 수 있다.

브로의 단점은 가중치를 최대로 끌어내기 위한 가파른 학습 곡선에 있으며 설정하는 것이 복잡할 수 있다는 것이다. 그러나 커뮤니티가 점점 더 성장해 많은 도움을 제공하고 있다. 브로는 다른 침입 탐지 도구가 놓칠 수 있는 예외와 패턴을 탐지할 수 있다.

3. 키스멧(Kismet)
무선IDS의 표준인 키스멧은 대부분의 기업에서 필수적인 도구다. 와이파이 및 블루투스를 포함한 무선 프로토콜에 초점을 맞추고 직원이 실수로 쉽게 생성할 수 있는 무단 액세스 포인트를 추적한다. 기본 네트워크 또는 구성 간격을 탐지할 수 있으며, 채널을 도약할 수 있지만 네트워크를 검색하는 데 오랜 시간이 걸리고 최상의 결과를 얻으려면 범위가 제한적이다. 

키스멧은 안드로이드와 iOS를 포함한 여러 플랫폼에서 실행되지만 윈도우 지원은 제한적이다. 추가 도구를 위해 통합하기 위한 다양한 API가 있으며, 작업 효율을 위해 다중 스레드 패킷 디코딩을 제공한다.

4. 오섹(OSSEC)
호스트 기반 IDS 또는 HIDS를 살펴본다면 오섹을 찾게 된다. 오섹은 가장 완벽한 기능의 HIDS다. 확장성이 뛰어나 윈도우, 리눅스, 맥OS, 솔라리스(Solaris) 등 대부분의 주요 운영체제에서 실행된다. 분석을 위해 중앙 서버에 경고 및 로그를 전송하는 클라이언트 서버 아키텍처가 있다. 

이는 호스트 시스템이 오프라인 상태로 되거나 완전히 해킹당한 경우에도 경고가 진행된다는 걸 의미한다. 또한 이 아키텍처를 사용하면 여러 에이전트를 중앙에서 관리할 수 있으므로 배포가 간편해진다.

작은 인스톨러이기 때문에 한번 실행하고 나면 시스템 자원에 미치는 영향이 미비하다. 또한 사용자 정의가 가능하며 실시간 자동적으로 작동하도록 구성할 수 있다. 오섹은 커다란 커뮤니티를 보유하고 있으며, 이를 통해 많은 자원을 활용할 수 있다. 중앙 서버이기 때문에 잠시 멈추는 경우, 삼하인 랩(Samhain Labs)을 호스트 기반의 대안으로 고려해 볼 수 있지만 에이전트로부터 여러 출력 방법을 제공한다.

5. 오픈 DLP(Open DLP)
데이터 유출 방지(Data Loss Prevention, DLP)는 오픈DLP의 목표다. 데이터베이스나 파일 시스템에서 데이터를 검색하는 동안 데이터를 검사할 수 있다. 오픈 DLP는 조직과 관련된 주요 데이터를 검색해 해당 데이터의 무단 복사 및 전송을 발견한다. 이는 악의적인 내부자 또는 무능한 직원이 자신이 해서는 안되는 데이터를 보내는 행위들을 발견하는데 유용하다. 윈도우에서는 잘 작동할뿐만 아니라 리눅스도 지원하며 에이전트를 통해 또는 에이전트리스 도구로 배포할 수 있다. 

지금까지 설명한 우수한 무료 오픈소스 침입 탐지 도구는 전체 목록은 아니지만 시작하기 좋은 선택지가 될 것이다. editor@itworld.co.kr  



원문보기: 
http://www.itworld.co.kr/news/111187#csidxe8c11a9e95cfdd2a13992c10cac01a6 

+ Recent posts