- 펌: https://cscscs.tistory.com/entry/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%B6%99%EB%8A%94-%EB%B2%95

 

알고리즘 트레이닝을 하는 방법

알고리즘 트레이닝시, 코딩테스트를 "붙어서 면접을 보는 수준"에 집중해서는 안됩니다.
코딩테스트 점수를 면접에 반영하지 않을까요? 지원자의 능력을 회사/팀에서 정한 문제를 통해 측정한 귀중한 정보입니다. 코딩테스트를 "붙는 수준"까지만 "합리적인 추론 능력"을 키우면.. 다른 outstanding한 스팩이 없는 경우 서류 및 면접에서 채용될 확률이 낮습니다. (물론 코테만 높고, cs가 부족해도 동일하게 채용될 확률이 낮습니다.)

알고리즘 트레이닝의 관점에서 4개 범주로 나눌 수 있습니다.

  1. 문법을 모르는 단계
    예를 들어 2중 반복문을 자유롭게 사용하지 못하는 단계가 해당 단계에 속합니다.
  2. 동작 원리를 정확히 모르는 단계
    call stack에 대한 이해도가 부족하고, 적절한 상황에 재귀를 사용할 수 없는 단계가 해당 단계에 속합니다.
  3. 추론 능력이 부족한 단계
    문법은 알지만 문제를 보았을 때 못 본 유형에 대해 부분 문제도 손도 못대는 경우가 해당 단계에 속합니다.
  4. 경험이 더 필요한 단계
    추론해서 문제를 풀 수 있지만, 종종 풀 수 없는 유형의 문제가 있는 경우가 속합니다.

각각에 대해 공부방법을 제시해드리겠습니다.

 


 

1. 문법을 모르는 단계 / 2. 동작 원리를 정확히 모르는 단계

우선 해당 언어의 문법을 완벽히 숙지하고, 본인이 사용하는 언어가 메모리를 어떻게 관리하는지 이해해야 합니다. os와 같은 지식은 필요 없지만, 포인터와 function call에 대한 완벽한 이해가 될 때 까지 우선 문법을 공부해야 합니다.

그 후 codeup.kr에서 관계기반 설계까지 모든 문제를 풀어주시면 됩니다.
(* 교육시에는 문제들을 제가 선별해서 진행했지만, 문제 선별은 해당 단계의 개인이 하기 어렵습니다.)

너무 쉬운 문제들은 건너뛰어도 되지만, 아래 문제집에 해당되는 문제들은 건너뛰지 말고 꼭 다 풀어주셔야 합니다.

  • 중첩 반복문
  • 2차원 배열
  • 재귀함수
  • 탐색 기반 설계
  • 관계 기반 설계

 


 

3. 추론 능력이 부족한 단계

많은 사람들이 위 단계 이후에 "잘못된 방향"으로 공부 방향을 설정합니다.

일반적으로 설정되는 잘못된 방향은 다음과 같습니다.

  1. DFS, BFS 문제들을 유형화
  2. 해당 유형의 문제들을 암기

해당 방법은 아래 소개드리는 방법보다 시간이 더 오래걸리고, 문제도 더 못풀고, 인생에 도움이 1도 안되는 행위 입니다. 코딩테스트가 욕을 먹는 이유중 하나입니다.

제가 제시하는 공부 방법은 본인에 수준에 맞는 알고리즘, 자료구조를 습득하고, 해당 자료구조 알고리즘을 사용하는 능력을 기르는데 초점을 맞춥니다.

방식은 USACO / COCI 문제를 푸는 것 입니다. 방법은 아래와 같습니다.

  1. USACO 브론즈, COCI 1번 문제를 선택한다.
  2. 해당 문제에 대회 공식 페이지에서 제공하는 답 (solution)이 있는지 확인한다.
    • 솔루션을 찾는 방법은 COCI의 경우 COCI 2019/2020와 같이 해당 연도를 구글에 검색하면 공식 페이지가 뜹니다.
    • USACO의 경우 USACO 2020 February Contest와 같이 현재 보고있는 contest의 연도 / 월을 포함해 구글 검색을 하면 공식 페이지가 뜹니다.
  3. 타이머를 재고, 문제당 풀이를 완벽히 정리하는데 30분의 시간을 할당한다.
    이때 풀이를 생각할때 시간복잡도를 생각하지 않고 무조건 답이 나오는 풀이(백트래킹) 풀이를 먼저 생각하고,
    문제 제한에 맞게 한 단계씩 최적화해나간다. 
    1. 정리가 성공한 경우 > 해당 시간 내 문제 풀이가 나온 경우 코딩을 시작한다.
      • 코딩을 한 후 틀린 경우 디버깅에 5분(타이머) 사용한다. 5분이 지난 경우 주저하지 않고 solution을 확인한다.
    2. 정리에 실패한 경우 > 솔루션을 보고 이해하고, 코딩을 시작한다.
      • 솔루션에 본인이 모르는 자료구조 / 알고리즘이 있는 경우 해당 자료구조 알고리즘을 찾아서 학습한다.
      • 본인이 생각했던 부분에서 어떻게 해당 풀이로 넘어가는지에 집중해서 솔루션을 읽는다
  4. 1번 반복 (너무 쉽다는 인상을 받으면 한단계 위 문제를 푼다)

초반에는 속도가 느려서 한 문제 한 문제가 굉장히 고되지만, 점점 가속도가 붙습니다. 믿고 진행해보세요.

연도가 넘어갈 수록 난이도가 올라가는 경향이 있기 때문에, 2010년도 정도의 대회를 선택하는 것을 추천드립니다.

USACO와 COCI를 선택한 이유는 solution에서 단순히 최적해만 알려주지 않습니다. 어떤 유도 과정을 통해 느린 솔루션에서 빠른 솔루션으로 최적화 과정을 설명합니다. 즉 이를 통해 어떤 과정으로 문제를 접근해야하고, 생각하는 힘이 길러집니다.

위 단계가 끝났으면 고등부 정보올림피아드 기준 운에 따라 동상은 받을 수도 있는 수준에 도달했습니다.
위 단계에서 USACO 실버, COCI 3~4번 문제를 동일하게 진행함을 병행합니다. 해당 수준까지 쉽게 풀리는 상황이 됐다면, 그 이후는 취업을 위해서 준비로써는 굳이 추천드리지 않습니다.

 


 

4. 경험이 더 필요한 단계

그래도 너무 알고리즘 문제풀이가 재밌고, 더 실력을 올리고 싶다면, 추천드리는 방법중 하나는 Codeforces를 사용하는 것 입니다. 방식은 아래와 같습니다.

  1. 300~400라운드의 div2 대회의 A, B, C 문제에 대해 USACO, COCI에서 진행했던 방식을 동일하게 진행
  2. 400~500라운드의 div2 virtual round를 돌고, editorial을 보고, upsolving을 진행합니다. 한 라운드당 3시간 내지 4시간의 시간이 소요됩니다.

위 과정 중간 중간 실제 대회도 진행해보고 본인 수준을 체크해보면 됩니다. 이 상태면 아마 웬만한 코딩테스트 대회 5시간 대회 문제를 2시간 안에 해결하게 됩니다.

그 이후 공부 방식은 Codeforces의 실제 대회도 참여중이라는 가정하에, [본인 레이팅, 본인 레이팅 + 200] 에 해당되는 문제를 필터링 해서 3에서 제시한 방법을 반복하면 꾸준히 성장하실 수 있습니다. 이후 근본적인 사고력이 부족하다는 느낌이 들 때, koosaga님의 OI Checklist를 활용해보시면 좋습니다. 보통 1900이후 구간에서 해당 작업을 병행하시면 좋습니다.

다만 4에서 제시하는 방식은 굉장히 효율이 안나오는 작업입니다. 취업이 안 된 상황에서 진행하는 것은 매우 비추천합니다.

출처: https://cscscs.tistory.com/entry/알고리즘-코딩-테스트-붙는-법 [CS BLOG:티스토리]

블로그 이미지

uchacha

개발자 일지

,

@펌글: https://shlee0882.tistory.com/206

 

1. Srping AOP 핵심기능과 부가기능

 

- 핵심 기능(Core Concerns): 업무 로직을 포함하는 기능

- 부가기능(Cross-cutting Concerns): 핵심 기능을 도와주는 부가적인 기능(로깅, 보안)

 

2. AOP란?

객체지향의 기본원칙을 적용하여도 핵심기능에서 부가기능을 분리해서 모듈화하는 것은 매우 어렵다.

AOP는 애플리케이션에서의 관심사의 분리(기능의 분리), 핵심적인 기능에서 부가적인 기능을 분리한다.

분리한 부가기능을 Aspect 라는 독특한 모듈형태로 만들어서 개발하는 방법이다.

 

- OOP를 적용하여도 핵심기능에서 부가기능을 쉽게 분리된 모듈로 작성하기 어려운 문제점을 AOP 가 해결해준다고 볼 수 있다.

- AOP는 부가기능을 Aspect 로 정의하며, 핵심기능에서 부가기능을 분리함으로써 핵심기능을 설계하고 구현할 때 객체지향적인 가치를 지킬 수 있도록 도와주는 개념이다.

 

3. Aspect 란?

- Aspect는 부가기능을 정의한 코드인 Advice 와 Advice 를 어디에 적용할지를 결정하는 PointCut 을 합친 개념이다.

Aspect = Advice + PointCut

- AOP 개념을 적용하면 핵심기능 코드 사이에 침투된 부가기능을 독립적인 Aspect 로 구분해 낼 수 있다.

- 구분된 부가기능 Aspect를 런타임 시에 필요한 위치에 동적으로 참여할 수 있다.

 

4. AOP 용어 정리

  • Target

- 핵심 기능을 담고 있는 모듈로 타겟은 부가기능을 부여할 대상이 된다.

  • Advice

- 타켓에 제공할 부가기능을 담고 있는 모듈이다.

  • Join Point

- 어드바이스가 적용 될 수 있는 위치를 말한다.

- 타겟 객체가 구현한 인터페이스의 모든 메서드는 조인 포인트가 된다.

  • Pointcut

- 어드바이스를 적용할 타겟의 메서드를 선별하는 정규표현식이다.

- 포인트컷 표현식은 execution 으로 시작하고 메서드의 Signature 를 비교하는 방법을 주로 이용한다.

  • Aspect

- AOP의 기본 모듈이다.

- Aspect = Advice + Pointcut

- 싱글톤 형태의 객체로 존재한다.

  • Advisor

- Advisor = Advice + Pointcut

- Spring AOP에서만 사용되는 특별한 용어이다.

  • Weaving

- Pointcut 에 의해서 결정된 타겟의 Joinpoint 에 부가기능(Advice)를 삽입하는 과정을 뜻한다.

- AOP가 핵심기능(타겟)의 코드에 영향을 주지 않으면서 필요한 부가기능(Advice)를 추가할 수 있도록 해주는 핵심적인 처리과정이다.

 

5. Spring AOP 특징

1. Spring은 프록시 기반 AOP를 지원한다.

- Spring 은 타겟 객체에 대한 프록시를 만들어서 제공한다.

- 타겟을 감싸는 프록시는 실행시간(Runtime)에 생성된다.

- 프록시는 어드바이스를 타겟 객체에 적용하면서 생성되는 객체이다.

 

2. Proxy 가 호출을 가로챈다(Intercept)

- 프록시는 타겟 객체에 대한 호출을 가로챈 다은 어드바이스의 부가기능 로직을 수행하고 난 후에 타겟의 핵심기능 로직을 호출한다.(전처리 어드바이스)

- 타겟의 핵심기능 로직 메서드를 호출한 후에 부가기능을 수행하는 경우도 있다.(후처리 어드바이스)

 

3. Spring AOP 는 메서드 조인 포인트만 지원한다.

- Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메서드 조인포인트만 지원한다.

- 핵심기능(Target)의 메서드가 호출되는 런타임 시점에만 부가기능(Advice)를 적용할 수 있다.

- 반면, AspectJ 같은 고급 AOP 프레임워크를 사용하면 객체의 생성, 필드값의 조회와 조작, static 메서드 호출 및 초기화 등의 다양한 작업에 부가기능을 적용할 수 있다.

 

6. Spring AOP의 구현 방식

1. XML 기반의 POJO 클래스를 이용한 AOP 구현

- 부가기능을 제공하는 Advice 클래스를 작성한다.

- XML 설정 파일에 <aop:config> 를 이용해서 Aspect 를 설정한다.

(즉, Advice 와 Pointcut 을 설정함)

 

2. @Aspect 어노테이션을 이용한 AOP 구현

- @Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스를 작성한다.

- 이 때, Aspect 클래스는 Advice 를 구현하는 메서드와 Pointcut 을 포함한다.

 

7. Advice 의 종류

  • Around 어드바이스

타겟의 메서드가 호출되기 이전(before) 시점과 이후(after) 시점에 모두 처리해야 할 필요가 있는 부가기능을 정의한다.

-> Joinpoint 앞과 뒤에 실행되는 Advice

 

  • Before 어드바이스

타겟의 메서드가 실행되기 이전(before) 시점에 처리해야 할 필요가 있는 부가기능을 정의한다.

-> Joinpoint 앞에 실행되는 Advice

 

  • After Returning 어드바이스

타겟의 메서드가 정상적으로 실행된 이후(after) 시점에 처리해야 할 필요가 있는 부가기능을 정의한다.

-> Joinpoint 메서드 호출이 정상적으로 종료된 뒤에 실행되는 Advice

 

  • After Throwing 어드바이스

타겟의 메서드가 예외를 발생된 이후(after) 시점에 처리해야 할 필요가 있는 부가기능을 정의한다.

-> 예외가 던져 질 때 실행되는 Advice

 

8. Advice 를 정의하는 태그

  • <aop:before>

- 메서드 실행전에 적용되는 어드바이스를 정의한다.

 

  • <aop:after-returning>

- 메서드가 정상적으로 실행 된 후에 적용되는 어드바이스를 정의한다.

 

  • <aop:after-throwing>

- 메서드가 예외를 발생시킬 때 적용되는 어드바이스를 정의한다.

- try-catch 블록에서 catch 블록과 비슷하다.

 

  • <aop:after>

- 메서드가 정상적으로 실행되는지 또는 예외를 발생시키는지 여부에 상관없이 어드바이스를 정의한다.

- try-catch-finally 에서 finally 블록과 비슷하다.

 

  • <aop:around>

- 메서드 호출 이전, 이후, 예외발생 등 모든 시점에 적용 가능한 어드바이스를 정의한다.

 

9. JoinPoint 인터페이스

- JoinPoint 는 Spring AOP 혹은 AspectJ에서 AOP가 적용되는 지점을 뜻한다.

- 해당 지점을 AspectJ에서 JoinPoint라는 인터페이스로 나타낸다.

 

* JoinPoint 메서드

getArgs() 메서드 아규먼트를 반환한다.
getThis() 프록시 객체를 반환한다.
getTarget() 대상 객체를 반환한다.
getSignature() Advice 또는 메서드의 설명(description)을 반환한다.
toString() Advice 되는 메서드의 설명을 출력한다.
블로그 이미지

uchacha

개발자 일지

,

- @참고: https://kcmschool.com/194

 

git ignore 파일 작성 예시

- .gitignore

## 파일 무시
test.txt

## 다음과 같은 확장자는 전체 무시
*.text
*.exe
*.zip

## 폴더 무시
test/

* 기존 git 의 관리를 받는 (commit 된) 파일, 폴더는 ignore 되지 않음

 

기존 git 관리를 받는 파일, 폴더에 대하여 ignore 하기

방법 1. 기존에 가지고 있는 cache 를 지우기

## 파일 이라면
git rm --cached test.txt

## 전체파일 이라면
git rm --cached *.txt

## 폴더 라면
git rm --cached test/ -r

* staging area 에서 파일을 제거하고 working directory 에서는 파일을 유지함.

* 위 명령어 실행 후 commit 이 필요함.

 

방법 2. cache 무시하기

# cache 무시하기
$ git update-index --assume-unchanged [파일명]

# cache 무시 취소하기
$ git update-index --no-assume-unchanged [파일명]

# 수정사항 무시 파일 조회
$ git ls-files -v|grep '^h'

 

블로그 이미지

uchacha

개발자 일지

,

- version

Spring Framework 4.3.20.RELEASE

hibernate-entitymanager-4.2.21.Final

 

- 동작 순서

org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean 에서 afterPropertiesSet() 후에 [spring-orm-4.3.20.RELEASE]

org.hibernate.ejb.EntityManagerFactoryImpl 에서 init() 하고 [hibernate-entitymanager-4.2.21.Final]

org.hibernate.cfg.Configuration 에서 buildSessionFactory() 해서 [hibernate-core-4.2.21.Final]

org.hibernate.internal.sessionFactoryImpl 에서 init() 시 [hibernate-core-4.2.21.Final]

ddl-auto 설정을 적용하게 된다.

해당 설정은

org.hibernate.tool.hbm2ddl.SchemaUpdate 에서 execute() 와 같이 설정 조건에 의하여 분기처리되서 수행된다. [hibernate-core-4.2.21.Final]

 

- 참고 자료

HHH000299: Could not complete schema update
org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'certpin'@'localhost' (using password: YES))
at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1225) ~[commons-dbcp-1.2.2.jar:1.2.2]
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880) ~[commons-dbcp-1.2.2.jar:1.2.2]
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:70) ~[hibernate-entitymanager-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.tool.hbm2ddl.SuppliedConnectionProviderConnectionHelper.prepare(SuppliedConnectionProviderConnectionHelper.java:51) ~[hibernate-core-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:219) ~[hibernate-core-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:203) ~[hibernate-core-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:509) ~[hibernate-core-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1799) ~[hibernate-core-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96) ~[hibernate-entitymanager-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915) [hibernate-entitymanager-4.2.21.Final.jar:4.2.21.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:900) [hibernate-entitymanager-4.2.21.Final.jar:4.2.21.Final]
at org.springframework.orhttp://m.jpa.vendor.SpringHibernateEjbPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateEjbPersistenceProvider.java:51) [spring-orm-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360) [spring-orm-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:384) [spring-orm-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371) [spring-orm-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336) [spring-orm-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1689) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1627) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1080) [spring-context-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) [spring-context-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) [spring-context-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) [spring-web-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) [spring-web-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) [spring-web-4.3.20.RELEASE.jar:4.3.20.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4763) [catalina.jar:8.5.81]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5232) [catalina.jar:8.5.81]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:8.5.81]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427) [catalina.jar:8.5.81]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417) [catalina.jar:8.5.81]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_301]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_301]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_301]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_301]

 

'DB' 카테고리의 다른 글

트랜잭션 격리 수준  (0) 2023.08.24
[Oracle Database 19c] restart  (0) 2023.05.25
[HikariCP] Configuration  (0) 2022.03.25
블로그 이미지

uchacha

개발자 일지

,

linux 계열에서는 table 의 case 를 구별해서 대문자로 작성된 query 의 table 명을 소문자 table 로 인식하지 못했다.

case sensitive 를 없애기 위해

/etc/my.cnf 에

[mysqld]
# Remove case sensitive in table names
lower_case_table_names=1

를 추가해주고 다시 시작하려하니 

systemctl restart mysqld

에러가 떨어져서 왜그런가 /var/log/mysqld.log 를 봤더니

data 폴더의 세팅 값이랑 불일치하게 되어서 그렇다고 한다. 즉 이미 생성된 data에 대하여 불일치로 인해 시작을 못하게 되는 것 같다. 

그래서 다음과 같은 방법으로 data 를 날리고 다시 시작해줬다.

- @참고: https://stackoverflow.com/questions/51803216/lower-case-table-names-settings-in-mysql-8-0-12

systemctl stop mysqld

sudo rm -rf /var/lib/mysql

sudo mkdir /var/lib/mysql

sudo chown mysql:mysql /var/lib/mysql

sudo chmod 751 /var/lib/mysql

systemctl start mysqld
블로그 이미지

uchacha

개발자 일지

,

- mysql 에서 처음 root 로 로그인하면 임시번호에서 비밀번호를 변경해줘야 사용할 수 있는데

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

대문자 및 소문자, 숫자, 특수문자에 길이도 제한이 있는 것 같다. 혹시 몰라 12자 해줬는데...

policy 에 대한 조건이 안나와있다보니 까다로웠다. 특히 테스트를 위한 비번을 사용하는데 기억하기 쉬운 걸로 하고 싶으므로 바꿔주기로 했다.

1. 일단 비밀번호를 바꾸고 로그인 해준다.

2. password 를 자유롭게 바꾸기 위해서 검증 파일 요소를 꺼준다.

mysql> UNINSTALL COMPONENT 'file://component_validate_password';

 

@참고(검증 구성 요소에 대한 문서): https://dev.mysql.com/doc/mysql-secure-deployment-guide/8.0/en/secure-deployment-password-validation.html

 

 

 

블로그 이미지

uchacha

개발자 일지

,

트랜잭션 격리 수준

DB 2023. 8. 24. 11:19

- @참고(oracle jdbc transaction): https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html

- @참고(트랜잭션 격리 수준): https://creampuffy.tistory.com/175

- @참고(트랜잭션 격리 수준과 lock): https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/

- @참고(mysql phantom row 처): https://dev.mysql.com/doc/refman/8.0/en/innodb-next-key-locking.html

 

- The interface Connection includes five values the represent the transaction isolation levels you can use in JDBC:

 

- READ UNCOMMITED

Dirty Read 가 발생한다.

    - Dirty Read: 트랜잭션이 2개 이상 열릴 때, 나중에 열린 트랜잭션에서 앞선 트랜잭션의 rollback 될 값일 수도 있는 commit 되지 않은 값을 읽을 수 있다. 

 

- READ COMMITED 

Non Repeatable Read 가 발생한다.

    - Non-Repeatable Read: 트랜잭션이 2개 이상 열릴 때, 나중에 열린 트랜잭션에서 commit 을 한 경우 먼저 열린 트랜잭션에서 같은 값을 반복해서 조회했을 때 값이 변한다.

오라클의 기본 트랜잭션 격리 수준이다.

 

- REPEATABLE READ

InnoDB 가 아닐 경우, Phantom Read 가 발생한다.

    - Non-Repeatable Read 가 발생하지 않는 이유: 각 트랜잭션언 트랜잭션 ID로 관리된다.

    선 트랜잭션 A가 트랜잭션을 열면, A commit 전에 후 트랜잭션 B가 열렸을 때 A의 새로운 값은 버퍼풀에, 기존 값은 언두 로그에 기록한다.

    A 가 commit 되면 버퍼풀의 새로운 값을 디스크에 기록되고,

    언두 로그의 기존 값은 열려있는 다른 트랜잭션인 B가 참조하며, B에서도 commit 이 일어날 시에 삭제 된다.

    - Phantom Read: Non-Repeatable Read 가 한 트랜잭션 내에서 하나의 레코드 값에 대하여 반복 조회시 다른 값을 조회할 수 있는 경우라면, Phantom Read는 한 트랜잭션 내에서 조회 시 결과 레코드 수가 달라질 수 있음을 말한다.

InnoDB의 기본 트랜잭션 격리 수준이다. InnoDB에서는 next-key 잠금 알고리즘을 이용해서 Phantom Read 를 방지한다.

 

- SERIALIZABLE

InnoDB의 경우 Gap lock 이 걸려서 조건에 해당하는 새로운 row 가 추가되는 것을 방지한다. 

SERIALIZABLE isolation level은 데이터를 안전하게 보호할 수 있지만 굉장히 쉽게 deadlock 에 걸릴 수 있다. 따라서 신중히 계산하고 사용해야한다.

 

 

블로그 이미지

uchacha

개발자 일지

,

[Oracle Database 19c] restart

DB 2023. 5. 25. 16:57

상황

oracle database 19c 를 centos 7에 설치 후 

- @설치 참고: https://oracle-base.com/articles/19c/oracle-db-19c-installation-on-oracle-linux-7

잘 사용하다가 docker 를 설치하기 위해 시스템을 재부팅했더니 oracle 이 꺼져있었다.

 

따라서 위 설치 참고 링크에서 

installation 이 완료 된 후 database 및 listener 를 실행하기 위한 start_all.sh 를 만들어서 실행 시켰다.

 

방법

모든 작업은 oracle 을 설치할때 생성한 oracle 계정으로 실행되었다.

1. /home/oracle/scripts 에 

설치했을 때의 ~/.bash_profile 을 참고하여 setEnv.sh 파일을 생성하고,

- setEnv.sh

더보기
cat > /home/oracle/scripts/setEnv.sh
# Oracle Settings
export TMP=/tmp
export TMPDIR=$TMP

export ORACLE_HOSTNAME=ol7-19.localdomain
export ORACLE_UNQNAME=cdb1
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/19.0.0/dbhome_1
export ORA_INVENTORY=/u01/app/oraInventory
export ORACLE_SID=cdb1
export PDB_NAME=pdb1
export DATA_DIR=/u02/oradata

export PATH=/usr/sbin:/usr/local/bin:$PATH
export PATH=$ORACLE_HOME/bin:$PATH

export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

 

2. start_all.sh, stop_all.sh 파일을 생성 한 후 실행권한을 주었다.

- start_all.sh

더보기
cat > /home/oracle/scripts/start_all.sh
#!/bin/bash
. /home/oracle/scripts/setEnv.sh

export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES

dbstart $ORACLE_HOME

 

 

- stop_all.sh

더보기
cat > /home/oracle/scripts/stop_all.sh
#!/bin/bash
. /home/oracle/scripts/setEnv.sh

export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES

dbshut $ORACLE_HOME

 

- 실행 권한 주기

chown -R oracle:oinstall /home/oracle/scripts
chmod u+x /home/oracle/scripts/*.sh

 

3. ORACLE_HOME 이 잘 세팅되어있는지 확인해보고, 값이 없으면 bash_profile을 다시 적용해주었다.

> echo $ORACLE_HOME
설정해 두었던 /u01/app/oracle/product/19.0.0/dbhome_1 이 나오지 않는 경우

> source ~/.bash_profile

 

4. /etc/oratab 파일을 listener 와 database 를 실행하도록 확인 후 수정해주었다.

SOLARIS 제외한 UNIX platform 에선 ORATAB=/etc/oratab 이며,

$ORACLE_SID:$ORACLE_HOME:<N|Y|W>
example> main:/usr/lib/oracle/emagent_10g:Y

W 는 dbstart 가 ASM 인스턴스가 돌아간 후에 database 가 자동 시작되게 하는 거라고 한다.

 

 

5. 확인작업으로 

ps -ef | grep pmon 을 통해 oracle database 가 돌 때 같이 도는 oracle process monitor 가 작동중인지 확인했으며,

lsntctl status 를 통해 리스터의 현 상태를 확인해 볼 수 있다.

sqlplus / as sysdba 로 접속해볼 수도 있다.

 

상황

oracle 은 동작하는데 DBeaver client 에서 접속이 안될때,

- @oracle 접속 안되는 이유: https://jhnyang.tistory.com/entry/DB-Sql-developer-%EC%97%90%EB%9F%AC-The-Network-Adapter-could-not-establish-the-connection-%EC%9B%90%EC%9D%B8%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0%EB%B2%95

SID, Service Name 설정 및 방화벽 설정을 차례로 체크해보다가 방화벽에 의한 것임을 알고 

방화벽에 1521 포트를 열어주었다.

> systemctl status firewalld
> firewall-cmd --permanent --zone=public --add-port=1521/tcp
> firewall-cmd --reload
> firewall-cmd --permanent --zone=public --list-ports
1521/tcp

 

블로그 이미지

uchacha

개발자 일지

,