Danh sách câu hỏi của đề

Câu hỏi: PRP201c Lập trình Python – Bộ ôn tập thi lại số 2

48 câu trắc nghiệm kèm lời giải của môn PRP201c - Lập trình Python, xếp đúng thứ tự trong đề. Trang 2/3 — câu 21–40.

Danh sách câu hỏi

40/48 câuCòn 8
21In the following XML, which are attributes?5 lựa chọncó code
Đề bài
<person>
  <name>Chuck</name>
  <phone type="intl">
    +1 734 303 4456
  </phone>
  <email hide="yes" />
</person>
Atype
Bemail
Cperson
Dname
Ehide
Lời giải
Đáp án đúng gồm hai ý: "type" và "hide". Thuộc tính (attribute) trong XML là cặp tên bằng giá trị đặt trong nháy, viết bên trong thẻ mở của một phần tử: ở đây thẻ phone mang thuộc tính type với giá trị intl, còn thẻ tự đóng email mang thuộc tính hide với giá trị yes. Trong Python với ElementTree, ta đọc thuộc tính bằng get, ví dụ tree.find('phone').get('type') cho 'intl'. "person" là tên phần tử gốc (root element) bao toàn bộ tài liệu, không phải thuộc tính. "name" là một phần tử con chứa văn bản Chuck, đọc bằng thuộc tính text chứ không bằng get. "email" là tên một phần tử, cụ thể là thẻ tự đóng không có nội dung; nó là nơi mang thuộc tính hide chứ bản thân nó không phải thuộc tính.
Mở trang câu hỏi này →
Asocket.accept()
Bsocket.sendto(address)
Csocket.acceptsocket
Daccept.socket()
Lời giải
Đáp án đúng: "socket.accept()". Một chương trình máy chủ TCP thường đi qua các bước: tạo socket, gọi bind() gắn địa chỉ và cổng, listen() để bắt đầu lắng nghe, rồi gọi accept(); accept() chờ tới khi có máy khách từ máy khác kết nối tới, sau đó trả về một cặp gồm socket mới dành riêng cho kết nối đó và địa chỉ của máy khách. Phương án "socket.sendto(address)" dùng để gửi dữ liệu tới một địa chỉ, chủ yếu với socket UDP, không nhận kết nối nào, và còn cần thêm đối số dữ liệu. Phương án "socket.acceptsocket" không phải phương thức nào của mô-đun socket, lại thiếu cặp ngoặc gọi hàm. Phương án "accept.socket()" đảo ngược tên đối tượng và phương thức: accept là phương thức của đối tượng socket nên phải viết theo thứ tự đối tượng rồi phương thức, không có đối tượng accept nào chứa phương thức socket.
Mở trang câu hỏi này →
Aappend()
BIndex assignment list[2] = x
Cremove()
Dinsert()
Lời giải
Đáp án đúng: "Index assignment list[2] = x". List là kiểu khả biến (mutable), nên có thể ghi đè phần tử tại một vị trí bằng phép gán theo chỉ số: lst[2] = x thay giá trị ở vị trí 2, độ dài list giữ nguyên, các phần tử khác không bị dịch. Chỉ số phải nằm trong khoảng hiện có, nếu không sẽ gây IndexError. "append()" thêm một phần tử mới vào cuối list, làm list dài thêm chứ không sửa phần tử có sẵn. "remove()" xoá lần xuất hiện đầu tiên của một giá trị, tìm theo giá trị chứ không theo vị trí, và làm list ngắn lại. "insert()" chèn phần tử vào một vị trí, như lst.insert(2, x), đẩy các phần tử từ vị trí đó lùi ra sau; giá trị cũ ở vị trí 2 vẫn còn, chỉ bị dời chỗ, nên đó là chèn chứ không phải cập nhật. Lưu ý đặt tên biến là list sẽ che mất hàm list() có sẵn, nên thực tế nên dùng tên khác.
Mở trang câu hỏi này →
AThe Request/Response Cycle
BIMAP
CInternet Protocol (IP)
DDECNET
ESMTP
Lời giải
Đáp án đúng: "The Request/Response Cycle". Khi trình duyệt tải một trang, nó mở kết nối tới máy chủ, gửi yêu cầu (request) HTTP như GET /page.html, máy chủ trả về phản hồi (response) gồm phần đầu và nội dung, trình duyệt hiển thị rồi mỗi lần người dùng bấm liên kết lại lặp một vòng yêu cầu mới; chuỗi lặp đó gọi là chu trình yêu cầu/phản hồi. "IMAP" sai vì đó là giao thức đọc thư điện tử trên máy chủ thư. "Internet Protocol (IP)" sai vì IP là tầng định tuyến gói tin bên dưới, HTTP chạy trên TCP/IP chứ IP không phải tên của việc tải trang. "DECNET" sai vì đó là bộ giao thức mạng cũ của hãng Digital Equipment Corporation, không liên quan tới web. "SMTP" sai vì đó là giao thức gửi thư điện tử.
Mở trang câu hỏi này →
At becomes sorted list
Bt becomes None
Ct becomes reversed
DError occurs
Lời giải
Đáp án đúng: "t becomes None". Phương thức sort() của list sắp xếp tại chỗ (in-place), tức sửa trực tiếp list đó, và trả về None; vì vậy khi gán lại vào t, list vẫn được sắp xếp xong nhưng tên t bị gán thành None và mất tham chiếu tới list. Muốn giữ kết quả, hãy gọi t.sort() trên một dòng riêng, hoặc dùng t = sorted(t) vì sorted() trả về list mới. "t becomes sorted list" chỉ đúng nếu dùng sorted(t), không đúng với sort(). "t becomes reversed" sai vì sort() sắp tăng dần chứ không đảo; muốn đảo phải dùng reverse() hoặc sort(reverse=True), mà reverse() cũng trả về None. "Error occurs" sai vì phép gán chạy bình thường; lỗi chỉ xuất hiện về sau khi dùng t như list, ví dụ lấy phần tử đầu sẽ gây TypeError vì NoneType không truy cập theo chỉ số được.
Mở trang câu hỏi này →
Đề bài
<a>
  <b>X</b>
  <c>
    <d>Y</d>
    <e>Z</e>
  </c>
</a>
Ab
Ba
Cc
De
Lời giải
Đáp án đúng: "c". Trong XML, các phần tử lồng nhau tạo thành cây; nút cha (parent node) của một nút là phần tử bao trực tiếp nó, tức thẻ mở gần nhất chưa đóng ngay phía trên nó. Thẻ e nằm giữa thẻ mở và thẻ đóng của c, cùng cấp với d, nên c là cha trực tiếp của e còn d là anh em (sibling) của e. Chọn "b" là sai vì b chỉ chứa chữ X và đã đóng trước khi c mở, nên b là anh em của c chứ không bao e. Chọn "a" là sai vì a là nút gốc, chỉ là tổ tiên (ancestor) của e qua trung gian c, không phải cha trực tiếp. Chọn "e" là sai vì một nút không thể là cha của chính nó; e chỉ chứa nút văn bản Z.
Mở trang câu hỏi này →
Atn.read_until(b"Login:")
Btn.read_until(b"user: ")
Ctn.read_until(b"user:")
Dtn.read_until(b"Username: ")
Lời giải
Đáp án đúng: "tn.read_until(b"Username: ")". Câu hỏi dùng module telnetlib: sau khi tạo đối tượng tn = telnetlib.Telnet(host), phương thức read_until đọc dữ liệu từ kết nối cho tới khi gặp đúng chuỗi byte được chỉ định, nên phải truyền đúng dấu nhắc (prompt) mà thiết bị in ra; router Cisco khi bật xác thực đăng nhập in dấu nhắc mặc định là chữ Username, dấu hai chấm và một dấu cách, sau đó script mới gửi tên người dùng bằng tn.write. Trong Python 3 đối số phải là kiểu bytes nên có tiền tố b. "tn.read_until(b"Login:")" chờ chuỗi Login mà router Cisco không in theo mặc định, nên lệnh sẽ đứng chờ tới hết thời gian chờ. "tn.read_until(b"user: ")" sai chữ: read_until so khớp từng byte và phân biệt hoa thường, mà dấu nhắc thật bắt đầu bằng U hoa và có chữ name. "tn.read_until(b"user:")" sai tương tự, lại thiếu cả dấu cách sau dấu hai chấm. Lưu ý telnetlib bị đánh dấu lỗi thời từ Python 3.11 và đã bị gỡ khỏi thư viện chuẩn ở Python 3.13 (PEP 594), nên mã này chỉ chạy trên phiên bản cũ hơn; ngày nay thường dùng SSH qua Paramiko hoặc Netmiko.
Mở trang câu hỏi này →
AThat the web site allows scraping
BThat the web site supports the HTTP GET command
CThat the web site returns HTML for all pages
DThat the web site only has links within the same site
Lời giải
Đáp án đúng: "That the web site allows scraping". Trước khi viết chương trình tự động tải và bóc dữ liệu từ một trang (web scraping), cần xem trang có cho phép điều đó không: đọc điều khoản sử dụng và tệp robots.txt ở gốc tên miền, vì có trang cấm thu thập tự động hoặc chỉ cho phép ở mức độ nhất định; bỏ qua bước này có thể bị chặn địa chỉ IP hoặc vi phạm điều khoản. Phương án "That the web site supports the HTTP GET command" không cần kiểm vì mọi máy chủ web đều phục vụ trang qua GET, đó chính là cách trình duyệt mở trang. Phương án "That the web site returns HTML for all pages" không phải điều kiện: chương trình có thể xử lý cả JSON, XML hay ảnh tuỳ theo trang. Phương án "That the web site only has links within the same site" không liên quan: liên kết trỏ ra trang khác chỉ cần lọc khi lần theo, chứ không quyết định có được phép thu thập hay không.
Mở trang câu hỏi này →
APacket
BSession
CData Link
DPhysical
Lời giải
Đáp án đúng: "Packet". Mô hình OSI có bảy tầng, từ dưới lên: Physical, Data Link, Network, Transport, Session, Presentation, Application. Packet (gói tin) không phải tên tầng mà là tên đơn vị dữ liệu ở tầng Network, nơi giao thức IP định tuyến các gói giữa các mạng; tương tự frame là đơn vị dữ liệu ở tầng Data Link. "Session" là tầng thứ năm, quản lý phiên làm việc giữa hai ứng dụng: mở, duy trì và đóng phiên. "Data Link" là tầng thứ hai, truyền khung dữ liệu giữa hai thiết bị kề nhau trên cùng đường truyền, ví dụ Ethernet hay Wi-Fi, dùng địa chỉ MAC. "Physical" là tầng thứ nhất, lo tín hiệu điện, sóng vô tuyến hay ánh sáng trên dây cáp. Ba tầng này đều có thật trong OSI nên không phải câu trả lời cho câu hỏi phủ định này.
Mở trang câu hỏi này →
A103
B14
C7
D71
Lời giải
Đáp án đúng: "71". Bảng mã ASCII gán chữ hoa từ 65 cho A, 66 cho B, rồi tăng dần nên G là chữ thứ bảy có mã 65 + 6 = 71; kiểm tra bằng ord('G') trong Python cho 71, ngược lại chr(71) cho 'G'. "103" sai vì đó là mã của chữ thường g; chữ thường bắt đầu từ 97 cho a, cách chữ hoa tương ứng đúng 32. "7" sai vì đó chỉ là vị trí của G trong bảng chữ cái, không phải mã số; mã 7 trong ASCII là ký tự điều khiển chuông BEL. "14" sai vì mã 14 là ký tự điều khiển SO (Shift Out), không phải chữ in được; mọi ký tự từ 0 tới 31 đều là ký tự điều khiển.
Mở trang câu hỏi này →
31How do you read a file line by line?4 lựa chọn
Afile.read()
Bfor line in file:
Cfile.write()
Dfile.line()
Lời giải
Đáp án đúng: "for line in file:". Đối tượng tệp trong Python là một iterable (đối tượng lặp được): mỗi vòng lặp for lấy phần tử kế tiếp thì tệp trả về một dòng, kèm cả ký tự xuống dòng ở cuối, nên đây là cách chuẩn để đọc tệp lần lượt từng dòng; cách này đọc dần nên tiết kiệm bộ nhớ khi tệp rất lớn. "file.read()" đọc toàn bộ nội dung tệp thành một chuỗi duy nhất, không tách theo dòng; muốn có từng dòng phải gọi thêm splitlines hoặc dùng readlines. "file.write()" dùng để ghi dữ liệu vào tệp, ngược hẳn với việc đọc, và chỉ chạy khi tệp được mở ở chế độ 'w' hoặc 'a'. "file.line()" không phải phương thức của đối tượng tệp, gọi nó sẽ gây AttributeError; phương thức gần nghĩa có thật là readline(), mỗi lần gọi đọc đúng một dòng.
Mở trang câu hỏi này →
A{}
B()
C[]
DNone
Lời giải

Đáp án đúng: "[]". Cặp ngoặc vuông rỗng tạo một list (danh sách) rỗng, ví dụ friends = [], sau đó có thể thêm phần tử bằng friends.append('Joe'); cách viết tương đương là gọi hàm list(). Phương án "{}" tạo một dict (từ điển) rỗng chứ không phải list, và cũng không phải set rỗng, vì set rỗng phải viết set(). Phương án "()" tạo một tuple rỗng; tuple giống list ở chỗ giữ thứ tự phần tử nhưng là kiểu bất biến (immutable), không append được. Phương án "None" là giá trị đặc biệt biểu thị không có giá trị, thuộc kiểu NoneType; biến bằng None không phải list và gọi append trên nó sẽ ném AttributeError. Có thể tự kiểm bằng type([]), kết quả là lớp list.

Mở trang câu hỏi này →
Đề bài
import socket

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80))
cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\n\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())
mysock.close()
Amysock.recv()
Bsocket.socket()
Cmysock.close()
Dmysock.connect()
Emysock.send()
Lời giải
Đáp án đúng: "mysock.recv()". Lần theo mã: lời gọi recv(512) nhận tối đa 512 byte từ kết nối và trả về bytes, đó là chỗ dữ liệu thật sự được đọc; vòng while lặp lại cho tới khi recv trả về dữ liệu rỗng (độ dài nhỏ hơn 1), nghĩa là máy chủ đã đóng kết nối, và mỗi khối nhận được được decode rồi in ra. "socket.socket()" chỉ tạo đối tượng socket, với AF_INET là IPv4 và SOCK_STREAM là TCP, chưa kết nối hay đọc gì. "mysock.connect()" mở kết nối TCP tới data.pr4e.org ở cổng 80, mới là bước thiết lập đường truyền. "mysock.send()" gửi yêu cầu GET đã được mã hoá thành bytes tới máy chủ, là chiều đi chứ không phải đọc. "mysock.close()" đóng kết nối sau khi đã đọc xong, giải phóng tài nguyên.
Mở trang câu hỏi này →
A^
B?
C.
D*
E$
F+
Lời giải
Đáp án đúng: ".". Trong biểu thức chính quy (regular expression), dấu chấm là ký tự đại diện (wild card): nó khớp đúng một ký tự bất kỳ, trừ ký tự xuống dòng; ví dụ mẫu f.o khớp foo, fao hay f9o. Phương án "^" là ký tự neo khớp vị trí đầu dòng, không khớp ký tự nào. Phương án "?" là bộ lượng hoá (quantifier) cho phép phần đứng trước xuất hiện 0 hoặc 1 lần. Phương án "*" lặp phần đứng trước 0 lần trở lên; phải ghép dấu chấm với dấu sao mới thành mẫu khớp mọi chuỗi, còn bản thân dấu sao không khớp ký tự nào. Phương án "$" là ký tự neo khớp vị trí cuối dòng. Phương án "+" lặp phần đứng trước 1 lần trở lên, như [0-9]+ khớp một dãy chữ số. Muốn khớp dấu chấm thật phải thoát thành \. trong mẫu.
Mở trang câu hỏi này →
AModel each "object" in the application as one or more tables
BUse a person's email address as their primary key
CNever repeat string data in more than one table in a data model
DUse integers as primary keys
Lời giải
Đáp án đúng: "Use a person's email address as their primary key". Khoá chính nên là giá trị ổn định, gọn và không mang ý nghĩa nghiệp vụ; địa chỉ email thì người dùng có thể đổi, mà khi khoá chính đổi, mọi khoá ngoại trỏ tới nó ở các bảng khác cũng phải đổi theo. Email còn là chuỗi dài nên so sánh và đánh chỉ mục chậm hơn số nguyên. Cách đúng là dùng id số nguyên làm khoá chính và đặt email là cột UNIQUE để tra cứu. "Model each "object" in the application as one or more tables" là quy tắc tốt: mỗi đối tượng như người dùng, bài hát, album có bảng riêng. "Never repeat string data in more than one table in a data model" là nguyên tắc chuẩn hoá (normalization): chuỗi chỉ lưu một lần, nơi khác tham chiếu tới nó bằng số. "Use integers as primary keys" là quy tắc tốt vì số nguyên gọn, so sánh nhanh và có thể để SQLite tự tăng. Ba quy tắc này đều nên làm nên không được chọn.
Mở trang câu hỏi này →
AMAKE people;
BCREATE TABLE people;
CMAKE DATASET people;
DCREATE people;
Lời giải

Đáp án đúng: "CREATE TABLE people; ". Câu lệnh tạo bảng mới trong SQL bắt đầu bằng hai từ khoá CREATE TABLE rồi tới tên bảng; trong thực tế còn kèm danh sách cột trong ngoặc, ví dụ CREATE TABLE people (name TEXT, email TEXT), và SQLite đòi ít nhất một cột mới chịu chạy. Dù viết rút gọn, đây là lựa chọn duy nhất dùng đúng cặp từ khoá tạo bảng. Phương án "MAKE people;" sai vì SQL không có từ khoá MAKE. Phương án "MAKE DATASET people;" cũng không tồn tại; dataset chỉ là khái niệm chung về tập dữ liệu chứ không phải lệnh SQL. Phương án "CREATE people; " thiếu từ chỉ loại đối tượng: sau CREATE phải nói rõ tạo gì, như TABLE, INDEX hay VIEW, nên câu này lỗi cú pháp.

Mở trang câu hỏi này →
AINSERT INTO
BINSERT ROW
CADD ROW
DINSERT TABLE
Lời giải
Đáp án đúng: "INSERT INTO". Lệnh thêm dòng trong SQL có dạng INSERT INTO tên_bảng (cột1, cột2) VALUES (giá_trị1, giá_trị2); ví dụ INSERT INTO Users (name, email) VALUES ('Chuck', 'csev@umich.edu') thêm đúng một bản ghi mới vào bảng Users. Trong Python với sqlite3, ta gọi cur.execute với câu lệnh này kèm dấu hỏi làm chỗ giữ giá trị, rồi conn.commit() để ghi hẳn xuống tệp. "INSERT ROW" sai vì ROW không thuộc cú pháp; sau INSERT phải là INTO và tên bảng. "ADD ROW" không tồn tại trong SQL; ADD chỉ xuất hiện trong ALTER TABLE ... ADD COLUMN để thêm cột, không thêm dòng. "INSERT TABLE" cũng sai cú pháp: tạo bảng dùng CREATE TABLE, còn thêm dữ liệu phải qua INSERT INTO.
Mở trang câu hỏi này →
38What is the purpose of a primary key?4 lựa chọn
ATo look up a row based on a string that comes from outside the program
BTo look up a particular row in a table very quickly
CTo track the number of duplicate values in another column
DTo point to a particular row in another table
Lời giải
Đáp án đúng: "To look up a particular row in a table very quickly". Khoá chính (primary key), thường là cột id số nguyên tự tăng, định danh duy nhất mỗi dòng và được cơ sở dữ liệu lập chỉ mục, nên tìm đúng một dòng theo nó rất nhanh; các bảng khác cũng tham chiếu tới dòng qua giá trị này. "To look up a row based on a string that comes from outside the program" sai vì đó là vai trò của khoá logic (logical key), như cột email hay tên mà người dùng nhập vào để tìm, thường gắn UNIQUE. "To track the number of duplicate values in another column" sai vì khoá chính không đếm gì; đếm trùng làm bằng GROUP BY với COUNT. "To point to a particular row in another table" sai vì đó là định nghĩa khoá ngoại (foreign key), cột chứa giá trị khoá chính của bảng khác.
Mở trang câu hỏi này →
AFaster execution
BCatch connection and parsing errors
CWrite files faster
DAvoid memory issues
Lời giải
Đáp án đúng: "Catch connection and parsing errors". Khối try/except bắt ngoại lệ phát sinh trong khối try và chuyển sang xử lý ở except thay vì để chương trình dừng giữa chừng. Khi dùng urllib hoặc socket, mạng có thể lỗi (URLError, hết thời gian chờ, ConnectionRefusedError), và dữ liệu trả về có thể hỏng khiến json.loads ném JSONDecodeError hoặc ElementTree ném ParseError; đặt các lệnh đó trong try giúp chương trình báo lỗi gọn rồi bỏ qua hoặc thử lại. "Faster execution" sai vì try/except không tăng tốc; khi có ngoại lệ còn tốn thêm chi phí xử lý. "Write files faster" không liên quan, tốc độ ghi tệp do hệ điều hành và ổ đĩa quyết định. "Avoid memory issues" sai vì try/except không giải phóng bộ nhớ; bộ nhớ do bộ thu gom rác của Python quản lý, và muốn giảm bộ nhớ phải đọc dữ liệu theo từng phần.
Mở trang câu hỏi này →
ADELETE FROM Cats WHERE name = 'Ruby'
BDELETE name='Ruby' FROM Cats
CDELETE ROW name='Ruby' FROM Cats
DDELETE FROM Cats WHERE name == 'Ruby'
Lời giải
Đáp án đúng: "DELETE FROM Cats WHERE name = 'Ruby'". Cú pháp chuẩn của SQL để xoá dòng là DELETE FROM tên bảng rồi WHERE điều kiện; mệnh đề WHERE chọn mọi dòng thoả điều kiện, nên tất cả các dòng có tên Ruby đều bị xoá, còn nếu bỏ WHERE thì cả bảng bị xoá sạch. So sánh bằng trong SQL dùng một dấu bằng và chuỗi đặt trong nháy đơn. "DELETE name='Ruby' FROM Cats" sai cú pháp vì DELETE không nhận tên cột hay điều kiện đứng trước FROM. "DELETE ROW name='Ruby' FROM Cats" cũng sai: SQL không có từ khoá ROW trong lệnh DELETE, bản thân DELETE vốn đã thao tác trên dòng. "DELETE FROM Cats WHERE name == 'Ruby'" dùng toán tử so sánh quen thuộc của Python; SQLite tình cờ chấp nhận hai dấu bằng như một cách viết khác của một dấu bằng, nhưng đó không phải SQL chuẩn và MySQL hay PostgreSQL sẽ báo lỗi cú pháp, nên cách viết đúng chuẩn vẫn là một dấu bằng.
Mở trang câu hỏi này →