Clean Architecture – Phụ Lục A. Khảo Cổ Kiến Trúc (Phần 1)

Để khám phá các nguyên tắc của một kiến trúc tốt, chúng ta hãy thực hiện hành trình 45 năm qua một số dự án mà tôi đã thực hiện kể từ năm 1970. Một số dự án này rất thú vị theo quan điểm kiến trúc. Một số khác thú vị vì những bài học kinh nghiệm và vì cách mà chúng có thể áp dụng vào các dự án tiếp theo.

Phụ lục này mang hơi hướng tự truyện. Tôi đã cố gắng giữ cho cuộc thảo luận có liên quan đến chủ đề kiến trúc; nhưng như trong bất kỳ cuốn tự truyện nào, các yếu tố khác đôi khi vẫn xâm nhập vào. 😉

Hệ thống kế toán hợp nhất

Vào cuối những năm 1960, một công ty tên là ASC Tabulating đã ký một hợp đồng với Local 705 của Liên Hiệp Vận Tải để cung cấp một hệ thống kế toán. Máy tính ASC được chọn để triển khai hệ thống này là một máy GE Datanet 30, như thấy ở Hình A.1.

Hình A.1 GE Datanet 30

Như bạn có thể thấy trong bức ảnh, đây là một cỗ máy khổng lồ[1]. Nó chiếm nguyên một căn phòng, và căn phòng này cần được kiểm soát thông số môi trường một cách nghiêm ngặt.

Chiếc máy tính này được tạo ra từ những ngày trước khi mạch tích hợp xuất hiện. Nó được dựng nên bởi các transistor rời. Nó thậm chí có cả một số ống chân không (mặc dù chỉ trong bộ khuếch đại cảm biến của ổ đĩa băng từ).

So với các tiêu chuẩn ngày nay thì cỗ máy này quá cồng kềnh, chậm chạp. Nó có 16K x 18 bits của lõi xử lý, với thời gian một chu kỳ khoảng 7 micro-giây[2]. Nó chiếm đầy một căn phòng lớn được kiểm soát môi trường. Nó có các ổ đĩa băng từ 7 rãnh và một ổ đĩa cứng với dung lượng 20 mega-byte.

Chiếc đĩa cứng đó trông như một con quái vật. Bạn có thể thấy nó trong bức ảnh ở Hình A.2 – nhưng có lẽ nó sẽ không mô tả đủ kích cỡ của con thú đó. Đỉnh của cái tủ đó cao hơn cả đầu tôi. Các đĩa có đường kính 36 inch (khoảng 914mm), và dày 3/8 inch (khoảng 9.5mm). Một trong những chiếc đĩa được chụp trong Hình A.3.

Bây giờ hãy đếm số đĩa trong bức ảnh đầu tiên. Có tới hơn một tá. Mỗi một chiếc có cánh tay tìm kiếm riêng và được điều khiển bởi các bộ truyền động khí nén. Bạn có thể nhìn thấy những đầu tìm kiếm này di chuyển qua các đĩa. Thời gian tìm kiếm có lẽ khoảng nửa giây tới một giây.

Khi con quái vật này bật lên, nó phát ra âm thanh như động cơ phản lực. Sàn nhà sẽ rung và lắc cho đến khi nó đạt được tốc độ[3].

Hình A.2 Bộ lưu trữ dữ liệu bằng các đĩa

Điểm mạnh của Datanet 30 là khả năng điều khiển một lượng lớn các thiết bị đầu cuối không đồng bộ ở tốc độ tương đối cao. Đó chính xác là những gì ASC cần.

ASC nằm ở Lake Bluff, Illinois, cách phía bắc Chicago 30 dặm. Văn phòng Local 705 nằm ở trung tâm Chicago. Hiệp hội này muốn hàng chục các thư ký nhập liệu của họ dùng các thiết bị đầu cuối CRT[4] (Hình A.4) để nhập dữ liệu vào hệ thống. Họ sẽ in các báo cáo lên máy teletype ASR35 (Hình A.5).

Hình A.3 Một tấm của ổ đĩa đó: dày 3/8 inch, đường kính 36 inch

Các thiết bị đầu cuối CRT chạy ở tốc độ 30 ký tự mỗi giây. Đó là tốc độ tương đối khá vào cuối những năm 1960 bởi vì thiết bị modem tương đối đơn giản vào những ngày đó.

ASC đã thuê cả tá các đường dây điện thoại riêng và số lượng modem 300 baund gấp đôi số đó từ công ty điện thoại kết nối tới Datanet 30 tới các thiết bị đầu cuối này.

Những chiếc máy tính này không đi kèm với hệ điều hành. Chúng thậm chí còn không có cả hệ thống file. Thứ mà bạn có là một trình biên dịch hợp ngữ.

Nếu bạn cần lưu dữ liệu trên đĩa cứng, thì bạn sẽ lưu dữ liệu lên đĩa cứng đó. Không phải trong một file. Không phải trong một thư mục. Bạn xác định xem đĩa nào, rãnh nào, và sector nào để đặt dữ liệu vào và sau đó bạn vận hành đĩa để đặt dữ liệu vào đó. Vâng, điều đó có nghĩa là chúng ta sẽ phải viết driver đĩa cứng của chính chúng ta.

Hình A.4 Thiết bị đầu cuối CRT

Hệ thống kế toán hợp nhất có ba loại bản ghi: Nhân Viên, Chủ, và Hội Viên. Hệ thống này là một hệ thống CRUD đối với những bản ghi này, nhưng cũng bao gồm các thao tác để đăng phí, tính toán thay đổi trong sổ cái chung.v.v.

Hệ thống gốc được viết bằng trình biên dịch hợp ngữ bởi một nhà tư vấn có khả năng nhồi tất cả những thứ đó trong 16K.

Như bạn có thể tưởng tượng, cỗ máy Datanet 30 to lớn đó rất đắt đỏ để vận hành và bảo dưỡng. Chi phí để thuê nhà tư vấn phần mềm để duy trì phần mềm chạy được cũng đắt không kém. Hơn nữa, máy tính mini đang trở nên phổ biến và rẻ hơn nhiều.

Hình A.5 Máy teletype ASR35

Vào năm 1971, khi tôi 18 tuổi, ASC đã thuê tôi và hai người bạn có cùng đam mê của tôi tới để thay thế toàn bộ hệ thống kế toán hợp nhất với một cái dựa trên máy tính mini Varian 620/f (Hình A.6). Chiếc máy tính này có giá rẻ. Tiền thuê chúng tôi cũng rẻ. Vì vậy có vẻ như ASC có một thương vụ hời.

Chiếc máy Varian có bus 16-bit và bộ nhớ lõi 32K * 16. Nó có chu kỳ khoảng 1 micro-giây. Nó mạnh mẽ hơn nhiều so với Datanet 30. Nó sử dụng công nghệ đĩa cứng 2314 rất thành công của IBM, cho phép chúng tôi lưu trữ 30-megabyte trên các đĩa chỉ có đường kính 14-inch và không thể phát nổ xuyên qua các bức tường khối bê tông!

Dĩ nhiên, chúng tôi vẫn không có hệ điều hành. Không có hệ thống file. Không có ngôn ngữ bậc cao. Tất cả thứ mà chúng tôi có là một trình biên dịch hợp ngữ. Nhưng chúng tôi đã làm.

Hình A.6 Máy tính mini Varian 620/f

Thay vì cố gắng nhồi nhét toàn bộ hệ thống vào 32K, chúng tôi đã tạo ra một hệ thống phủ chồng. Các ứng dụng sẽ được nạp từ ổ đĩa vào một khối bộ nhớ dành riêng để phủ chồng. Chúng sẽ được thực thi trong bộ nhớ đó, và được hoán đổi trước vào ổ đĩa với RAM cục bộ của chúng, để cho phép các chương trình khác thực thi.

Dĩ nhiên, khi UI của bạn chạy với tốc độ 30 ký tự một giây, thì các chương trình của bạn sẽ có nhiều thời gian để đợi. Chúng tôi có nhiều thời gian để hoán đổi các chương trình vào và ra khỏi ổ đĩa để giữ cho tất cả các thiết bị đầu cuối chạy nhanh hết mức có thể. Không một ai phàn nàn về vấn đề thời gian phản hồi hết.

Chúng tôi đã viết một trình giám sát để quản lý các ngắt và IO. Chúng tôi đã viết các ứng dụng; chúng đã viết các driver ổ đĩa, các driver thiết bị đầu cuối, các driver băng từ, và mọi thứ khác trong hệ thống đó. Không có gì trong hệ thống đó mà chúng tôi không viết cả. Mặc dù đó là một cuộc vận lộn kéo dài với quá nhiều tuần làm 80 tiếng, nhưng chúng tôi cũng đã đưa con quái vật lên và chạy được trong vòng 8 hoặc 9 tháng.

Kiến trúc của hệ thống này rất đơn giản (Hình A.7). Khi một ứng dụng bắt đầu, nó sẽ tạo ra đầu ra đến khi bộ nhớ đệm thiết bị đầu cuối của nó đầy. Sau đó bộ giám sát sẽ hoán đổi ứng dụng ra, và đổi một ứng dụng mới vào. Bộ giám sát sẽ tiếp tục trích xuất nội dung của bộ đệm đầu cuối ở tốc độ 30-cps cho đến khi nó gần hết. Sau đó, nó sẽ hoán đổi ứng dụng trở lại để lấp đầy bộ nhớ đệm lần nữa.

Hình A.7 Kiến trúc hệ thống

Có hai ranh giới trong hệ thống này. Đầu tiên là ranh giới đầu ra ký tự. Các ứng dụng này không hề biết rằng đầu ra của chúng sẽ tới một thiết bị đầu cuối 30-cps. Thực vậy, đầu ra ký tự hoàn toàn trừu tượng từ quan điểm của các ứng dụng. Các ứng dụng đơn giản truyền các chuỗi ký tự cho bộ giám sát, và bộ giám sát sẽ lo việc nạp bộ nhớ đệm, gửi các ký tự tới các thiết bị đầu cuối, và hoán đổi các ứng dụng vào và ra khỏi bộ nhớ.

Ranh giới này là phụ thuộc thông thường – nghĩa là sự phụ thuộc được trỏ theo hướng của luồng điều khiển. Các ứng dụng có các phụ thuộc vào bộ giám sát lúc biên dịch, và luồng điều khiển chuyển từ các ứng dụng tới bộ giám sát. Ranh giới này ngăn cho các ứng dụng biết về loại thiết bị mà đầu ra sẽ đi tới.

Ranh giới thứ hai là phụ thuộc được đảo ngược. Bộ giám sát có thể bắt đầu các ứng dụng, nhưng không có phụ thuộc lúc biên dịch nào vào chúng. Luồng điều khiển chuyển từ bộ giám sát tới các ứng dụng. Interface đa hình đảo ngược phụ thuộc đơn giản là thế này: Mọi ứng dụng được bắt đầu bằng cách nhảy tới chính xác cùng một địa chỉ bộ nhớ trong khu vực phủ chồng. Ranh giới này ngăn bộ giám sát khỏi biết bất cứ thứ gì về các ứng dụng ngoài điểm bắt đầu.

Cắt laser

Vào năm 1973, tôi gia nhập một công ty ở Chicago tên Teradyne Applied System (TAS). Đây là một chi nhánh của tập đoàn Teradyne, có trụ sở tại Boston. Sản phẩm của chúng tôi là một hệ thống sử dụng các tia laser công suất tương đối cao để cắt các bộ phận điện tử với độ chính xác rất cao.

Những ngày đó, các nhà sản xuất sẽ in lụa các linh kiện điện tử lên chất nền gốm. Các chất nền đó có kích thước1 inch vuông. Các bộ phận thường là điện trở – thiết bị để hạn chế dòng điện.

Trở kháng của điện trở phụ thuộc vào một số yếu tố, bao gồm thành phần và kích thước hình học của nó. Kích thước càng rộng thì điện trở của nó càng nhỏ.

Hệ thống của chúng tôi sẽ định vị chất nền gốm trong một dụng cụ có các đầu dò tiếp xúc với các điện trở. Hệ thống này sẽ đo đạc trở kháng của các điện trở, và sau đó dùng tia laser để đốt các phần của điện trở, làm cho nó ngày càng mỏng hơn cho đến khi nó đạt được giá trị điện trở mong muốn với dung sai khoảng 10%.

Chúng tôi đã bán hệ thống này cho các nhà sản xuất. Chúng tôi cũng sử dụng một số hệ thống nội bộ để cắt một số lô hàng tương đối nhỏ cho các nhà sản xuất nhỏ.

Chiếc máy tính này là một chiếc M365. Đây là thời kỳ nhiều công ty tự chế tạo máy tính: Teradyne đã chế tạo M365 và cung cấp nó cho tất cả các bộ phận của mình. M365 là một phiên bản nâng cao của PDP-8 – một máy tính mini phổ biến thời đó.

M365 điều khiển bảng định vị, nó di chuyển các tấm nền gốm dưới các đầu dò. Nó điều khiển hệ thống đo đạc và tia laser. Tia laser được định vị bằng các tấm gương X-Y có thể quay dưới sự điều khiển của chương trình. Chiếc máy tính này cũng có thể điều khiển cường độ của laser.

Môi trường phát triển của M365 tương đối thô sơ. Nó không có ổ đĩa. Thiết bị lưu trữ là các cuộn băng từ trông giống như những chiếc casset băng âm thanh 8-track. Các cuộn băng và ổ đĩa được chế tạo bởi Tri-Data.

Cũng giống như băng casset âm thanh 8-track thời đó, cuộn băng này được dẫn hướng theo một vòng lặp. Ổ đĩa chỉ di chuyển cuộn băng theo một hướng – không có tua lại! Nếu bạn muốn xác định vị trí của cuộn băng ngay từ đầu, bạn phải chuyển nó về phía trước cho tới “điểm nạp” của nó.

Cuộn băng di chuyển với tốc độ xấp xỉ 1 foot (khoảng 30cm) mỗi giây. Do vậy, nếu vòng lặp cuộn băng dài 25 feet, thì nó sẽ mất 25 giây để chuyển nó tới điểm nạp. Vì lý do này Tri-Data đã làm các cuộn băng có chiều dài khác nhau, từ 10 feet cho tới 100 feet.

M365 có một nút bấm phía trước có thể nạp bộ nhớ bằng một chương trình khởi động nhỏ và thực thi nó. Chương trình này sẽ đọc khối dữ liệu đầu tiên của băng từ, và thực thi nó. Thông thường khối này sẽ lưu một bộ nạp để nạp hệ điều hành ở trên phần còn lại của cuộn băng.

Hệ điều hành này sẽ nhắc người dùng nhập tên của một chương trình để chạy. Những chương trình này được lưu trên cuộn băng, ngay sau hệ điều hành. Chúng tôi sẽ gõ tên của chương trình – lấy ví dụ, ED-402 Editor – và hệ điều hành sẽ tìm cuộn băng có chương trình đó, nạp, và thực thi nó.

Console là một màn hình ASCII CRT phốt-pho xanh lá, rộng 72 ký tự[5], 24 dòng. Tất cả các ký tự đều viết hoa.

Để sửa một chương trình, bạn sẽ phải nạp trình soạn thảo ED-402 Editor, và sau đó đưa cuộn băng chứa mã nguồn của bạn. Bạn có thể đọc một khối mã nguồn trên cuộn băng vào bộ nhớ, và nó sẽ được hiển thị lên màn hình. Mỗi khối có thể lưu giữ 50 dòng code. Bạn thực hiện chỉnh sửa bằng cách di chuyển con trỏ quanh màn hình và gõ theo cách tương tự như vi[6]. Khi bạn hoàn thành, bạn sẽ ghi khối đó lên một cuộn băng khác, và đọc khối tiếp theo từ cuộn băng nguồn. Bạn tiếp tục làm như vậy cho đến khi hoàn thành công việc.

Không có khả năng quay trở lại các khối trước đó. Bạn sẽ phải chỉnh sửa chương trình của mình theo một đường thẳng, từ đầu đến cuối. Việc quay lại từ đầu buộc bạn phải hoàn thành việc sao chép mã nguồn vào cuộn băng đầu ra và sau đó bắt đầu một phiên chỉnh sửa mới trên băng đó. Có lẽ không có gì đáng ngạc nhiên, với những ràng buộc này, chúng tôi đã phải in các chương trình của mình ra giấy, đánh dấu tất cả các chỉnh sửa bằng tay bằng mực đỏ, và sau đó chỉnh sửa chương trình của chúng tôi theo từng khối bằng cách tham khảo các đánh dấu của chúng tôi trong danh sách này.

Khi chương trình đã được sửa xong, chúng tôi trở về hệ điều hành và gọi trình biên dịch hợp ngữ. Trình biên dịch hợp ngữ đọc cuộn băng mã nguồn, và ghi một cuộn băng nhị phân, trong khi đó cũng tạo ra một danh sách trên máy in dòng sản phẩm dữ liệu của chúng tôi.

Các cuộn băng không đáng tin cậy 100%, vì vậy chúng tôi luôn viết hai cuộn băng cùng một lúc. Bằng cách đó, ít nhất một trong số chúng có xác suất cao là không có lỗi.

Chương trình của chúng tôi có khoảng 20.000 dòng mã và mất gần 30 phút để biên dịch. Tỷ lệ chúng tôi gặp lỗi đọc băng thời kỳ đó là khoảng 1 trên 10. Nếu trình biên dịch hợp ngữ gặp lỗi băng, nó sẽ rung chuông trên bảng điều khiển và sau đó bắt đầu in một loạt lỗi trên máy in. Bạn có thể nghe thấy tiếng chuông kinh hoàng này khắp nơi trong phòng thí nghiệm. Bạn cũng có thể nghe thấy tiếng chửi rủa của một lập trình viên đáng thương, người vừa mới biết rằng quá trình biên dịch kéo dài 30 phút cần phải bắt đầu lại.

Kiến trúc này của chương trình là điển hình vào thời kỳ đó. Nó có một Chương Trình Điều hành Tổng thể (Master Operating Program), được gọi là “MOP”. Công việc của nó là quản lý các chức năng IO cơ bản và cung cấp các tính năng thô sơ của một “shell” console. Nhiều bộ phận của Teradyne đã chia sẻ mã nguồn MOP, nhưng mỗi bộ phận lại tạo một nhánh của mã nguồn này để sử dụng với mục đích riêng. Do đó, chúng tôi sẽ gửi các bản cập nhật mã nguồn cho nhau dưới dạng danh sách được đánh dấu mà sau đó chúng tôi sẽ tích hợp chúng lại theo cách thủ công (và rất cẩn thận).

Một layer tiện ích có mục đích đặc biệt là kiểm soát phần cứng đo đạc, bảng định vị và tia laser. Trong khi lớp tiện ích được gọi là MOP, MOP đã được sửa đổi riêng cho lớp đó và thường được gọi trở lại trong đó. Quả thực, chúng tôi không thực sự nghĩ về hai lớp này là các lớp riêng biệt. Đối với chúng tôi, đó chỉ là một số code mà chúng tôi đã thêm vào MOP theo một cách rất gắn kết.

Tiếp theo là layer cách ly. Lớp này cung cấp một interface máy ảo cho các chương trình ứng dụng, được viết bằng một ngôn ngữ hướng dữ liệu của một lĩnh vực cụ thể hoàn toàn khác (DSL). Ngôn ngữ này có các hoạt động để di chuyển tia laser, di chuyển bàn, tạo vết cắt, thực hiện các phép đo, v.v. Khách hàng của chúng tôi sẽ viết các chương trình ứng dụng cắt laser của họ bằng ngôn ngữ này và layer cách ly sẽ thực thi chúng.

Cách tiếp cận này không nhằm mục đích tạo ra một ngôn ngữ cắt laser độc lập với máy. Thật vậy, ngôn ngữ này có nhiều đặc điểm riêng được gắn kết sâu với các layer bên dưới. Thay vào đó, cách tiếp cận này đã cung cấp cho các lập trình viên ứng dụng một ngôn ngữ “đơn giản hơn” so với trình hợp dịch M356 để lập trình các công việc cắt của họ.

Các công việc cắt có thể được nạp từ băng và được thực thi bởi hệ thống này. Về cơ bản, hệ thống của chúng tôi là một hệ điều hành dành cho các ứng dụng cắt.

Hệ thống này được viết bằng trình biên dịch hợp ngữ M365 và được biên dịch trong một đơn vị biên dịch duy nhất để tạo ra mã nhị phân hoàn toàn.

Các ranh giới trong ứng dụng này đều rất mềm. Ngay cả ranh giới giữa mã hệ thống và các ứng dụng được viết bằng DSL cũng không được tuân thủ tốt. Sự gắn kết xuất hiện ở khắp mọi nơi.

Nhưng đó là điều bình thường của phần mềm vào đầu những năm 1970.

Theo dõi máy đúc nhôm

Vào giữa những năm 1970, trong khi OPEC đặt lệnh cấm vận đối với dầu mỏ và tình trạng thiếu xăng khiến các tài xế giận dữ đánh nhau tại các trạm xăng, thì tôi bắt đầu làm việc tại Outboard Marine Corporation (OMC). Đây là công ty mẹ của Johnson Motors và máy cắt cỏ Lawnboy.

OMC đã duy trì một cơ sở lớn ở Waukegan, Illinois, để tạo ra các bộ phận bằng nhôm đúc cho tất cả các động cơ và sản phẩm của công ty. Nhôm được nấu chảy trong các lò nung lớn, và sau đó được chở trong các thùng lớn đến hàng tá máy đúc nhôm hoạt động riêng lẻ. Mỗi chiếc máy đều có một nhân viên vận hành chịu trách nhiệm đặt khuôn, xoay máy và tách các chi tiết mới đúc. Những người vận hành này được trả tiền dựa trên số lượng chi tiết mà họ sản xuất được.

Tôi được thuê để làm việc trong một dự án tự động hóa cấp phân xưởng. OMC đã mua một máy IBM System/7 – đó là câu trả lời của IBM đối với máy tính mini. Họ gắn máy tính này vào tất cả các máy đúc trên phân xưởng để chúng tôi có thể đếm và căn thời gian, chu kỳ của mỗi máy. Nhiệm vụ của chúng tôi là thu thập tất cả thông tin đó và trình bày nó trên các màn hình xanh 3279.

Ngôn ngữ được sử dụng là hợp ngữ. Và, một lần nữa, toàn bộ mã được thực thi trong chiếc máy tính này đều là mã mà chúng tôi viết. Không có hệ điều hành, không có thư viện chương trình con và không có framework. Nó chỉ hoàn toàn là mã thô.

Nó cũng là mã thời gian thực điều khiển bởi ngắt. Mỗi chu kỳ của một máy đúc, chúng tôi phải cập nhật một loạt các thống kê và gửi các gói tin tới một chiếc máy tính IBM 370 vĩ đại trên-trời, nó đang chạy một chương trình CICS-COBOL trình bày những số liệu thống kê đó trên các màn hình màu xanh lá cây.

Tôi ghét công việc này. Ồ, tôi đã vậy ư. Ồ, công việc thật thú vị! Nhưng văn hóa thì… Chỉ cần nói rằng tôi bị buộc phải đeo cà vạt là đủ hiểu.

Ồ, tôi đã cố gắng. Tôi thực sự đã làm vậy. Nhưng rõ ràng tôi không hài lòng khi làm việc ở đó, và các đồng nghiệp của tôi biết điều đó. Họ biết điều đó vì tôi không thể nhớ những ngày quan trọng hoặc không thể dậy đủ sớm để tham dự các cuộc họp quan trọng. Đây là công việc lập trình duy nhất mà tôi từng bị sa thải — và tôi xứng đáng bị như vậy.

Từ quan điểm kiến ​​trúc, không có nhiều thứ để học ở đây ngoại trừ một điều. System/7 có một lệnh rất thú vị được gọi là thiết lập chương trình ngắt (Set Program InterruptSPI). Điều này cho phép bạn kích hoạt một ngắt của bộ xử lý, cho phép nó xử lý bất cứ ngắt nào có mức độ ưu tiên thấp hơn đang đợi khác. Ngày nay, trong Java, chúng tôi gọi nó là Thread.yield().


[1] Một trong những câu chuyện mà chúng tôi đã nghe về chiếc máy này tại ASC là nó được vận chuyển trên một chiếc xe tải se-mi rơ moóc lớn cùng với một đống đồ đạc phụ kiện. Trên đường đi, chiếc xe tải tông vào thành cầu với tốc độ cao. Chiếc máy tính này thì không sao, nhưng nó trượt về phía trước và nghiền nát mọi đồ đạc thành mảnh vụn.

[2] Ngày nay chúng ta nói rằng nó có clock rate là 142 kHz.

[3] Hãy tưởng tượng khối lượng của chiếc đĩa đó. Hãy tưởng tượng về động năng của nó! Một hôm, chúng tôi bước vào và thấy những mảnh vụn kim loại nhỏ rơi ra từ tay nắm tủ. Chúng tôi đã gọi cho người bảo trì đến kiểm tra. Anh ta khuyên chúng tôi nên đóng thiết bị này lại. Khi đến sửa chữa, anh ta nói rằng một trong những vòng bi đã bị mòn. Sau đó, anh ấy kể cho chúng tôi nghe câu chuyện về việc những chiếc đĩa này, nếu không được sửa chữa, nó có thể bị bung ra khỏi dây neo, cày xuyên tường bê tông và cắm thẳng vào ô tô trong bãi đậu xe.

[4] Cathode Ray Tube: Ống tia âm cực, đơn sắc, màn hình xanh lục, hiển thị ASCII.

[5] Con số 72 kỳ diệu đến từ các thẻ đục lỗ Hollerith, mỗi thẻ chứa 80 ký tự. 8 ký tự cuối cùng được “dành riêng” cho số thứ tự trong trường hợp bạn bỏ bộ thẻ.

[6] Chương trình soạn thảo văn bản phổ biến trên nền tảng Linux (người dịch)

Trả lời

Email của bạn sẽ không được hiển thị công khai.