1.1 소프트웨어 엔지니어링 1.0에서 2.0으로의 전환

1. 서론: 코드의 본질적 변화와 새로운 지평

컴퓨터 과학의 태동기부터 현재에 이르기까지, ’소프트웨어 개발’이라는 행위는 인간의 지적 노동을 기계가 이해할 수 있는 명시적인 논리로 변환하는 과정을 의미했습니다. 앨런 튜링(Alan Turing)이 정의한 보편적 기계(Universal Machine)의 개념 위에서, 프로그래머들은 수십 년간 문제 해결을 위한 알고리즘을 직접 설계하고, 이를 C++, Java, Python과 같은 프로그래밍 언어를 통해 한 줄 한 줄 코딩해왔습니다. 우리는 이를 **소프트웨어 1.0(Software 1.0)**이라고 부릅니다. 이 고전적인 패러다임은 인간이 문제의 구조를 완벽하게 이해하고, 이를 논리적인 단계로 분해할 수 있다는 전제 하에 성립되었습니다.

그러나 지난 10년, 특히 딥러닝(Deep Learning)과 인공지능 기술의 폭발적인 발전은 소프트웨어를 바라보는 우리의 관점을 송두리째 뒤흔들고 있습니다. 테슬라(Tesla)의 전 AI 디렉터이자 오픈AI(OpenAI)의 창립 멤버인 안드레이 카패시(Andrej Karpathy)는 이러한 변화를 **소프트웨어 2.0(Software 2.0)**이라는 개념으로 정의했습니다. 이는 단순히 새로운 언어나 도구의 등장이 아니라, 소프트웨어를 구성하는 ’코드’의 본질이 인간이 작성한 논리에서 데이터와 최적화 알고리즘이 발견해낸 수학적 가중치(Weights)로 변화했음을 의미합니다.

본 장에서는 소프트웨어 엔지니어링의 역사적 전환점인 1.0에서 2.0으로의 이행 과정을 심도 있게 분석합니다. 우리는 이 변화가 단순한 기술적 대체를 넘어, 개발 방법론, 테스트 및 검증 전략(오라클 문제), 유지보수와 기술 부채의 성격, 그리고 궁극적으로는 프로그래머라는 직업의 정의 자체를 어떻게 재구성하고 있는지 탐구할 것입니다.

2. 소프트웨어 1.0: 명시적 논리와 환원주의적 접근 (The Classical Stack)

2.1 정의: 프로그래머가 지배하는 세상

소프트웨어 1.0은 우리가 전통적으로 인지하고 있는 프로그래밍의 형태입니다. 이는 Python, C++, Java, JavaScript 등과 같은 언어로 작성된 소스 코드(Source Code)로 구성됩니다. 이 패러다임의 핵심은 **명시성(Explicitness)**과 **프로그래머의 통제(Programmer Control)**에 있습니다. 프로그래머는 컴퓨터가 수행해야 할 모든 작업을 구체적인 명령어로 작성하며, 프로그램의 논리적 흐름(Control Flow)을 완벽하게 장악합니다.

소프트웨어 1.0 개발 프로세스는 본질적으로 환원주의적(Reductionist)입니다. 복잡한 문제를 해결하기 위해 프로그래머는 이를 더 작은 하위 문제로 분해(Decomposition)하고, 각 하위 문제를 해결하는 함수나 모듈을 작성한 뒤, 이를 다시 조립하여 전체 시스템을 구축합니다. 예를 들어, 전자상거래 시스템을 개발한다고 가정해 봅시다. 개발자는 데이터베이스 스키마를 정의하고, 결제 처리 로직을 위한 if-else 조건을 작성하며, 사용자 인터페이스와 서버 간의 API 통신 규약을 명시합니다. 이 모든 과정에서 코드의 한 줄 한 줄은 프로그래머의 의도된 설계(Designed Logic)를 반영합니다.

2.2 한계: 폴라니의 역설과 복잡성의 장벽

소프트웨어 1.0은 금융 거래, 웹 서버 라우팅, 데이터 처리 등 규칙이 명확하고 논리적으로 기술 가능한 영역에서는 탁월한 성능을 발휘해 왔습니다. 그러나 현실 세계의 불확실하고 모호한 문제들, 특히 **인지(Perception)**와 관련된 문제에 직면했을 때 소프트웨어 1.0은 한계에 부딪혔습니다.

이 한계는 마이클 폴라니(Michael Polanyi)가 제시한 “우리는 우리가 말할 수 있는 것보다 더 많은 것을 알고 있다(We know more than we can tell)“는 **폴라니의 역설(Polanyi’s Paradox)**로 설명될 수 있습니다. 예를 들어, 인간은 사진 속의 고양이를 0.1초 만에 식별할 수 있습니다. 하지만 “고양이를 식별하는 규칙이 무엇인가?“라는 질문에 대해 명시적인 알고리즘을 작성하는 것은 거의 불가능에 가깝습니다. 고양이의 귀 모양, 털의 질감, 조명에 따른 색상 변화 등 수만 가지의 변수를 if-else 구문으로 표현하려는 시도는 수십 년간 컴퓨터 비전 분야에서 실패를 거듭했습니다.

소프트웨어 1.0의 접근 방식인 “특징 공학(Feature Engineering)“은 사람이 이미지의 에지(Edge)나 코너(Corner)를 검출하는 알고리즘(예: Sobel Filter, HOG)을 직접 설계하는 것이었으나, 이는 데이터의 다양성을 포용하지 못했고 확장성에 심각한 제약이 있었습니다. 결과적으로 소프트웨어 1.0은 복잡성이 일정 수준을 넘어서는 문제, 즉 규칙으로 정의하기 힘든 문제 영역(Problem Space)에서는 더 이상 효율적인 해결책이 되지 못했습니다.

3. 소프트웨어 2.0: 최적화를 통한 코드의 발견 (The Optimization Stack)

3.1 패러다임의 전환: 작성(Writing)에서 검색(Searching)으로

소프트웨어 2.0은 코드를 인간이 직접 작성하는 것이 아니라, 최적화(Optimization) 과정을 통해 찾아내는 새로운 방법론입니다. 이 패러다임에서 ’코드’는 더 이상 사람이 읽을 수 있는 텍스트가 아니라, 신경망(Neural Network)을 구성하는 수백만, 수십억 개의 **가중치(Weights)**로 존재합니다.

소프트웨어 2.0 개발 프로세스는 다음과 같이 진행됩니다:

  1. 목표 설정(Goal Definition): 개발자는 프로그램이 달성해야 할 목표를 정의합니다. (예: “이 이미지 셋을 입력받아 올바른 레이블로 분류하라”)
  2. 아키텍처 설계(Architecture Design): 개발자는 프로그램의 뼈대가 될 신경망 구조(예: CNN, Transformer)를 선택합니다. 이는 소프트웨어 1.0의 알고리즘 설계와 유사해 보이지만, 구체적인 동작이 아닌 ’학습 가능한 공간’을 정의한다는 점에서 다릅니다.
  3. 데이터 큐레이션(Data Curation): 개발자는 바람직한 동작을 예시하는 대규모 데이터셋을 수집하고 정제합니다. 이것이 소프트웨어 2.0의 실질적인 ‘소스 코드’ 역할을 합니다.
  4. 최적화(Optimization): 경사 하강법(Gradient Descent)과 역전파(Backpropagation) 알고리즘을 사용하여, 에러(Error)를 최소화하는 가중치 조합을 찾아냅니다. 이 과정은 마치 컴파일러가 소스 코드를 바이너리로 변환하는 것과 유사하지만, 훨씬 더 확률적이고 계산 집약적입니다.

결국, 소프트웨어 2.0에서 프로그래머는 코드를 ’작성’하는 것이 아니라, 가능한 프로그램의 거대한 검색 공간(Search Space)에서 최적의 프로그램을 **검색(Search)**하거나 **발견(Discover)**하는 역할을 수행합니다.

3.2 수학적 본질: 동질성(Homogeneity)과 추상화

소프트웨어 2.0은 본질적으로 수학적 연산의 거대한 덩어리입니다. 전통적인 소프트웨어 1.0이 복잡한 명령어 집합(Instruction Set)과 다양한 로직 분기(Branching)로 이루어진 이질적(Heterogeneous) 구조라면, 소프트웨어 2.0인 신경망은 행렬 곱셈(Matrix Multiplication)과 활성화 함수(ReLU 등)라는 두 가지 핵심 연산의 무한한 반복으로 구성된 동질적(Homogeneous) 구조를 가집니다.

카패시는 이를 “추상적이고 인간에게 친화적이지 않은 언어(Abstract, human unfriendly language)“라고 묘사했습니다. 수백만 개의 부동 소수점 숫자로 이루어진 가중치 행렬은 인간이 직관적으로 이해할 수 없지만, 컴퓨터 하드웨어 입장에서는 매우 효율적으로 처리할 수 있는 형태입니다. 이 동질성은 하드웨어 가속기(GPU, TPU)의 설계 철학과 완벽하게 일치하며, 이는 소프트웨어 2.0이 폭발적으로 성장할 수 있었던 물리적 기반이 되었습니다.

4. 1.0과 2.0의 심층 비교 분석 (Comparative Analysis)

소프트웨어 2.0으로의 전환은 단순한 성능 향상을 넘어, 소프트웨어의 속성과 유지보수 방식에 있어 트레이드오프(Trade-off)의 변화를 가져옵니다.

4.1 계산적 특성과 실행 시간의 예측 가능성

소프트웨어 1.0은 조건문(if-then-else)에 따라 실행 경로가 달라지므로, 입력값에 따라 실행 시간이 크게 변동할 수 있습니다. 이는 실시간 시스템(Real-time System)에서 최악의 경우(Worst-case) 실행 시간을 보장하기 어렵게 만듭니다. 반면, 소프트웨어 2.0의 순전파(Forward Pass)는 입력 데이터의 값과 무관하게 항상 고정된 수의 부동 소수점 연산(FLOPS)을 수행합니다. 이는 시스템의 성능을 예측 가능하게 만들고, 하드웨어 리소스 사용량을 정확하게 산정할 수 있게 해 줍니다. 무한 루프에 빠질 위험이 구조적으로 배제되어 있다는 점 또한 2.0의 특징입니다.

4.2 민첩성(Agility)과 하드웨어 친화성

기존 C++ 코드(1.0)를 최적화하여 속도를 2배 높이는 작업은 매우 고통스럽고 복잡한 리팩토링을 요구합니다. 그러나 소프트웨어 2.0에서는 단순히 신경망의 채널 수를 절반으로 줄이고 재학습(Retraining)시키는 것만으로 정확도를 약간 희생하면서 속도를 정확히 2배 높일 수 있습니다. 성능, 정확도, 메모리 사용량 간의 교환 관계가 선형적이고 연속적이어서, 요구사항 변화에 훨씬 민첩하게 대응할 수 있습니다.

또한, 소프트웨어 2.0은 **이식성(Portability)**이 뛰어납니다. 행렬 연산은 어떤 하드웨어 아키텍처에서든 쉽게 구현될 수 있으므로, 모델을 서버에서 학습시키고 모바일 기기나 임베디드 칩으로 배포하는 과정이 1.0 코드의 포팅(Porting)보다 훨씬 수월합니다.

4.3 해석 가능성(Interpretability)의 상실

가장 큰 손실은 해석 가능성입니다. 소프트웨어 1.0에서는 “왜 이 코드가 실행되었는가?“를 디버거를 통해 추적할 수 있습니다. 하지만 소프트웨어 2.0에서는 “왜 모델이 이 이미지를 고양이로 분류했는가?“라는 질문에 대해 “수백만 개의 가중치가 그렇게 계산되었기 때문“이라는 답 외에는 명쾌한 설명을 내놓기 어렵습니다. 이는 의료나 법률, 금융과 같이 결정의 근거가 중요한 분야(Explainable AI가 요구되는 분야)에서 소프트웨어 2.0 도입의 큰 장벽이 되고 있습니다.

5. 사양의 위기와 오라클 문제 (The Crisis of Specification and the Oracle Problem)

소프트웨어 2.0으로의 전환이 가져온 가장 심각하고 철학적인 문제는 바로 **‘사양(Specification)의 부재’**와 이로 인한 **‘오라클 문제(Oracle Problem)’**입니다. 이는 기존 소프트웨어 공학의 품질 검증 체계를 근본적으로 위협합니다.

5.1 사양 부재와 테스트 불가능성 (Non-testable Programs)

전통적인 소프트웨어 엔지니어링(1.0)에서는 개발 시작 전에 요구사항 명세서(SRS)가 작성됩니다. “입력값 A가 들어오면 시스템은 반드시 B를 출력해야 한다“는 명확한 진리(Ground Truth)가 존재합니다. 이를 바탕으로 테스트 케이스를 작성하고, 예상 결과와 실제 결과를 비교하는 것이 가능했습니다.

그러나 소프트웨어 2.0이 다루는 문제들—이미지 인식, 자연어 번역, 자율주행 등—은 본질적으로 완벽한 사양을 정의하는 것이 불가능합니다. “좋은 번역이란 무엇인가?”, “안전한 운전이란 무엇인가?“에 대해 수학적으로 모호함 없이 정의할 수 있는 공식은 존재하지 않습니다. 사양이 없다는 것은 정답을 판별할 기준이 없다는 것을 의미하며, 이러한 프로그램을 **‘테스트 불가능한 프로그램(Non-testable Programs)’**이라고 부릅니다.

5.2 오라클 문제의 심화 (The Oracle Problem)

**오라클(Oracle)**이란 테스트 수행 결과가 올바른지 판단할 수 있는 메커니즘을 말합니다. 소프트웨어 2.0에서는 자동화된 오라클을 구축하기가 극도로 어렵습니다.

  • 휴먼 오라클의 비용: 대부분의 머신러닝 모델 검증은 인간 라벨러(Human Oracle)에 의존합니다. 사람이 직접 이미지를 보고 “이것은 고양이“라고 판별한 결과를 정답(Ground Truth)으로 삼습니다. 그러나 인간 오라클은 비용이 많이 들고, 속도가 느리며, 주관적이고, 무엇보다 실수할 수 있습니다.
  • 부분적 오라클과 변성 테스트(Metamorphic Testing): 완전한 오라클이 없을 때, 우리는 **변성 테스트(Metamorphic Testing)**와 같은 기법을 사용하여 **부분적 오라클(Partial Oracle)**을 구축합니다. 이는 입력값을 변형시켰을 때 출력값이 어떻게 변해야 하는지에 대한 **관계(Relation)**를 검증하는 것입니다. 예를 들어, 자율주행 AI를 테스트할 때, 맑은 날씨의 주행 데이터를 ’비가 오는 날씨’로 그래픽적으로 변환(입력 변형)하더라도, 차량의 조향 각도(출력)는 급격하게 변하지 않아야 한다는 ’관계’를 테스트합니다. 정답은 모르지만, 적어도 논리적 일관성은 검증할 수 있습니다.

5.3 확률적 정확도와 침묵하는 실패 (Silent Failures)

소프트웨어 1.0은 버그가 있으면 프로그램이 충돌(Crash)하거나 예외(Exception)를 던집니다. 이는 명확한 신호입니다. 반면, 소프트웨어 2.0은 **“침묵하는 실패(Silent Failures)”**를 겪습니다. 데이터 분포가 바뀌거나 잘못된 학습이 이루어져도, 신경망은 오류를 뱉지 않고 그저 낮은 확률의 엉뚱한 예측값을 내놓으며 계속 작동합니다. 이는 시스템이 언제, 왜 실패했는지 파악하기 어렵게 만들며, 특히 안전이 중요한 시스템(Safety-Critical Systems)에서 큰 위험 요소가 됩니다. 따라서 소프트웨어 2.0 시대의 엔지니어링은 ’결함의 부재(Absence of Defects)’를 증명하는 것에서 **‘확률적 신뢰성(Probabilistic Reliability)’**을 관리하는 것으로 목표가 이동합니다.

6. 새로운 엔지니어링 부채와 유지보수의 악몽 (The New Technical Debt)

소프트웨어 2.0은 강력한 성능을 제공하지만, 그 대가로 기존에 없던 새롭고 복잡한 형태의 **기술 부채(Technical Debt)**를 도입합니다. 구글의 연구진은 이를 “기계학습 시스템의 숨겨진 기술 부채(Hidden Technical Debt in Machine Learning Systems)“라고 명명하며, 2.0 시스템이 1.0 시스템보다 유지보수가 훨씬 어렵다는 점을 경고했습니다.

6.1 데이터 부채(Data Debt)와 얽힘(Entanglement)

소프트웨어 1.0에서는 모듈화(Modularity)와 캡슐화(Encapsulation)를 통해 코드의 한 부분을 수정해도 다른 부분에 영향을 주지 않도록 격리할 수 있습니다. 그러나 소프트웨어 2.0 모델은 모든 입력 피처(Feature)가 서로 얽혀(Entangled) 있습니다. 이를 **CACE 원칙(Changing Anything Changes Everything)**이라고 합니다. 모델의 입력 중 하나인 ’사용자 나이’의 형식을 바꾸거나 데이터를 업데이트하면, 모델 전체의 가중치 최적화 결과가 바뀌어 버립니다. 이는 부분적인 수정이나 격리된 단위 테스트(Unit Test)를 불가능하게 만듭니다.

또한, 데이터 드리프트(Data Drift) 현상은 끊임없는 유지보수를 요구합니다. 1.0 코드는 수정하지 않으면 썩지 않지만(Software Rot은 비유적 표현임), 2.0 모델은 입력 데이터의 실제 분포가 변함에 따라 가만히 있어도 성능이 퇴보합니다. 이는 모델을 지속적으로 재학습시키고 모니터링해야 하는 운영 부담을 가중시킵니다.

6.2 접착제 코드(Glue Code)와 파이프라인 정글

많은 사람들이 소프트웨어 2.0을 도입하면 코딩이 사라질 것이라 착각하지만, 실제로는 파이프라인 코드가 그 자리를 대체합니다. 실제 머신러닝 시스템에서 핵심 모델 코드(2.0 코드)는 전체의 5% 미만에 불과합니다. 나머지 95%는 데이터를 수집, 검증, 전처리하고, 모델을 학습시키며, 결과를 서빙하고 모니터링하기 위한 방대한 **접착제 코드(Glue Code)**입니다. 이 주변부 코드는 대부분 소프트웨어 1.0(Python, C++ 등)으로 작성되며, 복잡한 의존성으로 인해 ’파이프라인 정글(Pipeline Jungle)’을 형성하여 유지보수를 어렵게 만듭니다.

6.3 소프트웨어 의존성 2.0 (Software Dependencies 2.0)

최근 연구는 소프트웨어 의존성의 개념을 2.0으로 확장하고 있습니다. 기존의 라이브러리 임포트(Import)가 1.0 의존성이라면, 사전 학습된 모델(Pre-trained Models, PTM)을 가져와 사용하는 것은 소프트웨어 의존성 2.0입니다. 이는 단순히 코드를 가져오는 것이 아니라, 해당 모델에 내재된 데이터의 편향, 학습된 행동, 그리고 알 수 없는 결함까지 그대로 상속받는 것을 의미합니다. 허깅페이스(Hugging Face)와 같은 모델 허브가 새로운 패키지 관리자로 부상하고 있지만, 모델 간의 호환성이나 버전 관리는 아직 초기 단계의 혼란을 겪고 있습니다.

7. 조직과 인재의 변화: 2.0 시대의 프로그래머

이러한 기술적 지형의 변화는 개발 조직의 구조와 프로그래머의 역할에 대한 재정의를 요구합니다. 카패시는 미래의 개발 조직이 1.0 프로그래머2.0 프로그래머로 분화될 것이라 예측했습니다.

7.1 역할의 분화와 협업

  • 1.0 프로그래머 (인프라 및 도구 엔지니어): 이들은 여전히 명시적인 코드를 작성합니다. 하지만 그 대상은 최종 애플리케이션 로직이 아니라, 2.0 코드를 생산하기 위한 **공장(Factory)**을 짓는 것입니다. 데이터 라벨링 도구, 시각화 대시보드, 대규모 분산 학습 인프라를 구축하고 유지보수합니다. 이들은 시스템의 안정성과 확장성을 책임지는 ’플랫폼 엔지니어’의 성격을 띠게 됩니다.
  • 2.0 프로그래머 (데이터 큐레이터): 이들의 주된 업무는 데이터셋을 수집, 정제, 라벨링하고 분석하는 것입니다. 이들에게 “프로그래밍을 한다“는 것은 “좋은 데이터를 큐레이션한다“는 것과 동의어입니다. 모델이 특정 케이스에서 실패할 때, 이들은 코드를 고치는 대신 해당 케이스의 데이터를 더 많이 수집하여 데이터셋에 추가합니다. 이는 프로그래밍이 논리 작성에서 **교육(Teaching)**과 커리큘럼 설계로 변화하고 있음을 보여줍니다.

7.2 도구의 진화: IDE에서 데이터 플랫폼으로

소프트웨어 1.0을 위한 도구가 텍스트 에디터(VS Code, IntelliJ)와 디버거였다면, 소프트웨어 2.0을 위한 IDE는 데이터 시각화 및 관리 도구입니다. 데이터의 분포를 시각적으로 확인하고, 잘못 라벨링된 데이터를 찾아내며, 모델의 예측 결과를 분석하는 도구들이 필수적입니다. 깃허브(GitHub)가 1.0 코드의 저장소라면, 허깅페이스(Hugging Face)나 모델 아틀라스(Model Atlas)와 같은 플랫폼이 2.0 시대의 저장소로 자리 잡고 있으며, 여기서 ’커밋(Commit)’은 코드 변경이 아니라 모델 가중치나 데이터셋의 업데이트를 의미합니다.

8. 결론: 소프트웨어 3.0(LLM)으로의 확장과 미래 전망

소프트웨어 엔지니어링 1.0에서 2.0으로의 전환은 단순한 기술 트렌드가 아닙니다. 그것은 컴퓨터에게 명령을 내리는 방식이 연역적(Deductive) 지시에서 귀납적(Inductive) 학습으로 바뀌는 문명사적 전환입니다. 2.0 패러다임은 우리가 과거에는 접근조차 할 수 없었던 인지적 문제들을 해결할 수 있게 해주었지만, 동시에 설명 가능성의 상실과 검증의 어려움이라는 막대한 비용을 청구했습니다.

이제 우리는 이 변화의 연장선상에서 소프트웨어 3.0의 부상을 목격하고 있습니다. 대규모 언어 모델(LLM)의 등장은 프로그래밍 인터페이스를 자연어(Natural Language)로 변화시키고 있습니다. 1.0이 코드를 작성하고, 2.0이 데이터를 관리했다면, 3.0은 프롬프트(Prompt)를 통해 거대 모델과 대화하며 원하는 결과를 얻어냅니다. 이는 프로그래밍의 민주화를 가속화하지만, 동시에 2.0이 가진 불확실성과 환각(Hallucination)이라는 문제를 더욱 증폭시키기도 합니다.

성공적인 현대의 소프트웨어 엔지니어는 이 1.0, 2.0, 3.0의 패러다임을 유연하게 오가야 합니다. 1.0의 견고한 인프라 위에, 2.0의 강력한 인지 능력을 얹고, 3.0의 직관적인 인터페이스로 이를 제어하는 하이브리드 아키텍처를 설계할 수 있어야 합니다. 소프트웨어는 더 이상 단순히 ’작성(Written)’되는 것이 아니라, 데이터와 상호작용하며 지속적으로 ’성장(Grown)’하고 ’관리(Managed)’되어야 하는 유기체가 되었습니다. 이것이 바로 우리가 맞이하고 있는 소프트웨어 엔지니어링의 새로운 시대정신입니다.

9. 참고 자료

  1. Software 2.0: An Emerging Era of Automatic Code Generation, https://blog.softtek.com/software-2.0-an-emerging-era-of-automatic-code-generation
  2. Software 2.0. I sometimes see people refer to neural… | by Andrej …, https://karpathy.medium.com/software-2-0-a64152b37c35
  3. Evolution of Software Development: Software 1.0 to Software 3.0, https://stackspot.com/en/blog/evolution-of-software-development/
  4. Building the Software 2.0 Stack by Andrej Karpathy [video], https://news.ycombinator.com/item?id=17280454
  5. Software 1.0, 2.0, and 3.0 - Grokipedia, https://grokipedia.com/page/Software_10_20_and_30
  6. Software 2.0: Emerging era of automatic generation of codes, https://sanjoygupta.com/software-2-0-emerging-era-of-automatic-generation-of-codes/
  7. The “Oracle Problem” and Its Impacts in Mixed Reality, https://ntrs.nasa.gov/api/citations/20230012828/downloads/Lehman%20-%20Oracle%20Problem_r3.pdf
  8. Test, don’t (just) verify - Alperen Keles, https://alperenkeles.com/posts/test-dont-verify/
  9. Fault-based testing in the absence of an oracle - SciSpace, https://scispace.com/pdf/fault-based-testing-in-the-absence-of-an-oracle-2e5ldwdoyv.pdf
  10. The Oracle Problem in Software Testing: A Survey - IEEE Xplore, https://ieeexplore.ieee.org/iel7/32/7106034/06963470.pdf
  11. The Oracle Problem in Software Testing: A Survey - EECS 481, https://eecs481.org/readings/testoracles.pdf
  12. The Oracle Problem in Software Testing: A Survey, http://www0.cs.ucl.ac.uk/staff/m.harman/tse-oracle.pdf
  13. The Oracle Problem in Software Testing: A Survey - UCL Discovery, https://discovery.ucl.ac.uk/1471263/
  14. The Oracle Problem - YLD, https://www.yld.io/blog/the-oracle-problem
  15. Intramorphic Testing: A New Approach to the Test Oracle Problem, https://www.research-collection.ethz.ch/server/api/core/bitstreams/30763e1f-803c-4e57-ae67-db38fc84cfc1/content
  16. A Machine Learning Approach for Developing Test Oracles for, https://ksiresearch.org/seke/seke16paper/seke16paper_137.pdf
  17. Security of Software 1.0 vs 2.0 - Xander Dunn, https://xander.ai/security-of-software-1-0-vs-2-0
  18. The transition from Software 1.0 to Software 2.0 | Insights - Liontrust, https://www.liontrust.com/insights/blogs/2025/02/the-transition-from-software-1-to-software-2
  19. A Scoping Review and Assessment Framework for Technical Debt, https://www.mdpi.com/2076-3417/15/13/7165
  20. Software Dependencies 2.0: An Empirical Study of Reuse and, https://arxiv.org/html/2509.06085v1
  21. Andrej Karpathy: Software is Changing (Again) - Storyboard, https://clearthink-ai.com/storyboards/software-is-changing-again/story
  22. Andrej Karpathy: Software Is Changing (Again) - The Singju Post, https://singjupost.com/andrej-karpathy-software-is-changing-again/
  23. Software 1.0 vs Software 2.0 vs Software 3.0: A 3-Minute Breakdown, https://medium.com/@agile.cadre.testing/software-1-0-vs-software-2-0-vs-software-3-0-a-3-minute-breakdown-2fb17a16340f
  24. (PDF) The Oracle Problem in Software Testing: A Survey, https://www.researchgate.net/publication/276255185_The_Oracle_Problem_in_Software_Testing_A_Survey
  25. A Survey on Test Oracles - Open Journal Systems, https://revista.univem.edu.br/jadi/article/download/1034/393/0
  26. Hacker’s guide to Neural Networks - Andrej Karpathy blog, http://karpathy.github.io/neuralnets/
  27. Parsing mathematical equation to generate computation graphs, https://blog.owulveryck.info/2017/12/18/parsing-mathematical-equation-to-generate-computation-graphs-first-step-from-software-1.0-to-2.0-in-go.html