
0. 들어가기 전에
이번 시간에는 알고리즘을 배운다. 알고리즘을 두 파트로 나눠서 할 예정인데, 하나는 어떤 "알고리즘"이 좋은 알고리즘이냐에 대해서이고, 다음에는 "알고리즘"의 방법에 대한 파트가 될 거 같다. 수업에서 배우는 것은 메서드와 로직과 관련된 부분인데, 그 기점이 되는 "어떤 로직을 쓸 것인가?" "어떤 메서드를 쓸 것인가?"에 대한 기준점에 대해서 먼저 배우고자 한다. 지난 번에도 말했듯이, TIL은 수업 내용을 토대로 한 추가 공부에 가깝다. 내가 무엇을 배웠느냐도 중요하지만, 그저 강의를 복습하는 건 이미 강의일지에서 충분히 하고 있다. 내가 무엇을 배우고 있는지 알아야 단순한 코드의 암기가 아니라 스스로 설계할 수 있게 되기 때문이다.
이번 TIL은
오랜만에 "초심"으로 돌아가고 싶다. 내 TIL을 본 사람들이 하나같이 말하는 장점이 바로 이해하기 쉽다는 것이었는데, 최근에는 바쁘다고 나의 내적 이해에 대한 이야기보다는 그저 코딩블로그 같이 쓰는 것에 치중되어 있었던 거 같다. 나름대로 이해의 언어를 쓰려고는 했지만 강의 외에도 추가 공부를 한다는 느낌으로 접근하다보니 많이 힘들었던 거 같다.
이번 포스팅은 그러므로 첫 TIL을 떠올리면서 글을 쓴다. 이번 포스팅에서는 일단 "알고리즘의 중요성"부터 시작해서, 좋은 알고리즘에 대해서, 그리고 그 좋은 알고리즘을 판별하는 기준의 개념에 대해 다룬다.
1. "AI 시대", 알고리즘은 왜 중요할까?
학원이나 취업 공고를 보면 AI를 사용하는 개발자에 대해 긍정적인 것 같다. 실제로 AI 시대에서 가장 AI에 대해서 거부감이 없는 건 개발 직종 같기도 하다. AI가 하나의 프로그램이기 때문이기도 하고, 많은 개발자들이 코드의 독창성에 대해서는 인정하지만 대체로 효율적인 코드를 찾고 싶어하기 때문인 듯도 하다.
그러나 AI를 실제로 개발 목적으로 사용해보면, AI는 완성된 코드를 생성해서 전부 내어준다. 특히 에이전트라 불리는 AI들은 스스로 설계까지 하여 모든 걸 완벽하게 내놓는 것처럼 보인다. 적게는 수십, 많게는 수만에 가까운 코드 뭉치들을 보고 있으면 과연 이게 돌아가는지 검증할 수 없는 채로, 그저 "AI가 썼으니 맞겠지"하고 신뢰하며 사용하게 된다.
내 이야기를 조금 해보자면, 나는 파이썬으로 내가 원하는 프로그램을 만든 적이 있다. 이른바 바이브 코딩이라는 것으로, 결과물을 만드는 것에는 막상 얼마 걸리지 않았다. 대부분이 내 Agent AI가 만들어주기 때문이다. 그리고 그 후부터는, 절대 어떠한 일이 있어도 AI의 툴적 도움을 받거나 디버깅을 시키기는 하지만 설계부터 완성까지 AI가 전부 하는 바이브 코딩을 하지 않는다.
왜일까? 하고 생각할 것이다. 결국 프로그램을 완성했으니까! 그러나 프로그램을 수정하고 만드는 과정에서 내가 원하는 기획을 AI는 제대로 구현해내지 못했다. 나는 어느 정도 파이썬을 할 수 있기 때문에 고치는 것은 가능했지만, Agent AI가 만들어준 "간결하지만" "어려운" 코드들 때문에 고치는 것에도 한계가 있었다. 내가 할 수 있는 건 그저 AI가 내 의도대로, 내 적확한 지시대로 만들기를 바라는 것밖에 없었다.

수 십에서 수 만개의 코드에서 내가 "무엇"을 고쳐야하는지 아는 것은 어렵다. 무엇이 어떻게 돌아가나? 어떤 형태로 이 코드가 완성된 것인가? 그러한 설계도를 바로 알 수 있기 위해서는 바로 알고리즘을 이해해야 한다. AI가 어떠한 알고리즘으로 돌아가는가부터 시작해서, 이 코드가 대체 어떠한 목적으로 만들어졌는가를 파악하기 위해서는 알고리즘을 빼놓고 이야기할 수 없다.
2. 알고리즘Alogirthm이란?
강의에서는 알고리즘을 문제를 해결하는 가장 똑똑한 방법이라고 정의했다. 즉, 최선의 효율을 따지는 것이 곧 알고리즘이라는 것인데, 대부분의 AI도 최선의 효율을 따져 코드를 작성한다. 비록 이것이 인간의 눈에는 매우 복잡하고 알아보기 어려울지라도 AI는 그 코드가 돌아가는 것에 중점을 둔다. 물론, 인간이 알아보기 쉽도록 맥락을 유지하여 코드를 만들어주는 경우도 있다.
알고리즘은 구체적으로 말하면 한 문제가 있다면 그 문제에 대한 풀이법이라고 할 수 있다. 코딩테스트Coding Test가 어떠한 문제를 내놓아서 그에 대한 해답을 보는 이유도, 이 알고리즘을 확인하기 위해서다. 알고리즘에는 답이 없다. 정확히 말하면 도출해야 하는 답은 있지만, 모로가도 서울로 가면 된다고 답만 내놓으면 되기도 한다. 이 때문에 개발자들마다 코드를 짜는 것에 개성이 발생하기도 한다.

이렇게 풀이가 나온 알고리즘은 대체로 실행된다. 당연하다, 코드는 실행하라고 있는 것이다. 어떤 언어를 쓰냐에 따라서 실행 과정은 다 달라지는데, 우리가 사용하는 java는 스스로의 동작구조에 따라서 진행된다. 이에 대한 자세한 설명은 지난 TIL에서 쓴 적이 있다.
[Java 풀스택 개발자] Java의 용어와 개념: 낯선 Java를 친숙하게 만들어 보자!
[Java 풀스택 개발자] Java의 용어와 개념: 낯선 Java를 친숙하게 만들어보자!
0. 들어가기에 앞서본래는 특별편인 React 실전으로 먼저 만나려고 했다. 그러나 생각보다 만들려던 것의 규모가 커지면서 다음 기회에 포스팅하게 되었다. 따라서 이번 주는 한국의 백엔드 중심
bbbbabbbababababa.tistory.com
이러한 과정을 거쳐 실행이 되면… 오류 없이 돌아가면 다 했다! 하고 끝내면 될까? 그렇지 않다. 혹시 사이트를 들어가거나 실행할 때 인터넷 문제도 아니고 브라우저 문제도 아닌데 너무 느린 적이 있을 것이다. 그건 단순히 처리해야할 데이터가 많아서일까? 지금도 만 명을 훨씬 넘는 이용자가 있는 네이버나 구글의 로딩 속도는 1초도 채 되지 않는다. 단순히 서버의 문제일 수도 있지만 그 웹사이트 개발자가 '조금' 비효율적이라서 그렇게 된 것이라면?

그뿐이 아니다. 우리가 앱으로 은행에 인출한다고 치자. 그 은행 앱의 개발자가 '조금' 체크를 잘못해서, 우리가 우리 잔고 이상의 돈을 뽑을 수 있게 된다면? 그렇게 된다면 그 은행은 아주 난리가 날 것이다. 그렇다. 이게 바로 알고리즘, 코드의 효율과 최적화를 따지는 개념이다.
3. 어떤 게 좋은 알고리즘일까?
일단 코드의 실행에서 우선순위에 대한 그림을 한번 그려보았다.

첫 번째로 필요한 것은 바로 "오류가 나지 않을 것", 곧 정확성이다. 모든 코드는 실행이 되어야 그 의미가 있다고 할 수 있다. 실행이 되어야 좋고 나쁘고를 판단할 수 있다. 따라서 런타임 에러 등의 오류가 나는 코드는 아무리 잘 짜도 의미가 없다고 할 수 있다.
두 번째로는 "예외 처리가 잘 되어있을 것", 즉 엣지 케이스 처리이다. 상정 되지 않은 일이 발생했을 때, 이것을 어떻게 처리하느냐가 중요해진다. 상정되지 않은 일이 발생했을 때 예외처리를 하지 않을 경우, 오류가 나거나, 혹은 버그가 일어날 수 있다. 잘 돌아가는 것만큼이나, 아니 어쩌면 그 이상으로 중요한 기준은, 버그가 발생하지 않는 것이다.
세 번째로는 "기획에 맞게 구동될 것"이다. 이건 위에서 말한 예외 처리와도 관계 있지만, 단순히 오류나 예외의 문제가 아니라 기획한 그대로 이루어지느냐가 된다. 실행은 되는데 기획과 다른 결과를 내고 있다면, 그건 마찬가지로 버그이다. 로봇에게 왼쪽으로 움직이라고 했는데 오른쪽으로 움직인다면, 움직이므로 오류는 아니지만 버그라고 할 수 있다.

네 번째로는 "빠르게 구동될 것", 즉 시간 복잡도이고, "메모리를 얼마나 적게쓰냐", 즉 공간 복잡도이다. 빨리 구동될 수록 좋은 건 당연하다. 이용자 입장에서 오랜 로딩이나 렉을 견디고 싶지 않기 때문이다. 메모리의 경우도 마찬가지다. 메모리가 적으면 처리 양이 적으니 속도도 빠르다. 즉, 이것은 사용자의 편의를 위한 기준에 가깝다.
마지막으로는 "남들도 알아보기 쉬운 코드를 짤 것", 즉 가독성이다. 사실 혼자서만 개발한다면 이 가독성은 어떻게 되든 상관이 없다. 그러나 많은 프로젝트를 하고 싶다면 개발자는 혼자가 될 수가 없다. 자신의 개성 또한 중요하지만, 남이 알아보고 그것을 수정하는 것도 중요하다.
이것이 곧 좋은 알고리즘의 기준에 들어간다고 할 수 있다. 당연히 준수해야할 1번부터 3번까지를 제외한다면(그렇지 않으면 제대로 동작조차 하지 않는 것이기에 출발선에도 서지 않는 것이나 다름없다.), 남는 것은 4번과 5번의 기준이다. 즉, 빠르게 구동되면서 메모리를 적게 사용하고, 남들도 알아보기 쉬운 코드가 되는 게 좋은 알고리즘의 조건이다.
4. 알고리즘의 기준 개념
위에서 기준에 대해서 이야기했으니, 관련 개념들에 대해서 얘기해볼까 한다. 여기서는 1. 정확성 2. 완전성 3. 시간 복잡도 4. 공간 복잡도, 5. 안정성, 6. 단순성 이렇게 나누어서 상세한 설명을 할 예정이다.
(1) 정확성
위에서 말한 정확성보다 조금 더 넓게, 2번 예외(엣지 케이스)처리까지 합한 개념이다. 알고리즘에서 정확성은 “항상 맞는 답을 내느냐”로 판단한다. 입력이 정상적인 경우뿐만 아니라, 빈 배열·0이나 음수 같은 값·최대/최소 값 등 경계 조건까지 모두 포함해서, 어떤 입력이 들어오든 문제에서 요구한 정답을 정확하게 내놓아야 한다.
코딩 테스트에서 우리가 통과 여부를 확인하는 테스트 케이스들도 결국 이 정확성을 검증하기 위한 장치다. 눈으로 봤을 때는 맞는 것 같아도, 특정 케이스에서만 다른 결과를 내놓는다면 그 알고리즘은 아직 "정확하지 않은" 상태라고 볼 수 있다. 이 때문에 코딩 테스트에서는 최소 20개 이상의 케이스를 넣는 경우가 많다.
2) 완전성
완전성은 간단히 말해 이 코드, 종료 되나?를 묻는다. 한 마디로, 무한적으로 루프하지 않고 프로그램이 무사 종료될 수 있느냐를 묻는다. 무한적으로 루프하는 경우가 종종 있는데, 예를 들어 자기 자신을 계속 호출하는 재귀를 하다보면 루프가 되게 된다. 이렇게 반복되다보면 결국 StackOverflowError가 나서 프로그램은 강제 종료가 된다. 이것도 사실 메모리에서 자체 종료를 시켜주는 것이지, 아니었다면 프로그램을 종료하지도 못한 채 있거나 강제로 셧다운 해야할 것이다.

3) 시간 복잡도
1부터 N까지 더하기 문제를 수학시간에 배워본 적 있을 것이다. 특히 1부터 100까지 합을 구하라는 문제는 유명하다. 이걸 하나하나 세는 방법도 있겠지만, 가우스의 덧셈 공식을 사용하면 아주 간단해진다.

그렇다, 이게 바로 "시간 복잡도"의 대표적인 예제이다. 하나씩 세어나갈 것이냐, 간단히 다른 방법을 취할 것이냐. 아무리 컴퓨터라고 해도 하나씩 훑어보면서 더해나가는 것에는 시간이 걸린다. 그러나 간단한 식과 함께라면 이 속도가 확연히 빨라질 수 있다.
시간 복잡도에 대한 틀린 설명이나 오해가 있는데, 시간 복잡도라는 건 결국 얼마나 빨리 효율적으로 연산할 수 있느냔 것이지 어떤 방법을 사용하느냐 아니냐에 따라서 구분되지 않는다. 그렇게 따지면 가장 빠른 것은 가우스 덧셈이라면 1부터 100까지 합은 5050이라는 걸 외우는 것이다. 특히 for문 순회에 대해서 부정적인 경우가 많은데(단순해보이고, 순차적으로 보기 때문에) 그것이 왕도일 때도 많다.
이런 시간 복잡도의 표기법이라는 게 있다. 빅 오 표기법이라는 건데, O(입력) 형태로 표기된다. 이에 따라 복잡도는 다음 기준으로 평가가 된다. 이것은 알고리즘이 최악의 상황에서 돌아갈 때 이 성능은 보장한다는 의미의 표기법으로, 다른 표기법으로는 오메가(Ω, 최상 시간 표기)와 세타(Θ, 평균 시간 표기)가 있다.

4) 공간 복잡도
그러나 우리가 신경 써야할 것은 단순히 시간 복잡도만이 아니다. 위에서 설명한 걸 보면 시간이 빠르면 메모리도 당연히 적게 드는 거 아니야? 혹은 메모리가 많으면 시간이 느린 게 당연한 거 아니야? 싶겠지만, 조금 다르다. 당연히 메모리가 많아지면 처리 속도는 느려진다. 컴퓨터가 좋아졌으니 메모리 신경을 덜 써도 되는 것은 맞지만, 어떠한 연산은 그런 컴퓨터마저 작동하기 어렵게 만들 수도 있다. 코딩 테스트에서는 이러한 공간 복잡도도 매우 신경 쓰기 때문에, 메모리 제한이 있는 경우가 많다.
이것도 빅 오 표기법을 사용한다. 마찬가지로 O(입력) 형태로 표기하여, 복잡도는 다음 기준으로 평가 된다.

5) 안정성
안정성은 주로 정렬 알고리즘에서 많이 등장하는 기준이다. 간단히 말해, “같은 값일 때 원래 순서를 유지하는가?”를 묻는 개념이다.
예를 들어 학생 목록을 점수순으로 정렬한다고 할 때, 점수가 같은 학생들이 여러 명 있을 수 있다. 이때 안정 정렬을 사용하면, 같은 점수인 학생들끼리는 원래 리스트에서 보이던 순서 그대로 유지된다. 반대로 불안정 정렬(unstable sort)은 같은 값일 때 순서가 섞일 수 있다.
실무에서는 “1차 정렬: 점수, 2차 정렬: 이름”처럼 여러 기준으로 정렬할 때, 먼저 한 번 정렬해 둔 순서를 유지해야 하는 경우가 많기 때문에 안정성이 중요한 기준이 된다. 알고리즘 자체의 속도나 메모리만 보는 게 아니라, 정렬 후 데이터의 의미까지 보존되는지를 함께 보는 것이 안정성이라고 할 수 있다.
안정성에 대해서는 사실 번외 개념처럼 다뤄지는 경우가 많지만, 데이터를 다루기 위해서는 중요한 부분이다. 따라서 웹에서는 꽤 중요하게 취급된다.
6) 단순성
수박수박수박수박수박수?라는 프로그래머스 문제가 있다.
https://school.programmers.co.kr/learn/courses/30/lessons/12922
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
이 문제의 해답은 이러한데,
class Solution {
public String solution(int n) {
String answer = "";
String str = "수박";
answer = str.repeat(n / 2);
answer += n % 2 == 1 ? "수" : "";
return answer;
}
}
이런 해답도 존재한다.
class Solution {
String text =
"수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박수박";
public String solution(int n) {
String answer = text.substring(0, n);
return answer;
}
}
이런 방법은 단순성에서 사실 좋지 않다. 단순성이라는 것은, 남이 알아보기 쉬운가, 로직에서 틀릴 확률이 적은가를 따지는 것이다. 단순히 text를 사용하는 것은 메모리적으로도 손해지만 남이 알아보기가 어렵다는 게 문제고, 오류가 나도 바로 알 수가 없다.
사실 단순성 관련해서는 정말 재미있는 영상이 있다.
여기서 주상욱의 말을 보자. 다른 말은 어색하더라도 이 부분이 중요하다.
한줄로 짤 코드를 누가 열 줄로 만들어놨어요? 에러 찾기 힘들게.
이게 바로 단순성(가독성) 관련한 핵심적인 문장이라고 할 수 있다.
보너스. 알고리즘에 사용되는 이상한 용어들
알고리즘에 대해서 이야기할 때 가끔 나오는 용어가 있다. 남의 풀이를 보다보면 바이트나 버퍼, 스택 힙, 오버헤드 같은 이상한 단어들이 나오는데 이에 대해서 간단하게 정리해본다.

1) 바이트 스트림 / 문자 스트림
바이트 스트림은 1바이트 단위(그냥 숫자 덩어리)로 데이터를 읽고 쓰는 흐름이고, 반면 문자 스트림은 그 바이트들을 글자로 해석해서 “문자 단위”로 다루는 흐름이다. 파일/네트워크에서 데이터만 쭉 읽을 때는 바이트 스트림, 글자 단위로 읽고 싶을 땐 문자 스트림을 쓴다. InputStreamReader가 대표적으로 바이트 스트림을 문자 스트림으로 변환해주는 브릿지 클래스이다. 반면 System.in은 단순한 바이트 스트림이다.
2) 버퍼(buffer)
데이터를 "한 번에 조금씩"이 아니라 “한 덩어리로 모아서” 처리하기 위해 잠깐 쌓아두는 공간이다. 매번 한 글자씩 읽고 쓰면 너무 느려지기 때문에, 버퍼에 모았다가 묶음으로 처리해서 속도를 올린다고 보면 된다. 이 때문에 버퍼가 없으면 InputStreamReader는 의미가 없다고 봐도 된다. InputStreamReader는 바이트를 문자로 바꿔 주기만 할 뿐, 입출력 자체를 빠르게 만들어주지는 못하기 때문이다.
3) 캐시(cache)
“자주 쓰는 데이터”를 더 빠른 곳에 한 번 더 저장해 두는 공간이다. 원래 자리(디스크, 메인 메모리 등)까지 매번 갔다 오면 느리기 때문에, 가까운 데(메모리, CPU 캐시 등)에 복사본을 두고 먼저 거기서 꺼내 쓰는 방식이다. 캐시는 특히 웹에서 크게 중요하게 나오는데, 일부는 일부러 캐시 저장하지 않도록 처리하기도 한다.
4) 스택(stack) / 힙(heap)
둘 다 메모리 영역의 이름이다. 스택은 함수 호출, 지역 변수처럼 잠깐 쓰고 사라지는 것들이 쌓였다가 빠지는 공간이고, 힙은 new로 만든 객체처럼 “원할 때 만들고, 안 쓰면 지워지는 것들”을 두는 공간이라고 생각하면 된다. 재귀 호출이 너무 깊어지면 스택이 터지는 "스택 오버플로"가 난다. 위에서 설명한 완전성도 이런 스택 오버플로와 깊게 연관이 있다.
5) in-place (인플레이스)
"추가로 큰 저장공간을 만들지 않고, 원래 있던 배열/자료구조 안에서만 값들을 바꾼다"는 뜻이다. 예를 들어 배열을 뒤집을 때, 새 배열을 하나 더 만들지 않고 원래 배열 안에서만 swap하면 in-place, 같은 크기의 새 배열을 만들어 거기에 복사하면 in-place가 아니다. 보통 in-place면 공간 복잡도가 O(1)에 가깝다.
6) 오버헤드(overhead)
"원래 해야 할 일" 외에도, 그것 때문에 추가로 드는 비용을 통째로 부르는 말이다. 예를 들어서, Scanner가 편하긴 한데 내부에서 정규식도 파싱하고 이것저것 하느라 느리네? → 이때 그 느려지는 부분을 "Scanner의 오버헤드"라고 표현하는 식. 오버헤드가 크면 빈대 잡는다고 초가 삼간 태우는 일도 생길 수가 있다. 메서드의 선택 기준이 이 오버헤드의 기준이 되는 경우가 많다.
'부트캠프 일지 > 멀티캠퍼스 TIL' 카테고리의 다른 글
| [Java 풀스택 개발자] 시큐어 코딩편: 개발자가 알아야 할 웹 보안 (0) | 2026.03.17 |
|---|---|
| [Java 풀스택 개발자] 알고리즘 편#2: 알고리즘 방법론 (0) | 2026.03.09 |
| [Java 풀스택 개발자] JDBC 편 : Java와 DB의 Connection, JDBC (0) | 2026.02.24 |
| [Java 풀스택 개발자] SQL편: SQL의 작동원리와 기본 문법 (0) | 2026.02.10 |
| [Java 풀스택 개발자] Java의 용어와 개념: 낯선 Java를 친숙하게 만들어보자! (0) | 2026.02.02 |