Mục lục bài họcĐang ở d02-b4
Operating System Services, Application Software and Character Encoding
What the operating system does, and for whom. Applications never touch hardware directly; every file read, every pixel drawn, every packet sent goes through the operating system. That is why it carries a fixed list of responsibilities you should be able to name and explain: memory management (allocating RAM to programs and keeping them out of each other's space); processor scheduling (deciding which process runs next); the file system (organising storage into files and folders with permissions); device management (drivers that translate generic requests into commands for a specific printer or disk); the user interface; security (users, passwords, access rights); and multitasking (switching between programs fast enough to appear simultaneous). A question that asks for a function wants the function and what would go wrong without it.
Hiding complexity. The most examinable idea about operating systems is that they present a simple picture of a complicated machine. A physical disk with platters and sectors appears as a drive letter and a folder tree. RAM plus a region of disk appear as one large, continuous virtual memory. Thousands of printer models appear as one Print command, because the driver does the translation. A Java program sees a single virtual machine rather than the real processor, so the same code runs on any hardware. Each abstraction lets application programmers and users ignore detail they do not need — at the cost of some performance and of not knowing what is really happening when something goes wrong.
Application software. Word processors, spreadsheets, databases, browsers, email, graphics and computer-aided design each solve a class of user problems and share common features: a graphical interface, toolbars, menus, dialogue boxes, and — the point examiners like — common features that reduce learning, so that Save or Undo works the same way in every program. Applications are chosen by fitness for purpose, cost, compatibility with existing data and hardware, and support, not by feature count.
Characters are numbers. A computer stores only bits, so every character is a code. ASCII uses 7 bits for 128 characters: uppercase A is 65, lowercase a is 97, the digit 0 is 48, space is 32. Uppercase and lowercase differ by exactly 32, one bit, which is why case conversion is a single bit flip. ASCII has no Vietnamese, no Chinese, no accents; Unicode assigns over 140 000 codes covering every script, and UTF-8 stores them in one to four bytes, so Vietnamese text takes more space than English. Because digits are characters with their own codes, comparing numbers stored as strings goes wrong: "10" sorts before "9" because the character 1 is less than the character 9. Hexadecimal is a shorthand for binary — each hex digit is exactly four bits, so 1010 1111 is AF — used for memory addresses, colours and MAC addresses because it is compact and converts trivially. The machine does not store hex; hex is for human eyes. Underlying all of this: the same bit pattern is a number, a character, a colour or an instruction depending only on how the program reading it chooses to interpret it.
Hệ điều hành làm gì, và cho ai. Ứng dụng không bao giờ chạm phần cứng trực tiếp; mọi lần đọc tệp, vẽ điểm ảnh, gửi gói tin đều đi qua hệ điều hành. Đó là lý do nó gánh một danh sách trách nhiệm cố định mà bạn phải gọi tên và giải thích được: quản lý bộ nhớ (cấp RAM cho chương trình và giữ chúng không lấn sang vùng của nhau); lập lịch bộ xử lý (quyết định tiến trình nào chạy tiếp); hệ tệp (tổ chức bộ nhớ ngoài thành tệp và thư mục có quyền truy cập); quản lý thiết bị (trình điều khiển dịch yêu cầu chung thành lệnh cho một máy in hay ổ đĩa cụ thể); giao diện người dùng; bảo mật (người dùng, mật khẩu, quyền); và đa nhiệm (chuyển giữa các chương trình đủ nhanh để có vẻ đồng thời). Câu hỏi yêu cầu nêu một chức năng muốn cả chức năng lẫn điều gì sẽ hỏng nếu thiếu nó.
Giấu sự phức tạp. Ý dễ ra thi nhất về hệ điều hành là nó trình bày một bức tranh đơn giản của một cỗ máy phức tạp. Một ổ đĩa vật lý với đĩa từ và sector hiện ra như một ký tự ổ và một cây thư mục. RAM cộng một vùng đĩa hiện ra như một bộ nhớ ảo lớn, liền mạch. Hàng nghìn kiểu máy in hiện ra như một lệnh In duy nhất, vì trình điều khiển làm việc dịch. Một chương trình Java thấy một máy ảo duy nhất thay vì bộ xử lý thật, nên cùng mã chạy trên mọi phần cứng. Mỗi lớp trừu tượng cho phép người lập trình ứng dụng và người dùng bỏ qua chi tiết họ không cần — với cái giá là mất một chút hiệu năng và không biết chuyện gì thực sự xảy ra khi có lỗi.
Phần mềm ứng dụng. Soạn thảo văn bản, bảng tính, cơ sở dữ liệu, trình duyệt, thư điện tử, đồ hoạ và thiết kế có máy tính hỗ trợ, mỗi loại giải một lớp bài toán của người dùng và chia sẻ các đặc điểm chung: giao diện đồ hoạ, thanh công cụ, menu, hộp thoại, và — điểm giám khảo thích — các đặc điểm chung làm giảm thời gian học, để Lưu hay Hoàn tác hoạt động giống nhau ở mọi chương trình. Ứng dụng được chọn theo mức phù hợp với mục đích, chi phí, tương thích với dữ liệu và phần cứng hiện có, và hỗ trợ, chứ không theo số tính năng.
Ký tự là số. Máy tính chỉ lưu bit, nên mọi ký tự là một mã. ASCII dùng 7 bit cho 128 ký tự: A hoa là 65, a thường là 97, chữ số 0 là 48, dấu cách là 32. Chữ hoa và chữ thường cách nhau đúng 32, một bit, nên đổi hoa thường chỉ là lật một bit. ASCII không có tiếng Việt, tiếng Trung hay dấu; Unicode gán hơn 140 000 mã cho mọi chữ viết, và UTF-8 lưu chúng trong một tới bốn byte, nên văn bản tiếng Việt tốn chỗ hơn tiếng Anh. Vì chữ số là ký tự có mã riêng, so sánh số lưu dưới dạng chuỗi cho kết quả sai: "10" xếp trước "9" vì ký tự 1 nhỏ hơn ký tự 9. Hex là cách viết tắt nhị phân — mỗi chữ số hex đúng bốn bit, nên 1010 1111 là AF — dùng cho địa chỉ bộ nhớ, màu và địa chỉ MAC vì gọn và chuyển đổi dễ. Máy không lưu hex; hex là cho mắt người. Nền của tất cả: cùng một dãy bit là số, là ký tự, là màu hay là lệnh chỉ tuỳ vào chương trình đọc nó chọn diễn giải thế nào.
Một chương trình sắp xếp danh sách mã học sinh nhập từ tệp và cho ra thứ tự: 1, 10, 11, 2, 3. Cùng chương trình đó hiển thị tên "Nguyễn Văn Ế" thành "Nguy?n V?n ?". Giải thích cả hai và nêu cách sửa.
Lỗi 1 — so sánh chuỗi thay vì số. Mã học sinh được đọc từ tệp dưới dạng chuỗi ký tự, và chương trình sắp xếp theo thứ tự ký tự. So sánh chuỗi đi từ trái sang phải: "10" và "2" được so ở ký tự đầu, và ký tự 1 (mã 49) nhỏ hơn ký tự 2 (mã 50), nên "10" đứng trước "2" bất kể phần sau. Thứ tự 1, 10, 11, 2, 3 là thứ tự từ điển, hoàn toàn đúng với chuỗi — chương trình không sai, nó làm đúng việc sai. Sửa: chuyển mã sang số nguyên trước khi sắp xếp, hoặc nếu mã phải là chuỗi thì đệm số 0 cho đủ độ dài cố định (01, 02, 10, 11) để thứ tự từ điển trùng thứ tự số.
Lỗi 2 — sai bảng mã. Tên được lưu bằng Unicode (UTF-8), trong đó ễ, ă, Ế là các mã lớn hơn 127 và chiếm hai hoặc ba byte mỗi ký tự. Chương trình đọc tệp và diễn giải từng byte như ASCII 7 bit hoặc một bảng mã 8 bit khác; các byte không có ý nghĩa trong bảng đó được thay bằng dấu hỏi. Các chữ không dấu hiển thị đúng vì mã của chúng dưới 128 và giống nhau ở mọi bảng mã — đó là manh mối chẩn đoán. Sửa: khai báo đúng bảng mã UTF-8 khi mở tệp và khi hiển thị; nếu tệp gốc đã bị lưu sai bảng mã thì phải xuất lại từ nguồn.
Bài học chung. Cả hai lỗi có cùng gốc: cùng một dãy byte được diễn giải theo hai cách. Ở lỗi 1, dãy byte của "10" được coi là hai ký tự thay vì một số; ở lỗi 2, ba byte của một chữ Việt được coi là ba ký tự riêng. Dữ liệu không tự biết mình là gì — chương trình quyết định.
(a) Chuyển 2C hex sang nhị phân và thập phân. (b) Chuyển 1101 0110 sang hex. (c) Một địa chỉ bộ nhớ được viết bằng 6 chữ số hex; hỏi bộ nhớ có tối đa bao nhiêu byte nếu mỗi địa chỉ trỏ tới một byte? (d) Vì sao dùng hex thay vì viết nhị phân trực tiếp?
(a) 2C. Mỗi chữ số hex là bốn bit: 2 = 0010, C = 12 = 1100, nên 2C = 0010 1100. Thập phân: 2 × 16 + 12 = 44. Kiểm lại từ nhị phân: 32 + 8 + 4 = 44.
(b) 1101 0110. Tách thành hai nhóm bốn bit từ phải sang: 1101 = 13 = D, 0110 = 6. Kết quả D6. Lỗi hay gặp là tách nhóm từ trái khi số bit không chia hết cho bốn — luôn tách từ phải và đệm 0 bên trái nếu cần.
(c) Sáu chữ số hex. Mỗi chữ số hex là bốn bit, nên 6 chữ số = 24 bit. Số địa chỉ = 224 = 16 777 216, tức 16 MiB khi mỗi địa chỉ là một byte. Cách trả lời nhanh: 166 = 224. Câu này nối với bus địa chỉ ở bài 1: bus 24 bit đánh địa chỉ được đúng chừng ấy.
(d) Vì sao hex. Một địa chỉ 24 bit viết nhị phân là 24 ký tự 0 và 1 rất dễ đọc nhầm; viết hex chỉ 6 ký tự. Vì mỗi chữ số hex là đúng bốn bit, chuyển đổi hai chiều làm được bằng mắt mà không cần tính — điều thập phân không có, vì 10 không phải luỹ thừa của 2. Đó là lý do hex xuất hiện ở địa chỉ bộ nhớ, mã màu (#FF8800 là ba byte đỏ, lục, lam) và địa chỉ MAC. Cần nói rõ trong bài: máy không lưu hex, nó chỉ lưu bit; hex là cách con người viết bit cho gọn.
Bẫy 2 — nói máy tính lưu hex. Máy chỉ lưu bit; hex là cách viết cho người, mỗi chữ số đúng bốn bit.
Bẫy 3 — coi ASCII và Unicode như nhau. ASCII 7 bit, 128 ký tự, không có tiếng Việt; Unicode hơn 140 000 mã, UTF-8 một tới bốn byte.
Đọc xong rồi — làm thử ngay
Bài tập của chương Computer Organization gồm 14 câu trắc nghiệm và 5 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.