[네이버 클라우드 캠프-DevOps] 21일차

정지안·2023년 7월 5일
0
post-thumbnail

21일차(7/5수)

JS

DOM에서 이벤트 처리하기

DOM요소에 함수 직접 연결하기

  • 클릭시 이미지전환
  • addEventListener, mouseover, mouseout 예시 (마우스를 대면 일어나는 변화)


  • for문으로 addEventListener추가하기


JSP

getter와 setter

usebean 활용

  • MemberBean.java
package member.dto;

public class MemberBean {
	private String id;
	private String name;
	
	public String getId() {
		return id;
	}
	public String getName() {
		return name;
	}
	
	public void setId(String id) {
		this.id=id;
	}
	public void setName(String name) {
		this.name=name;
	}
	
}
  • MemberReg.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title style="text-align:center;">회원정보1</title>
<style>
#container{
width: 400px;
height: 200px;
margin: 0 auto;
padding: 10px;
border: 1px solid #222;
}
.inputTag{
width: 360px;
height: 40px;
margin: 0 auto;
padding: 5px;
vertical-align:middle;
text-align:center;
}
</style>
</head>
<body>

<form action="MemberGet.jsp" method="post">
<div id="container">
	<h3 style="text-align:center; margin-bottom:25px;">회원정보 입력</h3>
		<div class="inputTag">아이디: &nbsp;&nbsp;
			<input name="id" value="" size="10" required="required">
		</div>
		<div class="inputTag">이름: &nbsp;&nbsp;
			<input name="name" value="" size="10" required="required">
		</div>
		<div class="inputTag">
			<input type="submit" value="전송">
		</div>
</div>
</form>
</body>
</html>
  • MemberGet.jsp
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.DriverManager" %>
<%@page import="java.sql.Connection" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!-- 요청시 들어오는 글자를 utf-8로 변경해라 -->
<% request.setCharacterEncoding("UTF-8");
%>
<jsp:useBean id="member" class="member.dto.MemberBean" scope="page"/>
<jsp:setProperty property="*" name="member"/>

<jsp:getProperty name="member" property="id"/><jsp:getProperty name="member" property="name"/>을
저장 합니다.
<%
//웹 라이브러리 저장. mysql은 connector/j, oracle은 jdbc
//드라이버를 클래스로 받아라.
Class.forName("com.mysql.jdbc.Driver");
//Class.forName("com.mysql.jdbc.Driver");
//데이터베이스와 길을 뚫어라 Connection 연결 객체 생성
//DriverManager 단 하나의 connection을 객체로 갖고 오게 해준다.(singleton)
Connection conn=
DriverManager.getConnection("jdbc:mysql://localhost:3306/boarddb","root","1234");
PreparedStatement pstmt = null;
if(conn!=null){
	//성공하면 데이터베이스에 저장
	String id = member.getId();
	String name = member.getName();
	//?를 사용하면 외부에서 잘못된 정보로 공격하는 것을 막을 수 있음.
	String sql = "insert into member(id,name) values (?,?)";
	/*쿼리문을 가지고 다니는 객체*/
	pstmt = conn.prepareStatement(sql);
	//? 완성
	pstmt.setString(1, id);
	pstmt.setString(2, name);
	//실행하라.
	int c = pstmt.executeUpdate(); // insert, update, delete 실행하는 메서드.
	if (c>0) out.println("저장성공");
}else{
	out.println("연결실패");
}
if(pstmt!=null)pstmt.close();
if(conn!=null) conn.close();
%>
  • CommonEncodingFilter
package common.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CommonEncodingFilter implements Filter {

    /**
     * 인코딩을 수행할 인코딩 캐릭터 셋 지정
     */
    private String encoding = null;

    /**
     * 필터 설정 관리자
     */
    protected FilterConfig filterConfig = null;

	
    /**
     * @return
     */
    public FilterConfig getFilterConfig() {
        return filterConfig;
    }

    /**
     * @param cfg
     */
    public void setFilterConfig(FilterConfig cfg) {
        filterConfig = cfg;
    }

	@Override
	public void destroy() {
		this.encoding = null;
	    this.filterConfig = null;

	}

	@Override
	public void doFilter(ServletRequest request, 
			   ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		  
		if (request.getCharacterEncoding() == null) {
	            if (encoding != null) {
	              request.setCharacterEncoding(encoding);
	            }
	        }

	        chain.doFilter(request, response);

	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	    this.filterConfig = filterConfig;
	    this.encoding = filterConfig.getInitParameter("encoding");

	}

}

Java

열거형(enum)

  • 관련된 상수들을 같이 묶어 놓은 것. Java는 타입에 안전한 열거형을 제공

타입 불일치를 잡아준다.

열거형의 정의와 사용

  • 열거형을 정의하는 방법

  • 열거형 타입의 변수를 선언하고 사용하는 방법

  • 열거형 상수의 비교에 ==와 compareTo() 사용가능

열거형의 조상 - java.lang.Enum

  • 모든 열거형은 Enum의 자손이며, 아래의 메서드를 상속받는다.

  • values(), valueOf는 컴파일러가 자동으로 추가

enum Direction{ EAST, SOUT, WEST, NORTH }

class Ex12_5{

public static void main(String[] args){

Direction d3 = Enum.valueOf(Direction.class, “EAST”);

}

예제

valueOf

  • 기본 데이터 타입을 해당하는 래퍼 클래스의 객체로 변환하는 메서드
  • 기본 데이터 타입과 그에 대응하는 래퍼 클래스는 아래와 같다.
    • booleanBoolean
    • byteByte
    • shortShort
    • intInteger
    • longLong
    • floatFloat
    • doubleDouble
    • charCharacter
  • 이는 래퍼 클래스의 정적 메서드로서, 해당 데이터 타입의 값을 인자로 받아 래퍼 클래스의 객체로 변환하여 반환
  • 기본 데이터 타입과 래퍼 클래스 간의 변환을 간편하게 수행할 수 있다.3

열거형에 멤버 추가하기

  • 불연속적인 열거형 상수의 경우, 원하는 값을 괄호()안에 적는다.

    • ex_) enum Direction { EAST(1), SOUT(5), WEST(-1), NORTH(10) }
    • 이렇게 괄호를 사용하려면, 인스턴스 변수와 생성자를 새로 추가해줘야한다.

       
  • 열거형의 생성자는 묵시적으로 PRIVATE이므로, 외부에서 객체 생성 불가

  • values()란?

    • 열거형(enum) 타입의 모든 상수를 배열로 반환하는 메서드
  • of()란?

    • of() 메서드는 매개변수로 전달된 값들을 컬렉션에 추가하여 초기화한 불변 컬렉션 객체를 생성
    • 반환되는 컬렉션은 일반적으로 수정할 수 없는(immutable) 컬렉션임.
    • 따라서 요소의 추가, 삭제, 변경 등의 작업은 허용되지 않음
  • 예제

애너테이션이란?

  • 주석처럼 프로그래밍 언어에 영향을 미치지 않으며, 유용한 정보를 제공

표준애너테이션

  • @Override
    • 오버라이딩을 올바르게 했는지 컴파일러가 체크
    • 오버라이딩 할 때 메서드 이름을 잘못 적는 실수를 하는 경우가 많다.
    • 오버라이딩 할 때는 메서드 선언부 앞에 @Override를 붙이자.
  • @Deprecated
    • 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙인다.
    • 필드나 메서드에 문제가 발생하던가, 더 좋은 필드나 메서드가 나왔을 때.
    • 자바는 호환이 중요하기때문에 함부로 지울 수 없는 경우가 있음.
  • @FunctionalInterface
    • 함수형 인터페이스에 붙이면, 컴파일러가 올바르게 작성했는지 체크
    • 함수형 인터페이스에는 하나의 추상 메서드만 가져야 한다는 제약이 있음.
  • @SuppressWarnings
    • 컴파일러의 경고 메시지가 나타나지 않게 억제한다.
    • 괄호()안에 억제하고자 하는 경고의 종류를 문자열로 지정

메타에너테이션

  • @Target
    • 애너테이션을 정의할 때, 적용 대상 지정에 사용
  • @Retention
    • 애너테이션이 유지(retention)되는 기간을 지정하는데 사용
    • 컴파일러에 의해 사용되는 애너테이션의 유지정책은 SOURCE이다.
    • 실행시 사용 가능한 애너테이션의 정책은 RUNTIME이다.
  • @Documented, @Inheited
    • javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙인다.
    • 애너테이션을 자손 클래스에 상속하고자 할 때, @Inherited를 붙인다.
  • @Repeatable
    • 반복해서 붙일 수 있는 애너테이션을 정의할 때 사용
    • @Repeatable이 붙은 애너테이션은 반복해서 붙일 수 있다.
    • @Repeatable인 @ToDo를 하나로 묶을 컨테이너 애너테이션도 정의해야함

애너테이션 타입 정의하기

  • 애너테이션을 직접 만들어 쓸 수 있다.
@interface 애너테이션이름 {
	타입 요소이름(); //애너테이션의 요소를 선언한다.
	...
}
  • 애너테이션의 메서드는 추상메서드이며, 애너테이션을 적용할 때 지정(순서X)

애너테이션의 요소

  • 적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null 제외)
  • 요소가 하나이고 이름이 value일 때는 요소의 이름 생략 가능
  • 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다.

모든 애너테이션의 조상

  • Annotation은 모든 애너테이션의 조상이지만 상속은 불가. ⇒그냥 문법상 Annotation이지 직접적으로 쓰진 않는다.
  • 사실 Annotation은 인터페이스이다.

마커 애너테이션 - Marker Annotation

  • 요소가 하나도 정의되지 않은 애너테이션

애너테이션 요소의 규칙

상수는 허용됨

  • 요소를 선언할 때, 요소타입은 아래만 허용됨.
    • 기본형
    • String
    • enum
    • 애너테이션
    • Class
  • 괄호()안에 매개변수를 선언할 수 없다.
  • 예외를 선언할 수 없다.
  • 요소를 타입 매개변수로 정의할 수 없다.

프로세스와 쓰레드(process & thread)

  • 프로세스 : 실행중인 프로그램, 자원(resources)과 쓰레드로 구성
  • 쓰레드 : 프로세스 내에서 실제 작업을 수행. 모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다.
💡 프로세스 : 쓰레드 = 공장 : 일꾼
  • 하나의 새로운 프로세스를 생성하는 것보다, 하나의 새로운 쓰레드를 생성하는게 비용이 적다!

  • 프로세스의 병렬처리

  • 프로세스의 병행처리

  • 멀티쓰레드의 장단점

대부분의 프로그램이 멀티쓰레드로 작성되어 있다. 그러나, 멀티쓰레드 프로그래밍이 장점만 있는 것이 아님.

  • 장점
    • 시스템 자원을 보다 효율적으로 사용
    • 사용자에 대한 응답성이 향상
    • 작업이 분리되어 코드가 간결해짐.
  • 단점
    • 동기화에 주의해야한다.
    • 교착상태가 발생하지 않도록 주의해야한다.
      • A와B가 각각 톱,망치를 들고있을 때
      • 서로 망치와 톱을 바꿔야할 상황이 왔을 때
      • A: 니가 톱을주면 내가 망치를 줄게.
      • B: 니가 망치를주면 내가 톱을줄게
      • 이런식으로 교착상태가일어남.
    • 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야한다.

쓰레드의 구현과 실행

  1. Thread클래스를 상속
    1. 자바는 단일상속이기때문에 다른 클래스를 상속받기 힘듦.
  2. Runnable인터페이스를 구현
    1. 인터페이스를 구현하면 다른 클래스를 상속받을 수 있음.
    2. 따라서 인터페이스를 구현하는방식이 쓰레드 구현,실행에 권장되는 편
  • 예제

쓰레드의 실행 - start()

  • 쓰레드를 생성한 후에 start()를 호출해야 쓰레드가 작업을 시작한다.
  • start()했다고 즉시 실행되는 것이 아님
    • 실행 가능한 상태가 되는 것임.
    • 실행순서는 OS스케줄러가 결정함.
  • t1, t2중 어느것이 먼저 실행되는지 모름.

run()을 작성했는데 왜 start()가 호출되지?

main에서 start()를 호출

start메서드는 새로운 호출스택 생성

호출스택에 run을 올린다.

그리고 start()는 종료된다.
각각의 쓰레드가 자기만의 호출스택을 가지고 실행한다. 따라서 서로 독립적인 작업을 할 수 있다.

main쓰레드

  • 메인메서드의 코드를 수행하는 쓰레드
  • 쓰레드의 종류
    • 사용자쓰레드
    • 데몬쓰레드: 사용자의 역할을 보조해주는 역할

실행중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료된다.

싱글쓰레드와 멀티쓰레드

  • 싱글쓰레드

    • 싱글쓰레드예시

  • 멀티쓰레드

context switching : A작업⇒B작업으로넘어가는 것

멀티스레딩이 시간이 더 오래걸린다.

하지만 시간이 더 걸리더라도 여러가지 기능을 같이 수행하는 것이 장점이다.

쓰레드의 I/O블락킹(blocking)

블락킹 : 입출력시 작업중단하는 것

이럴 때 멀티스레드를 돌린다면?

쓰레드의 우선순위(priority of thread)

  • .setPriority(n)

  • .getPriority()

  • 작업의 중요도에 따라 쓰레드의 우선순위를 다르게 하여 특정 쓰레드가 더 많은 작업시간을 갖게 할 수 있다.

  • 하지만 이는 희망사항.

  • OS의 스케줄러는 공평하게 돌아간다. 따라서 OS스케줄러가 참고만 하는 수준이다.

쓰레드 그룹

  • 서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위한 것

  • 모든 스레드는 반드시 하나의 쓰레드 그룹에 포함되어 있어야 한다.

  • 쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 main쓰레드 그룹에 속한다.

  • 자신을 생선한 쓰레드(부모 쓰레드)의 그룹과 우선순위를 상속받는다.

쓰레드 그룹의 메서드

데몬 쓰레드(daemon thread)

  • 일반 쓰레드(non-daemon thread)의 작업을 돕는 보조적인 역할을 수행
  • 일반 쓰레드가 모두 종료되면 자동적으로 종료된다.
  • 가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용된다.
  • 무한루프와 조건문을 이용해서 실행 후 대기하다가 특정 조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.

  • setDaemon(boolean on)은 반드시 start()를 호출하기 전에 실행되어야 한다. 그렇지 않으면 IllegalThreadStateException이 발생한다.

쓰레드의 상태

상태설명
NEW쓰레드가 생성되고 아직 start()가 호출되지 않은 상태
RUNNABLE실행 또는 실행 가능한 상태
BLOCKED동기화블럭에 의해 일시정지된 상태(lock이 풀릴때까지 기다리는 상태)
WAITING, TIMED_WAITING쓰레드의 작업이 종료되지는 않았지만 실행가능하지 않은(unrunnable) 일시정지상태. TIMED_WAITING은 일시정지시간이 지정된 경우를 의미
TERMINATED쓰레드의 작업이 종료된 상태

쓰레드의 실행 제어

  • 쓰레드의 실행을 제어할 수 있는 메서드가 제공된다.
  • 이들을 활용해서 보다 효율적 프로그램 작성이 가능하다.
메서드간단설명설명
static void sleep(long millis)일시정지지정된 시간(1/1000 초 단위)동안 쓰레드를 일시 정지시킨다. 지정한 시간이 지나고 나면 자동적으로 다시 실행대기 상태가 된다.
static void sleep(long millis, int nanos)
void join()다른 쓰레드 기다리기지정된 시간동안 쓰레드가 실행되도록 한다. 지정된 시간이 지나거나 작업이 종료되면 join()을 호출한 쓰레드로 다시 돌아와 실행을 계속한다.
void join(long millis)
void join(long millis, int nanos)
void interrupt()다른사람 꺠우기sleep()이나 join()에 의해 일시정지상태인 쓰레드를 깨워서 실행대기상태로 만든다. 해당 쓰레드에서는 interrupted Exception이 발생함으로써 일시정지 상태를 벗어나게 된다.
void stop()쓰레드 종료쓰레드 즉시 종료
void suspend()일시정지쓰레드 일시정지시킨다. resume()을 호출하면 다시 실행대기 상태가 된다.
void resume()일시정지 재개suspend()에 의해 일시정지상태에 있는 쓰레드를 실행대기상태로 만든다.
static void yield()양보실행 중 자신에게 주어진 실행시간을 다른 쓰레드에게 양보(yield)하고 자신은 실행대기상태가 된다.

Static은 쓰레드 자기 자신에게만 호출 가능

sleep()

  • 현재 쓰레드를 지정된 시간동안 멈추게한다.
    • static void sleep(long miilis) : 천분의 일초
    • static void sleep(long miilis, int nanos) : 천분의 일초+나노초
  • 예외처리를 해야한다.(InterruptedException이 발생하면 깨어남)
  • 예외 트라이캐치를 통해 잠자는상태를 벗어나려고 하는 것.
    • 따라서 캐치문에 아무것도 안넣어도 된다.
  • 특정 쓰레드를 지정해서 멈추게 하는 것은 불가능하다.

interrupt()

  • 대기상태(WAITING)인 쓰레드를 실행대기 상태(RUNNABLE)로 만든다.

suspend(), resume(), stop()

  • 쓰레드의 실행을 일시정지, 재개, 완전정지 시킨다.
  • void suspend() :쓰레드를 일시정지 시킨다.

  • void resume() : suspend()에 의해 일시정지된 쓰레드를 실행대기상태로 만든다.

  • void stop() : 쓰레드를 즉시 종료시킨다.

  • 교착상태(Dead-lock)을 일으킬 수 있기때문에 쓰지 않는것을 권장한다.

join()

  • 지정된 시간동안 특정 쓰레드가 작업하는 것을 기다린다.

  • void join() : 작업이 모두 끝날때까지

  • void join(long millis) : 천분의 일초동안

  • void join(long millis, int nanos) : 천분의 일초+나노초 동안

  • 예외 처리를 해야한다.(IntereptedException 이 발생하면 작업 재개)
  • join() 예제

yield()

  • 남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 쓰레드)은 실행 대기한다.

  • static이다.(자기자신에게 쓸 수 있는 것)

  • yield()와 interrupt()를 적절히 사용하면, 응답성과 효율을 높일 수 있다.

  • 사용여부에 따른 큰 차이가 없으나, yield를 쓰는게 아주조오오금 더 빠를때가 있다고 한다.

쓰레드의 동기화(synchronization)

  • 멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다.
  • 진행중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 ‘동기화’가 필요
    • 쓰레드의 동기화: 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하게 막는것.
  • 동기화 하려면 간섭받지 않아야 하는 문장들을 ‘임계영역’으로 설정
  • 임계영역은 락(lock)을 얻은 단 하나의 쓰레드만 출입 가능(객체 1개에 락 1개)

synchronized를 이용한 동기화

  • synchronized로 임계영역을 설정하는 방법 2가지
  1. 메서드 전체를 임계 영역으로 지정
  2. 특정한 영역을 임계 영역으로 지정

wait()과 notify()

  • 동기화를하면 프로그램 효율이 좋지 않아진다.
  • 동기화의 효율을 높이기 위해 wait(), notify()를 사용.
  • Object클래스에 정의되어 있으며, 동기화 블록 내에서만 사용할 수 있다.
  • wait() - 객체의 lock을 풀고 쓰레드를 해당 객체의 waiting pool에 넣는다.
  • notify()-waiting pool에서 대기중인 쓰레드 중의 하나를 깨운다.
  • notifyAll() - waiting pool에서 대기중인 모든 쓰레드를 깨운다.
    • 일반적으로 notifyAll이 notify보다 좋다.

람다식(Lambda Expression)

  • 함수(메서드)를 간단한 식으로 표현하는 방법
  • 익명함수(이름이 없는 함수, anonymous function)
  • 함수와 메서드의 차이
    • 근본적으로는 동일.
    • 함수는일반적 용어, 메서드는 객체지향개념 용어
    • 함수는 클래스에 독립적, 메서드는 클래스에 종속적.

람다식 작성하기

  • 메서드의 이름과 반환타입을 제거하고 ‘->’을 블록{} 앞에 추가한다.

  • 반환 값이 있는 경우, 식이나 값만 적고 return문 생략 가능(끝에 ‘;’안붙임.)

  • 매개변수의 타입이 추론 가능하면 생략 가능(대부분의 경우 생략 가능)

람다식 작성하기- 주의사항

  • 매개변수가 하나인 경우, 괄호() 생략 가능(타입이 없을 때만)

  • 블록 안의 문장이 하나뿐 일 때, 괄호{} 생략 가능(끝에 ‘;’ 안 붙임)

람다식은 익명함수가 아닌 익명 객체다.

=객체 선언과 생성을 동시에 하는 것

함수형 인터페이스

  • 단 하나의 추상 메서드만 선언된 인터페이스

람다식의 참조변수타입은 함수형인터페이스를 사용하면 된다.

함수형 인터페이스 타입의 매개변수 반환타입

  • 함수형 인터페이스 타입의 매개변수

java.util.function패키지

  • 자주 사용되는 다양한 함수형 인터페이스를 제공

  • java.lang.Runnable
  • Supplier
  • Consumer
  • Function<T,R>
  • Predicate

매개변수가 2개인 함수형 인터페이스

  • BiConsumer<T,U>
  • BiPredicate<T,U>
  • BiFunction<T,U,R>

매개변수의 타입과 반환타입이 일치하는 함수형 인터페이스

  • UnaryOperator
  • BinaryOperator

Predicate의 결합

  • and(), or(), negate()로 두 Predicate를 하나로 결합(default메서드)
    • and()
    • or()
    • negate()

  • 등가 비교를 위한 Predicate의 작성에는 isEqual()를 사용(static메서드)

컬렉션 프레임웍과 함수형 인터페이스

  • 함수형 인터페이스를 사용하는 컬렉션 프레임웍의 메서드(와일드카드 생략)

메서드 참조(method reference)

클래스이름::메서드이름

  • 하나의 메서드만 호출하는 람다식은 ‘메서드 참조’로 간단히 할 수 있다.

생성자의 메서드 참조

  • 생성자와 메서드 참조
profile
1% 개발자를 향해:: 개발 공부 일지를 써나갑니다

0개의 댓글