# 들어가며
2주차는 프로그래밍 기초를 다지기 위해 JAVA 언어의 기반을 다지고 코딩테스트를 진행하는 주차였다.
본인이 어떤식으로 풀어냈는지, 팀원들과 스터디를 진행하면서 효율적인 알고리즘을 생각하는 사고를 키워나가는데 도움이 되었다. 또한, 3주차 발제를 시작하며 JPA를 사용하여 웹을 만들어보고 직접 Spring을 사용해보며 주특기의 기초를 다졌다.
# 코딩테스트를 풀어보며 느꼈던점
사실 절반정도의 문제는 예전에 푼 문제들이였던지라 금방금방 풀거라 생각했는데 또 그건 아니였다. 예전엔 대부분 Python을 사용하여 풀었는데 Java로만 푸니 생각해야할게 한 두가지가 더 추가된 느낌이다. 가장 간단한예로 파이썬은 리스트를 사용하여 자유로운 추가,삽입,반환, 굳이 필요없는 자료형 선언, 간단한 함수 존재등으로 비교적 코드가 많이 축약되어 있는 형태라면 자바는 리스트를 배열로 바꿔주고 리턴하거나(나중에 알게된 점이지만 프로그래머스 코드 자체에서 함수 리턴타입에 리스트를 선언해도 정답으로 인정하긴한다.) 간단해 보이는 함수에도 다양한 라이브러리 존재한다는 점이 다른점이였다. 자바를 쓰며 문제를 풀때 배열을 선언하고 추가 삽입을 요구하는 문제가 많았는데 그때마다 ArrayList<>를 사용하였다. 문제에서 숫자에대해 다루는 내용이 많기에 ArrayList의 제네릭은 Integer를 대부분 사용하게 되었는데 ArrayList는 왜굳이 제네릭을 사용하는지, 또 Integer와 int는 다르기때문에 같이 쓸수가 없었기 때문에 연쇄적으로 궁금증이 많아지며 관련 레퍼런스를 찾아보느라 많은 시간을 할애하였다.
또 시간을 생각보다 많이 할애했던건 문자열을 숫자로, 숫자를 문자열, 문자열을 배열로 등등 다양한 타입 변환에 관한 레퍼런스를 각 문제마다 다르게 나왔기때문에 그냥 이건 기초적으로 알아야겠다 싶어서 간단한 함수들은 Notion에 정리해두었다.
👉 Coding Test 기본적인 함수
https://invincible-flag-377.notion.site/Coding-Test-14b7d140f8424492840a0b935d102db8
후반에가서 어려운 문제를 풀때 알고리즘적으로 풀어낼수 없다는 생각도 했던 문제가있었다. 그 중 어떤 문제는 다른 문제에 비해 난이도가 높은편이 아니였음에도 반복문안에 엄청난 조건문을 걸어 시간을 초과하여 풀어내지 못했다. 핵심은 문자열에서 조건이 충족될때,특정 문자를 다른 문자로 치환하는 것이였는데 이 과정에서 문자열을 리스트로 바꾼뒤, 조건이 충족될때 특정 문자를 인덱스 번호로 지운뒤 인덱스 번호를 찾아서 추가해줬더니 시간초과가 뜬것이다. 혼자 두시간동안 벙쪄서 다른방법이 있나 생각하다가 혹시나해서 검색했더니 바로 간단하게 처리해줄수 있는 replace()함수가 있었다. 많이 허무했으나 이제라도 내것으로 만들자라는 생각으로 이것도 노션에 정리해두었다..
# int vs Integer
그래서 int와 integer의 차이가 뭐냐? 라고 한다면 int는 자료형(primitive type)이며 Integer는 래퍼 클래스(Wrapper class)이다. 래퍼 클래스는 매개변수로 객체를 필요로 할 때, 기본형 값이 아닌 객체로 저장해야 할때에 사용한다.
따라서 알고리즘 문제들을 풀며 ArrayList<int>대신 ArrayList<Integer>를 계속 사용한 이유는 ArrayList 제네릭타입에 자료형이 올수없다는 사실을 알수있었다. 예를들면 ArrayList<long>은 오류가뜨지만 ArrayList<Long>은 오류가뜨지 않는것을 들수있다.
👉int와 Integer의 차이
int는 자료형이며 산술 연산이 가능하고, null로 초기화가 불가능하다.
Integer는 래퍼 클래스이며 Unboxing하지 않을 시 산술 연산이 불가능하고, null값 처리가 가능하다.
**
boxing : primitive type -> wrapper class (int to integer)
unboxing : wrapper class -> primitive type (integer to int)
# String vs StringBuffer vs StringBuilder
알고리즘 스터디를 진행하는 도중 아직도 기억나는것은 아주 간단한 문제도 효율적으로 짤수있구나 라는생각이다.
예를들어 자연수 n이 매개변수로 들어오면 n만큼 '수'와 '박'이 반복되는 문자열을 반환하는 문제였는데(예를들어 n이 4이면 "수박수박") 단순하게 반복문에 String 변수에 +=를 이용하여 문자를 붙였지만 팀원중 한명은 이를 StringBuffer와 StringBuilder를 사용하였다. 그게 무엇인고 살펴보니 String은 불변성을 가지므로 계속 새로운 문자가 붙을때마다 참조변수가 새로운 메모리영역을 가르키게 변경되고 처음 값이 할당되어 있던 메모리 영역은 Garbege collection에 의해 사라지게 된다. 그러나 StringBuilder와 StringBuffer 가변성을 가지므로, 동일 객체내에서 문자열을 변경하는 것이 가능하다. 따라서 자연수 n이 커질수록 두가지가 더 효율적임을 알수있었다.
👉 String과 StringBuilder,StringBuffer의 차이
String : 불변
StringBuilder,StringBuffer : 가변
👉 StringBuilder와 StringBuffer의 차이
StringBuilder : 동기화 지원X(단일쓰레드 성능)
StringBuffer : 동기화 지원(멀티쓰레드 성능)
StringBuffer는 동기화를 지원하여 멀티쓰레드 환경에서 안전하며 StringBuilder는 동기화를 지원하지 않기때문에 단일쓰레드의 성능이 뛰어나다.
# 시간 복잡도의 중요성 -> 최대값을 구하는 두가지 예제
똑같은 예제가 파이썬의 for-else문으로 되어있길래 JAVA로 바꿔서 예제를 만들어봤다.
public class MaxNumTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {10,5,25,2,31,2};
int a =max_Num(array);
System.out.print(a);
}
public static int max_Num(int[] array) {
int max=0; // 대입 연산+1
for(int i : array) { // array의 길이만큼 아래 연산 실행
int a=0; // 대입 연산 + 1
for(int j : array) { // array의 길이만큼 아래 연산 실행(항상 오래 걸리는 경우를 생각)
if(i<j) { break; } // 비교 연산 + 1
else { a+=1; } // 대입 연산 + 1
}
if(a==6) { max=i;} // 비교 연산+1 , 대입 연산 + 1
}
return max;
}
}
위의 연산은 (대입 연산 1) + array의 길이x(대입 연산1+ 비교 연산1+ 대입 연산1) X array의 길이 X (비교 연산 1번 + 대입 연산 1번) 만큼의 시간이 필요하다.
따라서 위의 시간은 1 + (1+1+1) X N X 2 X N 즉, 1 + 6N제곱의 시간이 필요하다.
public class HiClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {10,5,25,2,3,2};
int a =max_Num(array);
System.out.print(a);
}
public static int max_Num(int[] array) {
int max=array[0]; // 대입 연산 +1
for(int i : array) { // array의 길이만큼 아래 실행
if(i>max) { // 비교 연산 + 1
max=i; // 대입 연산 + 1
}
else {
continue;
}
}
return max;
}
}
위의 연산은 (대입 연산 1) + array의 길이 X (비교 연산 1번 + 대입 연산 1번) 만큼의 시간이 필요하다.
따라서 위의 시간은 1 + 2N의 시간이 필요하다.
이렇게 나중에 데이터가 많아질수록 위의 경우는 계산이 제곱씩 늘어나므로 알고리즘을 어떻게 짜느냐에 따라 시간을 줄일수있다.
# 마무리
3주차 발제로 Spring 시작하여 현재까지 JPA를 이용하여 간단한 CRUD를 구현하였는데 이것은 다음주 회고록에 제대로 다룰 예정이다. 금요일부터 지금까진 Controller, Service, Repository 계층으로 나누어 간단한 CRUD를 구현하였기에 다음주에 강의를 참고하여 개인 프로젝트를 개인적으로 만든다면 궁금증을 풀어낼 생각이다. 따라서 마무리는 부트캠프에서 제공하는 키워드 문제를 설명하고 마무리하고자 한다.
Q.객체지향 프로그래밍은 무엇이고 JVM이 무엇인가?
# 객체지향 프로그래밍
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
대충 인터페이스와 추상 클래스등을 이용하여 다형성을 극대화하고 클래스를 설계할때 공통의속성이나 기능을 묶어 이름을 붙이는것이라 생각하면 된다.
👉 다형성 : 하나의 변수명,함수명 등이 상황에 따른 다른 의미로 해석될 수 있는것(오버라이딩, 오버로딩)
# JVM
JVM은 Java Virtual Machine의 줄임말이며 자바를 실행하기 위한 가상 기계이다.
Java는 OS에 종속적이지 않기때문에, OS위에서 Java를 실행시킬 무언가가 필요한데 그것이 JVM이다.
즉, OS에 종속받지 않고 CPU가 java를 인식,실행할 수 있게 하는 가상컴퓨터이다.
Java의 소스코드 즉, 원시코드는(*.java) CPU가 인식을 하지 못하므로 기계어로 컴파일 해줘야한다. 그러나
Java는 JVM 가상머신을 거쳐서 OS에 도달하기 때문에 JVM이 인식할수 있는 Java bytecode(*.class)로 변환된다.
(여기서 변환해주는 역할은 Java complier가 담당하며 Java complier는 JDK를 설치하면 bin에 존재하는 javac.exe를 말한다.)
이제 변환된 bytecode는 기계어가 아니기 때문에 OS에서 바로 실행되지 않고, JVM이 OS가 bytecode를 이해할수 있도록 해석해준다. 따라서 Byte Code는 JVM위에서 OS상관없이 실행할 수 있다.
'항해 부트캠프 > 항해99' 카테고리의 다른 글
항해99 ) 4주차 회고록 (0) | 2022.07.17 |
---|---|
항해99 ) 3주차 회고록 (0) | 2022.07.09 |
항해99 ) 첫 1주차(팀 단위 미니프로젝트) 프로젝트 (0) | 2022.06.22 |