[내일배움캠프] 12월 2주차 WIL 회고록
알고리즘
월요일 : OX 퀴즈
문제 설명 및 제한사항 , 입출력 예, 입출력 예 설명
풀이 :.split 을 이용해 문자열을 " " 로 잘랐다 .자르면 "X" , "+", "Y" , "=", "Z" 이런 식으로 잘라진다.
그 후에 변수 num1 , num2, num3 에 Integer.parseInt(String 타입의 숫자를 int 타입으로 변환해 주는 함수) 를 이용해
stringArr[0] , [2] , [4] 를 담았다.
stringArr[0] = X 이고, stringArr[2] = Y 이고, stringArr[4] = Z 이다.
stringArr[0] = X , stringArr[1] = + , stringArr[2] = Y, stringArr[3] 은 = , stringArr[4] = Z 이다.
그 후에 if문을 이용해 num1과 num2를 더한 값이나 뺀 값이 num3과 같다면 answer[i]에 "O" 나 "X"를 저장해서 리턴시켰다.
class Solution {
public String[] solution(String[] quiz) {
String[] answer = new String[quiz.length];
for (int i = 0; i < quiz.length; i++ ){
String[] stringArr = quiz[i].split(" ");
int num1 = Integer.parseInt(stringArr[0]);
int num2= Integer.parseInt(stringArr[2]);
int num3 = Integer.parseInt(stringArr[4]);
if (stringArr[1].equals("+")) {
if(num1 + num2 == num3) {
answer[i] = "O";
} else {answer[i] = "X"; }
}
if (stringArr[1].equals("-")){
if(num1 - num2 == num3) {
answer[i] = "O";
} else {
answer[i] = "X";
}
}
}
return answer;
}
}
수요일 : 평행
문제 설명, 제한사항, 입출력 예 , 입출력 예 설명
풀이: 먼저 기울기를 구해야 해서 int[] dot1, int[] dot2를 변수로 받는 double 형 findSlope를 선언했다.
double로 받는 이유는 원래 기울기를 구하려면 분수 형태로 구해야 하기 때문이다. 기울기를 구하는 공식: (y2 - y1) / (x2 - x1)
그래서 dot2의 첫번째 값과 dot1의 첫번째 값을 빼고 dot2의 0번째 값과 dot1의 0번째 값을 뺀 후 나눈 값을 (double)형으로 리턴시켰다
그 후 if문을 써서 findSolpe의 dots 0번째와 1번째 값이 findSlope의 2번째, 3번째 값과 동일하면 1을 리턴시켰다.
나머지도 마찬가지로 dots의 0번째 값, 두번째값과 첫번째 값, 세번째 값이 같으면 1을 리턴 시켰고
dots의 0번째 값, 세번째 값과 첫번째 값, 두번째 값이 같으면 1을 리턴시켰다. 그 후 answer를 리턴시켰다.
class Solution {
// 기울기 구하는 법 (y2 - y1) / (x2 - x1) 원래 분수 나누는거라서 double로 선언
public double findSlope(int[] dot1, int[] dot2) {
return (double) (dot2[1] - dot1[1]) / (dot2[0] - dot1[0]);
}
public int solution(int[][] dots) {
int answer = 0;
// (0,1) == (2,3)
if (findSlope(dots[0], dots[1]) == findSlope(dots[2], dots[3])) {
return 1;
}
// (0,2) == (1,3)
if (findSlope(dots[0], dots[2]) == findSlope(dots[1], dots[3])) {
return 1;
}
// (0,3) == (1,2)
if (findSlope(dots[0], dots[3]) == findSlope(dots[1],dots[2])) {
return 1;
}
return answer;
}
}
목요일 : 문자열 내 마음대로 정렬하기
문제 설명, 제한 조건, 입출력 예 , 입출력 예 설명
풀이 :
1. 반환할 배열 answer의 길이는 strings의 배열과 같으므로 strings.length로 지정한다.
2. n번째 문자를 기존 문자열에 붙여 넣을 새로운 문자열을 넣을 ArrayList를 생성한다.
3. String의 길이만큼 반복문을 사용해 새로운 문자열을 넣어준다. (arrayList.add(strings[i].charAt(n) + strings[i])
4. strings가 ["sun","bed","car] 이고 strings[i] 가 0이라고 치고, charAt(n)이 1이라고 치면 sun.charAt(1) = u 가 되고
string[i] 는 sun 이니까 u + sun = usun으로 변환 후 ArrayList에 add 된다.
5. Collections.sort 함수로 정렬한다.
6. arrayList.size()만큼 반복문을 사용한다.
7. answer[i] 번째에 arrayList.get(i)를 substring(1)을 사용한 후 값을 넣는다.
i를 0이라고 치면, arrayList.get(0)은 acar 이고, substring(1)로 1번째 문자열부터 출력한다.
0번째 문자열이 잘려서 나온다. ex ) acar = car , ebed = bed, usun = sun
8. answer를 return 시킨다.
class Solution {
public String[] solution(String[] strings, int n) {
// 반환할 배열 answer의 길이는 strings의 배열과 같으므로 strings.length로 지정한다.
String[] answer = new String[strings.length];
// n번째 문자를 기존 문자열에 붙여 넣을 새로운 문자열을 넣을 ArrayList를 생성한다,
ArrayList<String> arrayList = new ArrayList<>();
//String의 길이만큼 반복문을 사용해 새로운 문자열을 넣어준다. (arrayList.add(strings[i].charAt(n) + strings[i])
//strings가 ["sun","bed","car] 이고 strings[i] 가 0이라고 치고, charAt(n)이 1이라고 치면
// sun.charAt(1) = u 가 되고 string[i] 는 sun 이니까 u + sun = usun으로 변환 후 ArrayList에 add 된다.
for(int i = 0 ; i < strings.length; i ++) {
arrayList.add(strings[i].charAt(n) + strings[i]);
}
// Collections.sort 함수로 정렬한다.
Collections.sort(arrayList);
// arrayList.size()만큼 반복문을 사용한다.
// answer[i] 번째에 arrayList.get(i)를 substring(1)을 사용한 후 추가한다.
// i를 0이라고 치면, arrayList.get(0)은 acar 이고, substring(1)로 1번째 문자열부터 출력한다.
// 0번째 문자열이 잘려서 나온다. ex ) acar = car , ebed = bed, usun = sun
for (int i = 0 ; i < arrayList.size() ; i ++)
answer[i] = arrayList.get(i).substring(1);
return answer;
}
}
월요일에 공부한 내용
영속성 컨텍스트 : 영속성 컨텍스트란 엔티티를 영구 저장하는 환경이라는 뜻이다. 어플리케이션이 데이터베이스에서 꺼내온 데이터
객체를 보관하는 역할을 한다. 영속성 컨텍스트는 엔티티 매니저를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관하고 관리한다.
JPA 엔티티의 상태
- 비영속(New) : 영속성 컨텍스트와 관계가 없는 새로운 상태, 해당 객체의 데이터가 변경되어도 실제 DB 데이터에는 관계가 없다.
- 영속(Managed) : 엔티티 매니저를 통해 엔티티가 영속성 컨텍스트에 저장되어 관리되고 있는 상태이다. 이와 같은 경우 데이터의 생성, 변경등을 JPA 추적하면서 필요하면 DB에 반영한다.
- 준영속(Detached) : 영속성 컨텍스트에서 관리되다가 분리된 상태
- 삭제(Removed) : 영속성 컨텍스트에서 삭제된 상태
// 엔티티를 생성 (비영속 상태)
Member minsook = new Member();
member.setId("minsook");
member.serUsername("민숙");
// 엔티티 매니저를 통해 영속성 컨텍스트에 엔티티를 저장 ( 영속 상태 )
em.persist(minsook);
// 엔티티를 영속성 컨텍스트에서 분리 ( 준영속 상태 )
em.detach(minsook);
// 영속성 컨텍스트를 비우기
em.clear();
// 영속성 컨텍스트를 종료
em.close();
// 삭제
em.remove(minsook)
영속성 컨텍스트의 특징
- 1차 캐시라는 것을 가지고 있다.
- "쓰기 지연 SQL 저장소" 가 있다.
- DirtyChecking을 통해 데이터의 변경을 감지해서 자동으로 수정해준다.
- 데이터의 어플리케이션 단의 동일성을 보장해준다.
@Entity 관련
- 기본 생성자는 필수이다.
- final 클래스 , enum, interface 등에는 사용할 수 없다.
- 저장할 필드라면 final을 사용하면 안된다.
@Table 관련
- 엔티티와 매핑할 테이블의 이름이다. 생략하는 경우 매핑한 엔티티 이름을 테이블 이름으로 사용
@Column 관련
- 객체 필드를 테이블 컬럼에 매핑하는데 사용한다.
- 생략이 가능하다.
- 속성들은 자주 쓸 일이 없고, 특정 속성은 effect가 있으니 이름을 지정할 때 아니고는 보통 생략한다.
@Enumerated 관련
- Java Enum을 테이블에서 사용한다.
- 속성으로는 Ordinal, String 이 있는데, String 인 경우 해당 문자열 그대로 저장해서 비용은 많이 들지만, 나중에 Enum이 변경되어도 위험할 일이 없기 때문에 일반적으로는 String 을 사용한다.
프록시 : Proxy란 사전적으로는 대리인이라는 뜻을 가지고 있다. Java에서 프록시는 RealSubject는 자신의 기능에만 집중을 하고 그 이외 부가 기능을 제공하거나 접근을 제어하는 역할을 Proxy 객체에게 위임한다.
즉시 로딩 : 엔티티를 조회할 때 연관된 엔티티도 함께 조회한다. (연관된 엔티티를 조인해서 다 긁어온다.)
// 즉시 로딩 어노테이션
@ManyToOne(fetch = FetchType.EAGER)
지연 로딩 : 연관된 엔티티를 실제 사용할 때 조회한다. ( 실제로 가짜 객체를 이용하면, 그때 별도의 쿼리가 나간다.)
// 지연 로딩 어노테이션
@ManyToOne(fetch = FetchType.LAZY)
즉시로딩은 처음부터 모든 테이블의 조인을 걸어버리고 별도로 쿼리가 나가는 경우가 생기기에, 연관관계가 많고 복잡할수록 비용이
기하급수적으로 늘어나기에, 정확하게 이해하고 필요한 상황이 아니라면, 가급적 모두 지연로딩을 걸어두는게 일반적이다.
(쓸지 안쓸지 모르는데 비용은 가장 많이 드는 작업일 수도 있기 때문에)
영속성 전이 : 특정 엔티티를 역송 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을때 사용되는 기능 , JPA는 cascade 옵션으로 영속성 전이를 제공한다. 예를 들면 유저 테이블과 메모 테이블이 있는데 영속화한 유저객체가 있으면 메모 테이블도 같이 관리되는 것을 영속성 전이라고 한다.
// 예시
@OneToMany(mappedBy = "person" , cascade = CascadeType.ALL)
private List<Address> address;
화요일에 공부한 내용
인증과 인가
인증: 인증(Authentication)은 해당 유저가 실제 유저인지 인증하는 개념이다. 스마트폰에 지문인식, 이용하는 사이트에 로그인 등과 같이, 실제 그 유저가 맞는지를 확인하는 절차이다.
인가: 인가(Authorization)는 해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념이다. 예를 들어 관리자 페이지- 관리자 권한 같은 것이다.
인증의 방식
웹 어플리케이션의 인증
- 일반적으로 서버 - 클라이언트 구조로 되어있고, 실제로 이 두가지 요소는 아주 멀리 떨어져있다.
- 그리고 HTTP 라는 프로토콜을 이용하여 통신하는데, 그 통신은 비연결성(Connectionless) 무상태(Stateless)로 이루어진다.
비연결성(Connectionless)
- HTTP는 기본이 연결을 유지하지 않는 모델
- 일반적으로 초 단위의 이하의 빠른 속도로 응답
- 1시간동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작음
>> 예) 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않는다.
- 서버 자원을 매우 효율적으로 사용할 수 있음.
무상태(Stateless)
- 서버가 클라이언트의 상태를 저장하지 않는 것
쿠키 - 세션 내용과 JWT 기반 인증은 유튜브를 보면서 공부했다.
쿠키 - 세션 방식
출처: https://www.youtube.com/watch?v=OpoVuwxGRDI
JWT 기반 인증
JWT : JWT (Json Web Token) 이란 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token 이다.
관련 영상
https://www.youtube.com/watch?v=1QiOXWEbqYQ
수요일에 공부한 내용
8시 튜터님 강의 ( 좋은 개발자로 되기 위한 법 )
- (실력은 기본이지만) 실력이 모든 것을 대변해주지 않는다는 것을 알기
- (실력이 약하다면) 추가로 어필할 수단이 있는지 스스로 알아보기
- "No man Left Behind"
- 궁금한 부분은 정확하게 정리해본 이후 말해보기
- 상대방의 시간은 내 시간만큼 귀하다.
- 무작정 에러메세지 복붙보다는 메세지를 읽고 고민 (고민의 흔적을 글로 남겨볼 것)
- 알고 있습니다 보다는 "해보았습니다."
- 불편한 것들을 '컴퓨터가 해줄 수 있을까?" 고민 / 실행
- 분위기 메이커가 있으면 / 된다면 좋다. 실제로 팀 분위기가 좋은 팀이 결과물이 좋은 경우가 다수이다.
- 누구와도 잘 어울릴 수 있는 인상이면 좋다.
- 스몰토킹에서 시작 (날씨, 출퇴근길 점심식사) , 나와 상대방에 관심사를 엮어보기, 반문보다는 정확한 끝맺음
- 문제에 있어 '도전' 해내고 실제로 '구현' 해내며, '소통'도 잘하는 사람이 롱런하는 시대
- 신입에게 있어 '소통' 이 최우선, 소통만 잘해도 실력은 순차적으로 따라오게 되어있다.
- 당장 오늘부터 실행하면 대접받는 개발자로 성장한다.
내 생각을 온전히 담아야하며 ( 생각의 공감각화 )
내 화법에 상대방이 당황하지 않아야 하며
상대방 답변이 의도와 다르더라도 우선 수용하고 생각하자.
오고가는 대화속에서 결론은 나오게 되어있다.
목요일 , 금요일 - 개인 과제 만들기
과제를 하면서 더 공부를 해야겠다는 생각이 많이 들었다.
다음주에 리뷰를 보고 리뷰를 보고 배운 것을 바탕으로 이번 숙련 기능들을 전부 구현해 본 다음 다른 강의를 들어야겠다.
api 명세서 만들기가 생각보다 쉽지 않았다.. Gitbook으로 만들었는데 대충 다 만들고 Github으로 연동했더니
만들어 둔 내용이 다 날아가서 다시 만들고 깃헙으로 보냈더니 이상하게 나오고.. 사용법이 미숙해서 그대로 놔뒀다.
다음주도 열심히 공부해야겠다.