(Helluva Boss)

영어에서 번역됨

(Helluva Boss)

205

3.9천

I.M.P 그룹, TETO의 등장 가능성!?

⯆⚉⯆
~테테테토~

"날 '귀엽다'고 하지 마, 난 갱스터라고!"
(프록시 같은 것과 함께 사용하는 걸 추천. JLMM이 작동할지는 모르겠고, 직접 테스트하기엔 너무 게을러서)

시나리오 1:
루나, 밀리, 목시가 경찰에게 쫓기고 있다.

시나리오 2:
당신은 이제 I.M.P에서 한 달째 일하고 있다. 오늘은 다들 회의가 있다.

시나리오 3:
당신은 아프다. 루나가 당신을 돌봐주고 있다. (달콤한 분위기용)

시나리오 4:
당신과 밀리는 지구에서 임무 중이다.

시나리오 5:
이런...

시나리오 6:
큰 싸움이 있었다. 가서 루나를 위로해라.

시나리오 7:
당신과 루나가 장난치고 있다.

시나리오 8:
루나, 밀리, 목시, 그리고 블리츠가 새 헬하운드를 입양하고 싶어 한다. 그게 바로 당신, 쌍둥이. (헬하운드 POV)

시나리오 9:
자신만의 시나리오를 입력하세요.

태그:
컴퓨터는 말이 안 된다. 상자에 금속 좀 넣으면 짠. 대체 여기서 무슨 일이 벌어지고 있는 걸까? 당신의 PC 안에는 중앙 처리 장치, 즉 CPU가 있다. 이건 기본적으로 트랜지스터라고 불리는 수십억 개의 미세한 스위치가 달린 실리콘 조각일 뿐이다. 전기의 흐름에 따라 켜지거나 꺼질 수 있는데, 마치 전구처럼 말이다. 이로써 우리는 1과 0이라는 두 가지 상태를 갖게 된다. 이런 스위치 하나의 값을 비트라고 한다. 비트 하나만으로는 별로 하는 게 없지만, 이걸 모으면... 8비트의 그룹을 바이트라고 하며, 0과 1의 256가지 조합을 가질 수 있다. 축하한다! 이제 우리는 이진법이라는 체계로 수를 세어 정보를 저장할 수 있다. 각 비트는 2의 거듭제곱을 나타내며, 1은 그 거듭제곱이 포함됨을, 0은 포함되지 않음을 뜻한다. 그래서 이 수는 1 곱하기 64, 1 곱하기 4, 1 곱하기 1을 더해 69가 된다. 좋긴 한데, 인간에게는 16진법이 훨씬 낫다. 흔히 이 0x로 표시되며, 단순히 이진법보다 읽기 쉬운 형식일 뿐이다. 4개의 이진 비트는 0부터 15까지 어떤 값이든 가질 수 있다. 16진법은 0부터 9, 그리고 A부터 F를 사용해 그 값들을 표현하므로, 4개의 비트 그룹은 하나의 16진수 숫자로 대체될 수 있다. 좋아, 이제 수를 저장할 수 있으니, 컴퓨터가 실제로 뭔가를 하도록 하면 된다. 트랜지스터를 사용하면 논리 게이트를 만들 수 있는데, 이는 논리적 명제를 담은 전자 회로다. 스위치 두 개가 달린 전구라고 생각하면 되는데, 특정 조건에서만 불이 켜진다. 예를 들어 A와 B가 모두 켜져 있을 때만 말이다. 논리 게이트를 영리하게 조합하면, 이진법으로 수학 연산을 형식화한 체계인 불 대수에 따라 계산을 수행하는 회로를 만들 수 있다. 하지만 컴퓨터가 0과 1을 이해한다 해도, 인간에게는 그다지 유용하지 않다. 그래서 ASCII 같은 문자 인코딩을 사용해 각 문자에 이진수를 할당할 수 있다. 키보드에서 뭔가를 입력하면 그것이 이 이진 코드로 변환되고, 컴퓨터가 이를 보는 순간 '아, 이건 대문자 A구나' 하고 화면에 찍어낸다. 이 장치들이 어떻게 맞물리는지는 Windows, Linux, Mac 같은 운영 체제 커널이 처리하는데, 이는 컴퓨터 하드웨어와 응용 프로그램 사이에 위치해 이들이 함께 작동하는 방식을 관리한다. 예를 들어 장치 드라이버 같은 것으로 말이다. 입력 장치를 사용하면 버튼 하나로 컴퓨터에 지시를 내릴 수 있지만, 가장 낮은 수준에서 컴퓨터는 기계어로 된 명령만 이해한다. 기계어는 CPU에게 무엇을 하고 어떤 데이터를 사용할지 알려주는 이진 코드다. 이런 명령을 따르는 데 있어 CPU는 일종의 천재인데, 다만 치매 걸린 금붕어의 기억력을 가졌을 뿐이다. 어떤 명령이든 처리할 수 있지만 데이터는 저장할 수 없어서, 랜덤 액세스 메모리, 즉 RAM과 함께일 때만 실질적으로 유용하다. 이를 격자라고 상상하면 되는데, 각 칸은 1바이트의 정보를 담을 수 있고, 그 정보는 데이터나 명령일 수 있으며, CPU가 네 단계로 접근할 수 있도록 주소를 가진다. 메모리에서 가져오고, 명령과 데이터를 해독하고, 마지막으로 실행하고 결과를 저장한다. 이것이 하나의 기계 주기다. 프로그램은 기본적으로 명령과 메모리의 목록일 뿐이므로, 이를 실행하기 위해 CPU는 완료될 때까지 기계 주기로 하나씩 실행한다. 아 참, 이런 게 정말 빠르게 일어난다고 말했던가? 현대 CPU는 초당 수십억 번의 주기를 수행할 수 있으며, 이는 클록 생성기에 의해 조정되고 동기화된다. 이 클록의 속도는 기가헤르츠로 측정되며, 사람들은 성능을 높이기 위해 CPU를 오버클럭하기도 하는데, 좋긴 하지만 PC에 불을 붙일 수도 있다. 더 미친 건 CPU에는 여러 코어가 있어 각각 다른 명령을 병렬로, 즉 동시에 실행할 수 있다는 점이다. 각 코어는 여러 스레드로 나뉠 수도 있어, 모든 코어가 동시에 여러 명령을 처리하며, 이들 사이를 아주 빠르게 전환할 수 있다. 좋아, 멋지다. 하지만 컴퓨터에 지시를 내릴 방법이 없다면 컴퓨터가 얼마나 강력하든 소용없다. 기계어를 손으로 타이핑하면 아마 미쳐버릴 것이다. 다행히 그럴 필요는 없다. 커널은 셸로 감싸져 있는데, 셸은 커널을 사용자에게 노출하는 프로그램일 뿐이며, 텍스트 입력이 가능한 명령줄 인터페이스에서 간단한 명령을 내릴 수 있게 해준다. 하지만 컴퓨터가 유용한 일을 하게 하는 최선의 방법은 프로그래밍 언어인데, 이는 추상화를 사용해 이런 대신 이렇게 보이는 코드를 작성하면, 그것이 대신 기계어로 변환된다. Python 같은 일부 언어는 인터프리터를 사용하는데, 소스 코드를 한 줄씩 직접 실행하려고 한다. C나 Go 같은 다른 언어는 컴파일러를 사용하며, 전체 프로그램을 기계어로 변환한 뒤 CPU가 실행할 수 있는 파일에 담는다. 이제 모든 프로그래밍 언어는 문법이 다르지만, 거의 모든 언어가 가진 기본 도구가 있다. 데이터를 사용하는 가장 기본적인 방법은 변수인데, 이름에 값을 할당해 재사용하고 수정할 수 있게 한다. 값에 따라 변수는 서로 다른 데이터 타입을 가질 수 있다. 텍스트의 경우 단일 문자와 여러 문자의 문자열이 있다. 숫자의 경우 정수가 있는데, 음수라면 부호 있는 정수가 될 수 있고, 소수 값에는 부동 소수점 수가 있다. 소수점이 정밀도와 범위를 맞바꾸며 떠다닐 수 있어 부동 소수점이라고 불린다. 이는 과학적 표기법을 사용하기 때문에 가능하다. 어떤 수 곱하기 소수점을 어디에 둘지 알려주는 거듭제곱인데, 그것이 바로 내부적으로 그들이 보이는 모습이다. 실제 수는 이진 분수로 저장된다. 3분의 1 같은 일부 분수는 이진법에서 무한 합으로만 근사될 수 있다. 하지만 메모리는 무한하지 않으므로 어느 시점에서 잘라야 하고, 이는 반올림 오류를 일으켜 가끔 꽤 이상한 계산 결과를 낳는다. 이것으로 충분치 않다면 long과 double은 두 배의 메모리를 사용해 정수와 부동 소수점의 범위를 두 배로 늘린다. Python 같은 일부 언어는 변수의 타입을 자동으로 알아내지만, C 같은 언어에서는 변수의 타입을 명시적으로 선언해야 한다. 변수의 값은 메모리의 특정 주소에 저장된다. 포인터는 값이 다른 변수의 메모리 주소인 변수이며, 이 앰퍼샌드로 표시된다. 그러니까 포인터는 그저 다른 메모리 덩어리를 가리키는 메모리 덩어리일 뿐이다. 메모리 주소는 그냥 수이므로, 메모리의 개별 바이트를 탐색하기 위해 더하고 뺄 수 있다. 이를 포인터 산술이라고 한다. C 같은 일부 저수준 언어에서는 더 이상 사용되지 않으면 메모리를 수동으로 할당하고 해제해야 한다. 이 모든 것은 힙에서 일어나는데, 힙은 프로그램의 요구에 따라 동적으로 커지고 작아질 수 있는 메모리 영역으로, 더 많은 제어를 가능하게 하지만 코드를 완전히 망가뜨리기가 엄청나게 쉬워진다. 존재하지 않거나 접근해서는 안 되는 메모리를 건드릴 수 있는데, 이를 세그멘테이션 오류라고 한다. 또한 더 이상 사용되지 않는 메모리 덩어리를 해제하는 것을 잊거나 더 이상 접근할 방법이 없다면, 그 메모리는 더 이상 사용할 수 없다. 이를 메모리 누수라고 하며 프로그램이 느려지다가 결국 충돌할 수 있다. 이 혼란을 피하기 위해 Python 같은 고수준 언어에는 메모리를 대신 관리해주는 내장 가비지 컬렉터가 있다. 데이터 타입마다 차지하는 메모리 양이 다르다. 정수는 대개 4바이트의 메모리, 단일 문자는 대개 1바이트의 메모리, 문자열은 여러 문자 바이트에 문자열의 끝을 알리는 널 문자를 더한 것이다. 이렇게 연속된 메모리 덩어리에 여러 항목을 저장하는 것이 배열의 개념이다. 더 일반적으로는 같은 데이터 타입의 항목 목록이며, 각 항목은 대개 0부터 시작하는 숫자 인덱스를 가진다. 항목들이 메모리에서 서로 옆에 있으므로, 첫 항목의 주소만 알면 포인터 산술을 이용해 배열의 어떤 항목으로든 빠르게 인덱싱할 수 있다. 배열은 데이터 구조라고 불리는 것인데, 단순히 데이터를 더 다루기 쉽게 조직하는 방식이다. 배열에서 값을 검색하는 것은 엄청나게 빠르지만, 배열의 크기는 생성할 때 고정되는 경우가 많아서, 꽉 차면 아무것도 추가할 수 없고, 다 쓰지 않으면 그냥 낭비되는 메모리가 된다. 그래서 더 유연한 옵션은 연결 리스트다. 이는 값과 다음 노드에 대한 포인터를 담은 노드를 사용해, 메모리에서 흩어져 있을 수 있게 한다. 또한 어떤 노드든 추가하고 제거할 수 있어 동적으로 커지고 작아질 수 있으며, 포인터를 재배치하기만 하면 순서를 바꿀 수 있다. 훌륭하지만, 마지막 노드에 접근할 방법이 그 이전의 모든 노드를 순회하지 않고는 없다는 점에서 비실용적일 수 있다. 그래도 배열과 연결 리스트 모두 유용한데, 큐와 스택을 만들 수 있게 해주기 때문이다. 스택은 팬케이크 더미에서 하나를 집어드는 것처럼 후입선출 원칙을 따른다. 실제로는 구조에 마지막으로 추가된 항목을 항상 가리키는 포인터를 상상하면 되고, 그러면 팝, 즉 마지막 항목을 제거하며 포인터를 뒤로 증가시킬 수 있다. 큐는 선입선출 원칙을 따르며 두 개의 포인터를 사용하는데, 하나는 처음 추가된 항목용이고 하나는 마지막 항목용이다. 새 항목은 마지막 포인터 뒤에 추가되고 그 포인터가 갱신되며, 디큐는 첫 번째 포인터에서 시작한다. 또 다른 유용한 데이터 구조는 해시 맵인데, 이는 키-값 쌍의 모음일 뿐이다. 배열처럼 작동하지만, 해시 함수를 사용해 키를 받아 인덱스에 할당하고 그곳에 값을 저장한다. 하지만 때로는 서로 다른 두 키가 같은 인덱스로 매핑될 수 있는데, 이를 충돌이라고 한다. 이를 처리하는 방법은 여러 가지가 있지만, 한 가지 방법은 배열의 해당 위치에 연결 리스트를 만드는 것으로, 그 값의 조회가 조금 느려지긴 하지만, 해시 맵은 모든 값을 가리키는 키를 정의할 수 있고 배열 기반이라 검색이 엄청나게 빠르기 때문에 매우 유용하다. 많은 문제에서 서로 다른 데이터 지점 간의 관계를 데이터 구조로 표현하는 것이 매우 유용할 수 있다. 연결 리스트의 노드를 가져오되 어떤 노드든 다른 노드를 가리킬 수 있게 하면 그래프가 되는데, 노드는 간선으로 연결되며, 간선은 방향성이 있거나 없을 수 있고, 거리나 비용 같은 어떤 지표든 나타낼 수 있는 가중치를 가질 수도 있다. 그래프는 네트워크 내 그룹을 분석하거나, 예를 들어 구글 지도에서처럼 두 지점 사이의 최단 경로를 찾는 데 유용하다. 그래프를 검색하는 주요 방법은 두 가지다. 너비 우선 탐색은 한 노드에서 시작해 대상 노드를 처음 찾을 때까지 층층이 나아간다. 깊이 우선 탐색은 막다른 길에 이를 때까지 모든 경로를 완전히 탐색한 뒤, 다른 경로가 있는 마지막 노드로 되돌아가 같은 방식으로 계속해 대상 노드를 찾을 때까지 진행한다. 어떤 두 노드든 정확히 하나의 경로로 연결된 그래프를 트리라고 하며 계층 구조, 예를 들어 컴퓨터의 파일 시스템을 나타낸다. 트리는 루트에서 시작해 리프 노드로 끝나는 하위 트리로 뻗어 나간다. 부모 노드는 어떤 수의 자식 노드든 가질 수 있지만, 이진 트리가 가장 유용한 경우가 많다. 예를 들어 어떤 노드의 왼쪽 값들은 모두 작고 오른쪽 값들은 모두 큰 이진 트리를 이진 탐색 트리라고 하며, 특정 값을 찾는 것이 매우 빨라진다. 대상 값을 찾고 싶다면 루트에서 시작하면 된다. 대상이 그 노드보다 작으면 왼쪽으로, 크면 오른쪽으로 가고, 대상을 찾을 때까지 이를 반복한다. 방금 사용한 것은 아주 간단한 알고리즘으로, 문제를 단계별로 해결하는 명령의 집합일 뿐이다. 알고리즘을 작성하는 가장 간단한 방법은 함수의 형태다. 입력을 받아 뭔가를 하고 출력을 반환한다. 변수처럼 함수의 이름으로 호출하고 서로 다른 인수를 전달할 수 있다. 함수를 호출하면 그 함수 호출이 호출 스택에 푸시되는데, 호출 스택은 코드 실행에 사용되는 단기 기억으로, 이름에서 알 수 있듯이 스택 데이터 구조에 기반하므로 후입선출이다. 알고리즘을 구현하려면 종종 두 값을 비교해야 하는데, 크다, 같다 같은 연산자와 그리고, 또는, 부정 같은 논리 표현식으로 할 수 있다. 이런 표현식은 단순하며 참이나 거짓일 수 있는데, 이는 불리언 데이터 타입의 가능한 값이며 조건문을 작성할 수 있게 해준다. 어떤 조건이 참이면 이렇게, 아니면 저렇게 하라. 불리언은 코드의 특정 부분을 반복하는 데도 쓰일 수 있다. 한 가지 방법은 while 루프다. 이 조건이 참인 동안 이 코드가 실행된다. 또 다른 방법은 for 루프인데, 배열 같은 데이터 구조 안의 모든 요소를 반복할 수 있고, 시작 값을 설정하고 각 반복 후 증가시키며 조건으로 상한을 설정해 특정 횟수만큼 반복할 수도 있다. 함수는 자기 자신을 호출할 수도 있는데, 이를 재귀라고 한다. 이는 문제를 더 작은 동일한 문제로 나눌 수 있을 때 유용한데, 예를 들어 5 팩토리얼을 계산하는 것은 5 곱하기 4 팩토리얼이고, 이는 4 곱하기... 하지만 기본적으로 재귀 함수는 그냥 영원히 자신을 호출한다. 이는 호출 스택에 더 많은 함수 호출을 계속 푸시해 스택 메모리가 초과되는 스택 오버플로에 이른다는 뜻이다. 그건 최적이 아니다. 이를 멈추려면 재귀 함수에 언제 멈출지 정의하는 기본 조건을 추가해야 한다. 그래야만 PC를 망가뜨리지 않고 함수 호출이 실행된다. 재귀는 멋지지만 시간과 공간 면에서 꽤 비쌀 수 있다. 그래서 필요한 계산량을 최소화하기 위해 과거 결과를 캐시에 저장해, 다시 나타나면 컴퓨터가 처음부터 재계산하지 않아도 되게 할 수 있다. 이를 메모이제이션이라고 한다. 성능 얘기가 나왔으니, 알고리즘이 얼마나 좋은지 판단하려면 시간 및 공간 복잡도, 즉 실행에 얼마나 많은 시간이나 공간이 필요한지 볼 수 있다. 이는 빅 오 표기법으로 측정되며, 입력 크기의 증가와 알고리즘 실행에 필요한 연산 수 사이의 관계를 설명한다. 예를 들어 배열 안의 모든 수에 1을 더하는 것은 O(...)인데, 배열이 커짐에 따라 연산 수가 선형으로 증가하기 때문이다. 중요한 것은 정확한 연산 수가 아니라 입력 크기가 무한대로 갈 때의 추세다. 보다시피 n 팩토리얼 같은 것은 어떤 선형 함수보다도 훨씬 빠르게 증가한다. 따라서 시간 복잡도가 어떤 종류의 선형 관계라면 O(...)로 단순화되고, 다른 그룹도 마찬가지다. 알고리즘을 작성할 때는 항상 다양한 접근법이 있다. 무차별 대입 접근법은 목록에서 대상을 찾을 때까지 모든 항목을 단순히 확인하는 것이다. 하지만 프로그램이 달팽이보다 빠르게 실행되길 원한다면 분할 정복 같은 더 정교한 접근법이 필요하다. 예를 들어 이진 탐색에서는 중간 요소를 반복해서 확인해 대상이 어느 쪽에 있는지 보고, 찾을 때까지 그 절반에서 계속 탐색한다. 또한 일반적으로 코드를 작성하는 다양한 접근법이 있는데, 이를 프로그래밍 패러다임이라고 한다. 선언형 프로그래밍은 코드가 무엇을 하는지 설명하지만 컴퓨터가 정확히 어떻게 해야 하는지는 설명하지 않는 반면, 명령형 프로그래밍은 컴퓨터가 결과를 달성하기 위해 어떻게 해야 하는지 상세한 명령으로 명시적으로 설명한다. 명령형 프로그래밍의 확장은 객체 지향 프로그래밍으로, 객체의 청사진인 클래스를 정의할 수 있으며, 객체는 속성 형태의 데이터와 메서드 형태의 동작으로 구성된 단일 단위다. 클래스를 코딩하려면 속성을 변수로, 메서드를 함수로 정의하는 것으로 시작한다. 클래스에 속성과 메서드를 캡슐화한 후, 객체를 인스턴스화하고 점 표기법으로 그 속성과 메서드를 사용할 수 있다. 클래스는 슈퍼클래스의 속성과 동작을 상속하지만 확장하고 재정의할 수도 있는 서브클래스를 정의할 수 있어 코드를 조직하고 재사용하기 쉽게 만든다. 예를 들어 고무오리 서브클래스는 꽥을 삑으로 구현할 수도 있다. 결과적으로 고무오리는 오리 클래스의 객체로 취급될 수 있지만 quack이 호출되면 다르게 행동하는데, 이것이 다형성의 개념이다. 하지만 일부 문제에는 이런 전통적인 패러다임 중 어느 것도 통하지 않는다. 이 이미지들 중 어느 것이 벌인지 컴퓨터가 인식하게 하고 싶다고 하자. 문제는 벌이 어떻게 생겼는지 코드로 설명할 수 없다는 것이다. 여기서 머신 러닝이 등장한다. 즉, 그 작업을 하도록 명시적으로 프로그래밍하지 않고도 컴퓨터에게 작업을 가르치는 것이다. 먼저 훈련 데이터와 테스트 데이터로 나눌 수 있는 많은 데이터가 필요하다. 다음으로 시간이 지남에 따라 매개변수를 바꿀 수 있는 알고리즘을 선택하는데, 예를 들어 다른 결과를 얻기 위해 가중치를 갱신할 수 있는 신경망이다. 아주 많은 훈련 데이터를 이 알고리즘에 먹임으로써 모델을 만들고, 그 정확도를 테스트 데이터로 확인할 수 있다. 완벽하지 않다면, 모델은 출력을 있어야 할 값과 비교하고 오류 함수에 그 차이를 담아 매개변수를 조정해 차이를 최소화함으로써 시간이 지남에 따라 개선될 수 있다. 하지만 아무리 미래적이고 최첨단이고 엄청나게 빠르고 최적화되어 있어도, 사람들이 당신이 작성한 애플리케이션을 실제로 사용하게 하려면 인터넷에 대해 알아야 할 것이다. 인터넷은 전 세계의 컴퓨터가 전선으로 연결된 네트워크다. 말 그대로 인터넷은 바다 밑을 따라 놓인 두꺼운 케이블과, 당신을 목적지로 연결해주는 인터넷 서비스 제공자 같은 시설일 뿐이다. 이 컴퓨터들은 인터넷 프로토콜 제품군으로 통신한다. 네트워크의 모든 컴퓨터는 고유한 IP 주소를 가지며, 두 컴퓨터는 전송 제어 프로토콜로 데이터를 주고받을 수 있다. 이는 메시지를 여러 패킷으로 나누어 전선 네트워크를 통해 보내고, 수신 측이 메시지를 다시 조립한다. 인터넷 연결이 좋지 않다면 패킷 손실을 경험했을 수 있는데, 이는 이 패킷들 중 일부가 가는 도중에 사라지는 것이다. 인터넷이 하드웨어라면 웹은 소프트웨어이며, 브라우저로 사용할 수 있다. 웹의 모든 페이지는 URL을 가진다. 브라우저에 입력하면, 도메인 이름 시스템, 즉 도메인 이름을 실제 서버의 IP 주소로 매핑하는 사전 같은 것으로 이 웹사이트를 호스팅하는 서버의 IP 주소를 찾는다. TCP로 연결한 후, 클라이언트라 불리는 브라우저는 하이퍼텍스트 전송 프로토콜을 사용해 서버에 HTTP 요청을 보내고, 서버는 이상적으로 웹페이지의 내용을 담은 응답을 준다. 실제 웹사이트는 대개 세 부분으로 구성된다. HTML 파일은 웹사이트의 모든 내용을 담고 기본적으로 요소의 모음일 뿐이며, 텍스트, 링크, 버튼 등이 될 수 있다. CSS 파일은 시각적 요소를 제어해 웹사이트를 보기 좋게 만든다. 하지만 보기 좋은 버튼을 눌러도 아무 일이 없다면 웹사이트는 쓸모없으므로, JavaScript 같은 언어가 기능을 더한다. 하지만 때로는 일이 잘못될 수 있다. 모든 HTTP 응답에는 응답 상태에 대한 정보를 담은 응답 코드가 따른다. 예를 들어 200은 OK를 뜻하고, 4로 시작하는 것은 오류로, 가장 유명한 것은 404, 페이지를 찾을 수 없음이다. HTTP 요청은 서로 다른 메서드를 가질 수 있는데, 예를 들어 get, post, put, delete로 정보를 검색, 추가, 갱신, 삭제한다. 이들은 종종 응용 프로그래밍 인터페이스, 즉 API에 의해 사용되며, API는 두 응용 프로그램을 연결해 서로 상호작용할 수 있게 한다. 예를 들어 데이터베이스에 데이터를 저장하고 검색하는 것이다. 가장 흔한 데이터베이스 유형은 관계형 데이터베이스로, 테이블을 사용해 데이터를 저장한다. 테이블의 열은 서로 다른 속성을 담고, 행은 개별 데이터 지점을 나타낸다. 또한 각 테이블에는 기본 키라고 불리는 고유 속성이 있다. 외래 키는 다른 테이블의 기본 키로, 두 테이블 간의 관계를 설정한다. 이 경우 각 책은 한 명의 저자와 연결된다. SQL 같은 언어로 이 테이블들의 데이터를 다루는 문장을 작성할 수 있다. 제목이 H로 시작하는 모든 책의 제목과 저자를 조회할 수 있는데, 이를 위해서는 일치하는 키로 저자 테이블과 책 테이블을 조인해 서로 다른 테이블의 두 속성을 하나로 결합해야 이 출력이 나온다. 이런 문장들은 유용하지만 조심해야 한다, 한 줄의 코드로 데이터베이스 전체를 삭제할 수도 있으니까. 걱정 마라, 그런 일은 한 번도 없었다. 모든 로그인 페이지 뒤에는 사용자 이름과 비밀번호가 담긴 데이터베이스가 있다. 사용자가 로그인을 시도하면 종종 SQL 쿼리로 사용자 입력이 데이터베이스의 항목과 일치하는지 확인한다. 좋다. 하지만 교활한 행위자는 이런 것을 입력할 수 있는데, 이는 문자열을 일찍 종료하고 나머지를 주석 처리해 쿼리를 바꾸므로, 이 사용자 이름이 데이터베이스에 존재하기만 하면 접근이 허용된다. 이를 SQL 인젝션 공격이라고 하며, 해커가 가서는 안 되는 곳에 들어가는 가장 쉬운 방법 중 하나다. 이런 개념을 듣는 것도 하나지만, 정말로 배우려면 실제 작동을 보고 직접 사용해야 하는데, 바로 그것을 Brilliant로 할 수 있다. Brilliant에는 수학과 데이터 과학부터 프로그래밍과 AI까지 수천 개의 인터랙티브 레슨이 있다. 시각적 레슨과 인터랙티브 문제로 지식을 각인시키는데, 이는 재미있고 직관적인 문제 해결 능력을 기를 뿐만 아니라 몇 시간의 강의를 보는 것보다 6배 더 효과적이라는 것이 입증되었다. 새로운 기술을 배울 시간을 내는 것이 어려울 수 있다는 걸 안다. 하지만 Brilliant는 그것을 아주 쉽게 만든다. 하루 몇 분만에, 어떤 기기에서든, 어디서든, 언제든 짤막한 레슨으로 귀중한 지식을 처음부터 쌓을 수 있다. 데이터 과학의 기초부터 Spotify의 실제 데이터셋 분석까지 순식간에 나아갈 수 있으며, 수학 기초와 Python 프로그래밍 과정으로 보완해 우리 시대 가장 수요가 많은 기술 세트 중 하나를 만들 수 있다. 가장 좋은 점은? brilliant.org/wackyscience를 방문하면 Brilliant가 제공하는 모든 것을 30일 동안 무료로 사용해볼 수 있다. 연간 프리미엄 구독료도 20% 할인된다. 이 영상을 후원해준 Brilliant에 감사한다.

생성됨 1월 30일

업데이트됨 8월 9일

게시됨 1월 30일

프록시 허용됨

공개된 채팅