GROWTH LOG STORIES

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

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

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

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

대표 이야기 읽기

ALL STORIES

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

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

성장일지

[GL 3기] 객체는 왜 같지 않은가, 그리고 내비게이션이 길을 찾는 알고리즘 (성장일지 2회차 큐레이션 ②) 🌱

GROWTH LOG🌱 2026. 8. 7. 05:22

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

{num: 1} === {num: 1}false인 이유를 메모리 주소로 따라간 기록, 그리고 전공 수업에서 배운 알고리즘이 내비게이션 안에서 도는 이야기. 3기 2회차 두 번째입니다.

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

앞선 큐레이션에서 자바스크립트 런타임과 가비지 컬렉션을 다뤘는데요, 이번 두 편은 기초를 자기 손으로 다시 확인한 기록입니다.

 

01

🧷 [자료구조] 원시타입과 참조타입의 참조변경 과정

박하진 님

박하진 님 원문에 실린 이미지
이런 내용이에요
제목 옆에 붙은 부제가 이 글의 질문입니다. "object는 왜 같지 않은가?"
숫자 11은 같은데, {num: 1}{num: 1}은 다릅니다. 다들 "원시 타입은 값, 참조 타입은 주소"라고 외우고 있죠. 그런데 "그런데 왜 그런 걸까?"에서 글이 시작됩니다.
답을 메모리 주소를 그려가며 단계별로 확인합니다. 변수를 선언하고, 복사하고, 값을 바꿀 때 주소가 어떻게 움직이는지를 표로 따라가요.

외운 걸 확인해보는 글입니다. 그리고 그 확인 과정이 아주 꼼꼼합니다.

조금 더 들어가 보면

출발점이 되는 코드가 이겁니다.

const num = 1
const newNum = 1
console.log(num === newNum)   // true

const obj = { num: 1 }
const newObj = { num: 1 }
console.log(obj === newObj)   // false

눈으로 보면 똑같이 생겼는데 결과가 반대입니다. 이 글이 짚은 답은 한 줄이에요.

"각 변수에 저장된 것은 값이 아닌 메모리 위치이기 때문."

===값을 비교하는 게 아니라 위치를 비교합니다. 위치가 같으면 같은 것, 다르면 다른 것.

그러면 왜 숫자는 위치가 같아질까요. 원시 타입은 불변(immutable)이기 때문입니다. 1은 절대 바뀌지 않으니, 여러 변수가 같은 1을 가리켜도 안전합니다. 그래서 새 공간을 만들지 않고 기존 값을 재사용해요.

객체는 다릅니다. 가변(mutable)이라 나중에 내용이 바뀔 수 있어요. {num: 1} 두 개가 같은 자리를 가리키게 만들면, 한쪽을 고쳤을 때 다른 쪽도 같이 바뀝니다. 그건 아무도 원하지 않는 동작이죠. 그래서 똑같이 생겼어도 매번 새 공간을 잡습니다.

"불변이라 공유해도 되고, 가변이라 공유하면 안 된다" — 이 한 문장이 두 타입의 차이를 전부 설명합니다.

📝 원문에서는 이렇게 따라갑니다

글의 방식이 좋습니다. 코드 한 줄마다 메모리 표를 다시 그려요.

const num = 1;
const newnum = 1;
let num2 = 1;
메모리 주소  
0x1000 1 👈 num, newnum, num2

셋 다 같은 자리를 봅니다. 그런데 여기서 하나를 바꾸면요.

num2 = 2;
메모리 주소  
0x1000 1 👈 num, newnum (참조 유지)
0x1001 2 👈 num2 (새로운 메모리 공간 할당)

0x1000의 값이 1에서 2로 바뀐 게 아닙니다. 새 자리에 2를 놓고 num2가 그쪽을 보게 만들었어요. 불변이라는 게 이런 뜻입니다.

참조 타입은 반대로 움직입니다.

let obj1 = { value: 1 }
let obj2 = obj1
obj2.value = 2
메모리 위치  
0x2000 {value: 2} 👈 obj1, obj2

obj2를 바꿨는데 obj1도 바뀌었습니다. 둘이 같은 자리를 보고 있으니까요. 이게 실무에서 사고가 나는 지점입니다. 함수에 객체를 넘겼는데 원본이 바뀌어 있는 상황이요.

그런데 여기서 한 단계 더 갑니다.

obj1 = { value: 3 }
메모리 위치  
0x2001 {value: 3} 👈 obj1
0x2000 {value: 2} 👈 obj2

이번엔 따로 갈라졌습니다. 속성을 고친 게 아니라 변수에 새 객체를 통째로 넣었기 때문이에요.

obj.value = 2(속성 변경)와 obj = {...}(재할당)는 완전히 다른 일입니다. 앞은 가리키는 자리의 내용을 바꾸고, 뒤는 가리키는 자리 자체를 바꿔요. 이 둘을 구분하면 const로 선언한 객체의 속성은 왜 바꿀 수 있는지도 자연히 풀립니다. const변수가 가리키는 자리를 고정할 뿐, 그 자리의 내용까지 잠그지는 않으니까요.

🧭 그리고 GC와 이어지는 지점

글에 이런 표시가 있습니다.

메모리 위치  
0x2001 {value: 1} 참조되지 않음. GC가 수거해갈 수 있음

재할당하고 나니 원래 객체를 아무도 안 가리키게 됐고, 그러면 가비지 컬렉터의 대상이 됩니다.

이 회차 다른 글에서 다룬 GC와 정확히 이어지는 지점이에요. "닿을 수 있으면 살아 있고, 아무도 안 가리키면 치워진다." 언어는 다르지만 원리는 같습니다.

큐레이터 노트

외운 것을 확인해봤다는 점에서 뽑았습니다.

"원시 타입은 값 복사, 참조 타입은 주소 복사"는 누구나 압니다. 그런데 "왜 그런 걸까?"를 실제로 따라가 본 사람은 드물어요. 이 글은 코드 한 줄마다 메모리 표를 다시 그리며 확인합니다. 시간이 꽤 걸리는 작업이에요.

그리고 이 방식의 이점은 응용이 된다는 겁니다. 표를 그려본 사람은 나중에 얕은 복사와 깊은 복사, 클로저, const의 범위 같은 걸 만났을 때 같은 방식으로 그려보고 답을 낼 수 있습니다. 외운 지식은 그게 안 돼요.

제목에 질문을 그대로 넣은 것도 좋았습니다. "object는 왜 같지 않은가?" — 같은 걸 궁금해하는 사람이 검색으로 정확히 찾아올 수 있는 제목입니다.

원문 읽으러 가기  ↗velog.io/@devjeenie/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%…
 

02

🗺️ [이산수학] 다익스트라 알고리즘으로 최단 경로 문제 해결하기

김혜경 님

김혜경 님 원문에 실린 이미지
이런 내용이에요
방송대 이산수학 과목에서 배운 다익스트라 알고리즘을 정리한 글입니다.
최단 경로 문제가 무엇인지부터 시작해, 의사코드를 한 줄씩 해석하고, 작은 그래프로 직접 계산해봅니다.
그리고 마지막에 실생활 활용 사례 세 가지를 붙여요. 내비게이션, 네트워크 라우팅, 게임의 길찾기입니다. 교과서 내용이 어디서 실제로 도는지가 연결됩니다.

전공 공부 기록인데, 읽고 나면 "내가 매일 쓰는 카카오내비 안에서 이게 돌고 있구나"가 남습니다.

조금 더 들어가 보면

다익스트라의 핵심 아이디어는 의외로 단순합니다. "지금까지 알아낸 것 중 가장 가까운 곳부터 확정한다."

시작점의 거리를 0, 나머지를 전부 무한대(∞)로 둡니다. "아직 가는 길을 모른다"는 뜻이에요. 그다음 아직 확정 안 된 곳 중 가장 가까운 데를 골라 확정하고, 거기서 갈 수 있는 이웃들의 거리를 다시 계산합니다.

갱신 규칙이 이 한 줄입니다.

d[v] ← min{ d[v], d[u] + w(u,v) }

"원래 알던 길"과 "지금 확정한 곳을 거쳐 가는 길" 중 짧은 쪽을 고르는 거예요. 이 비교를 계속 하다 보면 모든 곳까지의 최단 거리가 정해집니다.

글이 든 예시가 이 흐름을 잘 보여줍니다.

처음:  d[a] = 0,  d[b] = ∞,  d[c] = ∞
a 선택 → b, c 갱신:  d[b] = 4,  d[c] = 10
b 선택 → c 갱신:     d[c] = min(10, 4+3) = 7
c 선택 → 갱신할 인접 정점 없음
결과: a→b 는 4, a→c 는 7

c로 가는 길이 10에서 7로 줄어드는 순간이 이 알고리즘의 전부입니다. 직접 가면 10인데, b를 들렀다 가면 4+3=7이라 더 짧죠. 돌아가는 게 빠를 수 있다는 걸 계산으로 찾아내는 겁니다.

🧭 왜 음수 가중치가 안 되는가

글이 짚은 조건이 있습니다. "가중치가 음수가 아닌 경우에만 제대로 작동한다."

이유는 알고리즘의 전제에 있습니다. 다익스트라는 가장 가까운 곳을 고르면 그건 이제 확정이라고 봅니다. 나중에 뭘 더 봐도 더 짧아질 수 없다고 믿는 거예요.

그 믿음은 모든 길의 비용이 0 이상일 때만 성립합니다. 어딘가를 더 거치면 거리는 늘거나 그대로지, 줄지는 않으니까요.

그런데 음수 간선이 있으면 이 전제가 깨집니다. 멀리 돌아갔는데 도중에 거리가 줄어드는 상황이 가능해지거든요. 이미 확정한 답이 틀린 게 되는 겁니다. 그래서 음수가 있으면 벨만-포드 같은 다른 알고리즘을 씁니다.

거리나 시간은 음수가 될 수 없으니 실제 길찾기에는 문제가 없습니다. 하지만 가중치가 "이익"이나 "환율 차이" 같은 값이면 음수가 나올 수 있어요. 알고리즘의 전제를 아는 것이 언제 쓸 수 있는지를 아는 것입니다.

🚗 그리고 실제로 어디서 도는가

글의 마지막 부분이 이 기록을 살립니다. 세 가지 사례를 듭니다.

내비게이션 — 도로망을 그래프로 보고, 거리나 교통 상황을 가중치로 씁니다. 여기서 재미있는 게 가중치가 실시간으로 바뀐다는 점이에요. 막히는 길은 가중치가 커지니, 같은 출발지·목적지라도 시간대에 따라 다른 길이 나옵니다.

네트워크 라우팅OSPF 프로토콜이 다익스트라 기반입니다. 인터넷에서 데이터가 서버 사이를 옮겨 다닐 때 어느 경로로 갈지를 이 방식으로 정해요. 우리가 웹페이지를 열 때마다 어딘가에서 이 계산이 돌고 있는 셈입니다.

게임 길찾기 — 지형별 이동 비용을 가중치로 둡니다. 평지는 싸고 산은 비싸게요. 유닛에게 이동 명령을 내리면 알아서 돌아가는 게 이 계산 결과입니다.

교과서의 의사코드가 세 가지 전혀 다른 곳에서 돌고 있다는 걸 보여준 게 이 글의 가치예요.

큐레이터 노트

전공 수업을 실무 감각과 이어붙인 글이라 뽑았습니다.

방송대에서 배우는 이산수학은 시험을 위한 과목처럼 느껴지기 쉽습니다. 그런데 이 글은 배운 내용을 "이게 어디서 쓰이지"까지 끌고 갔어요. 그 연결이 생기면 공부의 성격이 달라집니다. 외울 것이 아니라 가진 도구가 되니까요.

의사코드를 한 줄씩 해석한 방식도 좋았습니다. 교재의 의사코드는 압축되어 있어서 처음 보면 막막한데, Q가 뭔지 Q'가 뭔지를 하나씩 풀어놨어요. 같은 과목을 듣는 동료에게 그대로 도움이 되는 형태입니다.

블로그 소개 문구도 마음에 남았습니다. "공부한 것들을 차곡차곡 기록하고 좋은 관점을 더해 쓸모 있는 지식 창고가 되고 싶은 블로그입니다." 이 글이 정확히 그 문장대로 쓰였어요. 정리에 그치지 않고 관점을 더했고, 쓸모까지 붙였습니다.

원문 읽으러 가기  ↗nanujahope.tistory.com/36

💡 두 편을 겹쳐 읽으며

한 편은 자바스크립트 메모리, 한 편은 이산수학 알고리즘입니다. 접점이 없어 보이죠.

그런데 두 글이 하는 일이 같습니다. 둘 다 "그냥 그런 거야"로 넘어가던 것을 손으로 따라가 봤습니다.

박하진 님은 ===의 결과를 메모리 주소 표를 그려가며 확인했습니다. 김혜경 님은 의사코드를 작은 그래프에 직접 대입해 계산했고요. 둘 다 읽고 이해하는 것에서 멈추지 않고, 종이에 옮겨 적어봤어요.

이 방식의 값어치는 나중에 드러납니다. 표를 그려본 사람은 처음 보는 상황에서도 똑같이 그려볼 수 있고, 알고리즘을 손으로 돌려본 사람은 조건이 바뀌었을 때 왜 안 되는지를 스스로 짚을 수 있습니다.

설명을 읽는 것과 직접 돌려보는 것 사이에는 생각보다 큰 간격이 있습니다. 그 간격을 건너간 두 편이었어요.

이번 회차에서 가져갈 것

1. ===는 값이 아니라 위치를 본다. 똑같이 생긴 객체가 false인 이유입니다. 내용을 비교하려면 직접 비교 함수를 쓰거나 직렬화해야 해요.

2. 속성 변경과 재할당은 다른 일이다. obj.value = 2가리키는 자리의 내용을 바꾸고, obj = {...}가리키는 자리 자체를 바꿉니다. const 객체의 속성을 왜 바꿀 수 있는지가 여기서 풀려요.

3. 함수에 객체를 넘길 땐 원본을 의심하기. 주소가 복사되니 함수 안에서 고치면 밖의 원본도 바뀝니다. 바꾸고 싶지 않다면 복사본을 만들어 넘기세요.

4. 알고리즘은 전제와 함께 외우기. 다익스트라는 음수 가중치에서 동작하지 않습니다. "어떻게 도는가"만 알면 언제 쓰면 안 되는지를 모릅니다.

5. 배운 걸 손으로 한 번 돌려보기. 의사코드를 작은 예제에 대입해보는 데는 10분이면 충분합니다. 읽어서 아는 것과 돌려봐서 아는 것은 다릅니다.


좋은 글 남겨주신 박하진 님, 김혜경 님께 감사드립니다! 😊

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

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


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

WRITE YOUR GROWTH

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

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

커뮤니티 둘러보기