GROWTH LOG STORIES

함께 만든 성장을,
기록으로 연결합니다.

AI와 함께 배우고, 직접 만들고, 서로 나눈
그로스로그 멤버들의 생생한 성장 기록을 만나보세요.

성장 기록
5기+이어진 커뮤니티
HEALTHIO
PROJECT

사진 한 장으로 시작하는 건강 루틴, Health IO

대표 이야기 읽기

ALL STORIES

성장의 순간을
한곳에서 만나보세요.

프로젝트의 시작부터 모임에서 나눈 인사이트까지,
그로스로그가 함께 만든 기록을 모았습니다.
개의 성장 기록

성장일지

[GL 4기 4회차 ②] 손대기 전에 먼저 재는 것 — 효율을 정의하는 기준, 시간 복잡도, 크롤러 유지보수 🌱

GROWTH LOG🌱 2026. 8. 11. 19:58

안녕하세요! 그로스로그 입니다!😊 🌱

효율이 무엇인지 먼저 정하는 일, 1초에 1억 번이라는 기준으로 미리 계산해보는 일, 그리고 남이 짜둔 크롤러를 고치기 전에 구조부터 읽는 일. 4기 4회차 세 편입니다.

4기 4회차는 2025년 11월입니다. 세 편이 서로 다른 자리에 있는데, 공통점이 하나 있어요. 손을 대기 전에 먼저 무언가를 재고 시작한다는 것입니다.

 

01

🧭 [CS 공부 #4] 알고리즘: 가장 효율적인 길을 설계하는 사고의 기술

홍범영 님

이런 내용이에요
CS 시리즈 4편입니다. 3편의 운영체제가 "한정된 자원을 어떻게 나눌 것인가"였다면, 이번은 "그 자원을 가장 효율적으로 활용하는 법"입니다.
알고리즘을 코드 기술이 아니라 "복잡한 세상 속에서 효율적인 길을 설계하는 사고의 기술"로 놓습니다.
탐색 · 정렬 · 최적화 세 가지로 나눠 설명하고, 각각을 일상의 판단과 겹쳐 읽어요.

앞 편의 질문을 받아 다음 질문을 여는 구조입니다. 연재를 계획해 둔 사람의 글쓰기예요.

조금 더 들어가 보면

첫 절의 제목이 이 글의 주장 전체입니다 — "효율은 '속도'가 아니라 '사고의 구조화'다."

시간 복잡도를 언급하되 이렇게 정리합니다.

"이건 단순한 수식이 아니라 '얼마나 덜 낭비할 것인가'를 정량화한 철학일 뿐입니다."

그리고 회의실 세 개에 요청이 다섯 개인 상황을 놓습니다. 컴퓨터가 이걸 스케줄링 알고리즘으로 푼다면서 두 방식을 대비시켜요 — FCFS는 공정하지만 느리고, Priority Scheduling은 효율적이지만 중요도가 낮은 일은 끝내 처리되지 않을 수 있다고요.

그래서 도달하는 질문이 이렇습니다.

"무엇을 기준으로 효율을 정의할 것인가?"

효율을 재기 전에 효율의 정의를 먼저 정해야 한다는 것. 이 순서가 이 글의 핵심입니다.

🧩 세 가지로 나눠 보기

탐색은 나침반에 비유합니다. 선형 탐색은 "한 칸씩 정직하게 모든 가능성을 확인"하고, 이진 탐색은 "절반을 과감히 버립니다." 이진 탐색을 "'가능성이 없는 길'을 지우는 용기 있는 지능"이라고 부른 대목이 인상적이에요.

정렬에서는 기준 이야기로 돌아옵니다. 버블 정렬과 퀵 정렬을 나란히 놓되, 중요한 건 무엇을 기준으로 정렬할 것인가라고 합니다. 백로그를 "'개발 난이도'로 볼지, '사용자 가치'로 볼지"에 따라 프로젝트의 효율이 달라진다는 예시가 붙어요.

최적화는 트레이드오프로 정리합니다. 그리디는 "지금 당장 최선을 택합니다. 빠르지만, 전체를 보지 못할 위험이 있습니다." 동적 프로그래밍은 과거 결과를 저장해 반복 계산을 줄이고, "느리지만, 전체 효율은 오히려 높습니다."

📝 원문에서는 이렇게 맺습니다

빅 오 표기법을 설명하면서 관점을 하나 더 붙입니다. $O(n^2)$이면 입력이 10배 커질 때 처리 시간은 100배 늘어난다고 하고서,

"이건 단순한 수식이 아니라 '규모가 커질수록 어떤 사고가 병목이 되는가'를 보여주는 지표입니다."

그리고 효율적인 사고 = 확장 가능한 사고로 연결합니다. 문제의 규모가 커져도 멈추지 않게 설계하는 것이 알고리즘적 사고의 목적이라고요.

결론은 제목 그대로입니다 — "효율은 숫자가 아니라, 선택의 철학입니다. 무엇을 먼저 풀고, 무엇을 버릴지, 그리고 언제 멈출지를 아는 것."

큐레이터 노트

알고리즘을 문제 푸는 기술이 아니라 기준 세우는 일로 읽은 글이라 뽑았습니다.

알고리즘 정리는 대개 종류와 복잡도를 나열합니다. 이 글은 "무엇을 기준으로 효율을 정의할 것인가"를 먼저 묻고 시작해요. 정의가 정해지기 전에는 어떤 알고리즘이 좋은지 말할 수 없다는 순서가 정확합니다.

FCFS와 Priority Scheduling을 나란히 놓은 대목이 그 예입니다. 어느 쪽이 낫다고 안 하고 각각 무엇을 잃는지 적었어요. 공정함을 택하면 느려지고, 효율을 택하면 낮은 우선순위가 밀립니다. 둘 다 적어야 고를 수 있습니다.

시리즈 4편인데 1편의 틀을 계속 쓰고 있는 것도 눈에 띕니다. 문제를 찾고 푸는 사고라는 관점이 회차마다 이어집니다.

원문 읽으러 가기  ↗hongby.tistory.com/14
 

02

⏱️ 코딩 테스트의 핵심, 시간 복잡도 이해하기

정다은 님

이런 내용이에요
시간 복잡도를 코딩 테스트 통과 기준으로 정리한 글입니다.
핵심 기준이 하나 있어요 — 1초 ≈ 1억 번(10⁸)의 연산. 이 숫자 하나로 알고리즘 선택이 계산 가능해집니다.
Ω · Θ · O 세 표기법을 구분하고, 왜 코딩 테스트에서는 빅-오만 보는지를 설명합니다.

앞의 글이 "효율이란 무엇인가"였다면, 이 글은 "그래서 몇 번이면 통과하는가"입니다.

조금 더 들어가 보면

첫 문장이 문제 설정입니다 — "코딩 테스트는 결국 정확함과 효율성의 싸움이다."

그리고 바로 기준을 줍니다.

💡 1초 ≈ 1억 번(=10⁸)의 연산

이 숫자가 있으면 계산이 됩니다. 예시를 그대로 보여줘요.

· 입력 크기 n = 10⁵에서 $O(n^2)$이면 약 10¹⁰번 → 1초 안에 안 끝남

· 같은 입력에 $O(n \log n)$이면 약 10⁶번 → 통과

같은 문제, 같은 입력인데 알고리즘 선택만으로 통과와 시간 초과가 갈립니다. 추상적인 "더 빠르다"가 아니라 자릿수로 보여준 게 좋습니다.

📊 세 표기법과 실전 기준

Ω(최선) · Θ(평균) · O(최악)을 표로 구분한 뒤, 코딩 테스트에서는 빅-오만 본다고 잘라 말합니다. 이유가 명확해요.

"테스트 케이스는 대부분 가장 복잡한 입력까지 포함되기 때문에"

그리고 정렬 두 개를 비교합니다. 삽입 정렬은 $O(n^2)$로 "작은 입력에서는 빠르지만, 입력이 커질수록 급격히 느려진다", 병합 정렬은 $O(n \log n)$로 "입력 크기가 커져도 안정적인 성능을 유지한다."

📝 원문에서는 실행 순서를 줍니다

마지막 팁 세 개가 이 글의 실용적인 부분입니다.

· 입력 크기 제한을 먼저 확인한다 — n ≤ 10⁶이면 $O(n \log n)$ 이하를 골라야 한다

· 자주 나오는 복잡도를 외운다 — 정렬 $O(n \log n)$, 이진 탐색 $O(\log n)$, 완전 탐색 $O(2^n)$ 또는 $O(n!)$

· 풀기 전에 대략 계산해본다"이 알고리즘이면 대략 몇 번의 연산이 필요할까?"

첫 번째가 순서를 뒤집습니다. 문제를 읽고 바로 짜는 대신, 입력 크기 제한을 먼저 보고 쓸 수 있는 알고리즘의 범위를 좁히는 것이죠.

큐레이터 노트

기준 숫자 하나로 판단을 계산 가능하게 만든 글이라 뽑았습니다.

"1초 ≈ 1억 번" — 이게 있으면 시간 복잡도가 이론에서 도구로 바뀝니다. n과 제한 시간을 보고 곱해보면 되니까요. 코딩 테스트를 준비하는 회원들에게는 바로 쓰이는 정보입니다.

"먼저 확인한다"는 순서도 짚어두고 싶습니다. 시간 초과는 다 짜고 제출한 다음에 알게 되는 실패예요. 입력 제한을 먼저 보면 짜기 전에 걸러집니다. 앞 편 홍범영 님의 "손대기 전에 기준을 정한다"와 같은 이야기를 실전 쪽에서 하고 있습니다.

원문 읽으러 가기  ↗devika.tistory.com/127
 

03

🕷️ 크롤링 코드 수리하기

노현주 님

노현주 님 원문에 실린 이미지
이런 내용이에요
이미 작성돼 있던 크롤링 코드를 유지보수하면서 알게 된 것을 정리한 글입니다. 크롤링 자체가 처음이었다고 해요.
scrapy-selenium 미들웨어가 무엇을 대신 해주는지, 별도로 selenium을 쓸 때와 어떻게 다른지를 나눠 적었습니다.
그리고 실제로 막혔던 문제 두 가지를 남겼어요 — 뷰포트 밖 요소 클릭과 CDATA 처리입니다.

새로 만든 게 아니라 남이 짜둔 것을 고친 기록입니다.

조금 더 들어가 보면

scrapy-selenium이 하는 일을 세 줄로 정리합니다.

· Scrapy 요청을 처리할 때 셀레니움 웹드라이버를 런치하고, url을 로드하고, 종료해준다

· 로드된 HTML을 Scrapy의 표준 응답과 유사한 SeleniumResponse 객체로 변환해 스파이더에 전달한다

· JavaScript 실행이 필요한 동적 페이지도 Scrapy 프레임워크 안에서 처리할 수 있다

그리고 바로 옆에 selenium을 별도로 쓸 경우를 놓았습니다. webdriver.Chrome()으로 직접 초기화하고, 끝나면 driver.quit()으로 수동 종료해야 한다고요.

미들웨어가 무엇을 대신 해주는지가 이 대비로 드러납니다. 도구 설명을 읽을 때 "그래서 이게 없으면 뭘 해야 하지"를 같이 봐야 이해가 되는데, 그걸 나란히 적어둔 겁니다.

⚙️ 막혔던 자리

문제 두 개를 실제 겪은 순서대로 적었습니다.

뷰포트 밖 요소 참조. Selenium은 화면에 보이지 않는 요소에 대한 클릭이 불안정하거나 불가능할 수 있다는 것. 해결은 요소를 화면에 노출시킨 뒤 클릭하는 것이고, scrollIntoView를 쓴 코드를 남겼습니다.

CDATA 처리. XML 출력 시 데이터 안에 <>가 들어 있으면 문법 오류가 날 수 있으니 <![CDATA[...]]> 로 감싸야 한다는 것. 여기에 주의사항을 덧붙였어요 — "XML 생성 라이브러리가 자동으로 CDATA 선언을 인코딩하지 않도록 주의."

감싸는 것만으로는 안 되고, 라이브러리가 그걸 또 인코딩해버리는 경우가 있다는 이야기입니다. 실제로 부딪혀야 아는 종류의 정보예요.

📝 원문에서는 기다리는 문제도 짚습니다

작동 플로우 중간에 이런 대목이 있습니다. XPATH로 메뉴 버튼을 찾아 클릭해 페이지를 이동시킨 다음,

"driver.page_source를 반복적으로 확인하여 JavaScript 동작으로 인한 DOM 변경이 멈출 때까지 기다려야 함"

동적 페이지 크롤링에서 가장 자주 걸리는 자리입니다. 요소가 아직 안 나타났는데 찾으러 가면 실패하니까요. 그리고 스크롤 영역을 execute_script로 강제 설정한 코드도 함께 남겼습니다.

수정 절차의 첫 단계도 적혀 있어요 — xpath로 페이지 구조부터 확인하기. 실제 xpath 경로를 스크린샷과 함께 남겼습니다.

큐레이터 노트

유지보수로 시작한 기록이라 뽑았습니다.

성장일지에 올라오는 코드 이야기는 대개 새로 만든 것입니다. 이 글은 이미 있는 코드를 고치면서 배운 것이에요. 실무에서 훨씬 자주 하는 일인데 기록으로는 잘 안 남습니다. 처음 보는 코드를 읽고, 왜 이렇게 짰는지 파악하고, 그다음에 고치는 순서니까요.

막힌 자리를 구체적으로 남긴 것이 이 글의 값어치입니다. 뷰포트 밖 요소 클릭과 CDATA 이중 인코딩 — 둘 다 검색해도 잘 안 나오고, 부딪히면 한참 헤매는 종류예요. "복기 목적으로 정리"한다고 적었는데, 같은 문제를 만날 다음 사람에게도 그대로 쓸모가 있습니다.

원문 읽으러 가기  ↗anyway03.tistory.com/6

💡 세 편을 겹쳐 읽으며

세 편이 효율을 재는 자리에서 만납니다. 그런데 재는 목적이 다 달라요.

홍범영 님정의를 잽니다. "무엇을 기준으로 효율을 정의할 것인가" — 무엇이 좋은지 말하려면 좋음의 기준부터 정해야 한다는 것이죠.

정다은 님숫자를 잽니다. 1초에 1억 번. n이 10⁵일 때 $O(n^2)$이면 10¹⁰번이라 안 됩니다. 정의가 아니라 통과선이에요.

노현주 님실제로 안 되는 것을 잽니다. 이론상 클릭되는 요소가 화면 밖에 있어서 안 되고, 감싼 CDATA를 라이브러리가 또 인코딩해서 안 됩니다.

같은 순서가 셋 다 있습니다. 손대기 전에 먼저 무언가를 확인한다는 것이요. 정다은 님은 "입력 크기 제한을 먼저 확인한다", 노현주 님은 "xpath 등으로 페이지 구조 확인"을 첫 단계로 놓았습니다. 홍범영 님은 아예 그걸 글 전체의 주장으로 삼았고요.

그리고 셋 다 트레이드오프를 적었습니다. FCFS는 공정하지만 느리고, 삽입 정렬은 작은 입력에서 빠르고, 미들웨어를 쓰면 편한 대신 드라이버를 직접 다루지 못합니다. 한쪽만 적으면 고를 수 없습니다.

이번 회차에서 가져갈 것

1. 효율을 재기 전에 효율의 정의를 정하기.

공정함인지 처리량인지에 따라 답이 달라집니다. 기준 없이 "더 좋은 방법"을 찾으면 답이 안 나옵니다.

2. 기준 숫자를 하나 갖기.

"1초 ≈ 1억 번" 같은 것이요. 숫자가 있으면 감으로 고르던 것이 계산으로 바뀝니다.

3. 짜기 전에 입력 크기 제한 보기.

시간 초과는 제출하고 나서 알게 되는 실패입니다. 먼저 보면 쓸 수 있는 알고리즘의 범위가 미리 좁혀집니다.

4. 도구를 배울 때 "없으면 뭘 해야 하는지"도 같이 보기.

미들웨어가 드라이버를 런치·로드·종료해준다는 건, 안 쓰면 그걸 직접 해야 한다는 뜻입니다. 대비를 봐야 도구의 자리가 보입니다.

5. 남이 짜둔 코드는 구조부터 읽기.

고치기 전에 xpath로 페이지 구조를 확인하는 것처럼요. 바로 손대면 왜 그렇게 짰는지 모른 채 부수게 됩니다.

6. 막혔던 자리를 구체적으로 남기기.

뷰포트 밖 요소, CDATA 이중 인코딩 — 검색해도 잘 안 나오는 것일수록 기록의 값어치가 큽니다.

좋은 글 남겨주신 홍범영 님, 정다은 님, 노현주 님께 감사드립니다! 😊

다음 큐레이션으로 다시 찾아오겠습니다! 🌱

- 에디터 · 성장일지 큐레이터 -


성장일지는 멤버들이 2주에 한 번씩 자신의 성장을 기록하는 활동이에요. 매 회차 운영진이 모든 글을 읽고, 그중 특히 마음에 남은 글을 함께 골라 큐레이션합니다.


※ 본 큐레이션은 각 저자가 공개한 글을 소개하는 것이며, 모든 원문의 저작권은 저자에게 있습니다. 저자 본인의 요청이 있을 경우 즉시 수정 또는 삭제합니다.

WRITE YOUR GROWTH

오늘의 배움을
내일의 성장으로.

기록은 나를 돌아보게 하고, 공유는 우리를 연결합니다.
당신의 다음 성장 이야기도 그로스로그에서 시작해보세요.

커뮤니티 둘러보기