Tổng hợp 61 câu hỏi phỏng vấn Ruby kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
Ruby (Matz, 1995) là ngôn ngữ thông dịch, dynamic typing, thuần hướng đối tượng, theo triết lý "developer happiness" — code đọc gần như tiếng Anh. Khác biệt so với ngôn ngữ khác: - Mọi thứ đều là object — kể cả 5 hay nil…
String là mutable, mỗi lần tạo là 1 object mới trong heap. Symbol là immutable, mỗi tên symbol chỉ tồn tại 1 lần trong memory (interned). Dùng Symbol cho hash key, method name, trạng thái cố định (:pending, :active). Dùng String khi cần thao tác…
Objectfreeze làm object trở thành immutable — mọi thao tác sửa đổi đều raise FrozenError (Ruby ≥ 2.5) hoặc RuntimeError. Vì sao dùng: tránh sửa nhầm hằng số, dùng string làm hash key an toàn, tiết kiệm memory (Ruby có thể cache frozen string). String…
Biến instance (@): thuộc về từng object riêng, mỗi instance có bản sao riêng. Biến class (@@): chia sẻ giữa mọi instance của class và các subclass. Lưu ý: @@ được kế thừa xuống subclass — sửa ở subclass làm thay đổi class cha. Nhiều…
Visibility Gọi từ bên ngoài Gọi trong subclass Gọi trong cùng class ------------ public Có Có Có protected Không Có (instance cùng class/subclass) Có private Không Có (implicit receiver) Có (implicit receiver) protected thường dùng để so sánh giữa 2 instance cùng class (ví dụ…
"Nếu nó đi như vịt và kêu như vịt, thì nó là vịt." — Ruby không kiểm tra kiểu của object, chỉ quan tâm object có respond với method được gọi hay không. Tại sao mạnh: viết code generic không cần interface/abstract class; dễ test…
Block là một đoạn code ẩn danh truyền cho method, không phải object, không gán vào biến được. Viết bằng {} (1 dòng) hoặc do...end (nhiều dòng). Method gọi block bằng yield.
Cả hai đều là object Proc, khác ở 2 điểm then chốt: 1. Kiểm tra arity: - lambda: sai số arg → ArgumentError. - proc: thiếu → nil, thừa → bỏ qua. 2. Semantics của return: - lambda: return chỉ thoát khỏi lambda. - proc:…
Enumerable là module mixin — class nào implement each đều có thể include Enumerable để nhận ngay ~60 method: map, select, reject, inject, sortby, groupby, flatmap... Class nào implement each và include Enumerable sẽ có sẵn toàn bộ ~60 method này mà không phải viết…
Lazy enumerator trì hoãn tính toán cho đến khi giá trị thực sự cần — không tạo array trung gian. Hữu ích khi xử lý chuỗi vô hạn hoặc pipeline dài. Khi nào dùng: - Dãy vô hạn ((1..)). - Pipeline nhiều bước với filter…
Module là tập hợp method và constant — không thể khởi tạo, không thể kế thừa. Hai vai trò chính: 1. Namespace — tránh trùng tên: Payments::Invoice vs Mailer::Invoice. 2. Mixin — include vào class để chia sẻ method. Class Module --------- Khởi tạo new…
Cả 3 đều đưa module vào class, nhưng tác dụng lên method lookup chain khác nhau: Keyword Method thêm vào Gọi từ --------- include instance methods object instances extend class methods (singleton) class trực tiếp prepend instance methods (ưu tiên hơn class) object instances, override…
Comparable cho phép class định nghĩa thứ tự bằng cách implement duy nhất 1 method <= (spaceship operator), sau đó tự có luôn: <, <=, , =, between?, clamp, và cả sort. <= trả 0 nếu bằng, -1 nếu nhỏ hơn, 1 nếu lớn hơn.…
Ruby cho phép mở lại bất kỳ class nào — kể cả built-in như String, Integer — để thêm hoặc ghi đè method. Gọi là open class hay monkey patching. Ưu điểm: DSL ngắn gọn, tự nhiên (Rails dùng rộng rãi: 2.days.ago). Nhược điểm: ghi…
Metaprogramming là viết code sinh ra hoặc sửa đổi code khác lúc runtime — thay vì viết cứng từng method, ta dùng các công cụ của Ruby để tự động hoá. Ví dụ đơn giản nhất: attraccessor :name tự sinh getter + setter thay vì…
Khi gọi method không tồn tại, Ruby leo lên method lookup chain, không tìm thấy thì gọi methodmissing trên object đó. Lưu ý bắt buộc: 1. Luôn super trong nhánh không xử lý để Ruby vẫn raise NoMethodError như bình thường. 2. Luôn override respondtomissing?…
def là keyword — tên method phải là identifier tĩnh biết lúc viết code. definemethod là method nhận tên động (string/symbol), cho phép tạo method theo pattern lúc runtime. Khi dùng definemethod: - Sinh nhiều method theo pattern (tránh copy-paste). - Tên method đến từ…
Thứ tự thực thi: 1. begin — code có thể raise. 2. rescue — bắt exception theo loại, khớp từ trên xuống. 3. else — chạy nếu không có exception nào xảy ra. 4. ensure — luôn luôn chạy (đóng file, release connection). Lưu ý:…
Exception là gốc của toàn bộ cây: Tại sao không rescue Exception: nó bắt cả SystemExit và Interrupt — Ctrl+C bị nuốt, process không tắt được. Luôn dùng rescue StandardError (hoặc subclass cụ thể).
Kế thừa từ StandardError (hoặc subclass của nó) — không phải từ Exception gốc. Best practice: - Tên kết thúc bằng Error. - Kế thừa StandardError, không phải Exception. - Tạo 1 base error class cho mỗi library/module. - Thêm context data qua attrreader để…
raise ném exception. Có 3 dạng: retry khởi động lại begin block từ đầu — chỉ dùng được trong rescue: Lưu ý: retry không có giới hạn → vòng lặp vô tận; không reset state → lặp lỗi mãi; retry blind → che giấu bug…
RubyGems là package manager của Ruby — mỗi thư viện đóng gói thành một gem. CLI: gem install <name. Bundler quản lý dependency của project: lock phiên bản cụ thể vào Gemfile.lock, đảm bảo mọi môi trường (dev/staging/prod) dùng đúng version. bundle install cài gems…
Toán tử So sánh Dùng khi --------- == giá trị (thường được override) so sánh tổng quát eql? giá trị và cùng class (dùng cho hash key) 1.eql?(1.0) → false equal? object identity — cùng objectid kiểm tra cùng object === "case equality" — mỗi…
Ruby object mặc định mutable (có thể sửa sau khi tạo). Trừ: - Integer, Float, Symbol — immutable theo thiết kế ngôn ngữ (không có setter). - Bất kỳ object nào đã freeze. - String literal khi bật frozenstringliteral: true (mặc định của Rubocop). Hình…
each map / collect --------- Return object gốc (self) array mới chứa kết quả Mục đích side-effect (in, ghi file...) biến đổi, tạo dữ liệu mới Quy tắc: Nếu không dùng giá trị trả về → each. Nếu cần array mới → map. map! biến…
Ba macro này tự động sinh getter/setter cho instance variable: Macro Sinh ra Dùng khi --------- attrreader :x def x = @x chỉ đọc attrwriter :x def x=(v); @x=v; end chỉ ghi attraccessor :x cả hai đọc + ghi Đây là ví dụ metaprogramming cơ…
Khi gọi method, Ruby tìm theo thứ tự: object eigenclass → class → prepended modules (LIFO) → included modules (LIFO) → superclass và cứ thế leo lên đến BasicObject. prepend chèn module trước class trong chain, include chèn sau class (trước superclass). Hình dung: ancestors…
- classeval (alias moduleeval): chạy block trong ngữ cảnh class — method định nghĩa trong đó là instance method của class đó. - instanceeval: chạy block trong ngữ cảnh object cụ thể — method định nghĩa là singleton method của object đó. Dùng classeval khi…
raise/rescue là cơ chế exception handling — dùng khi có lỗi thật. throw/catch là cơ chế control flow — dùng để thoát khỏi vòng lặp lồng nhau mà không có lỗi gì. throw không phải exception — nó không tạo stack trace, không chậm như…
Bundler dùng pessimistic constraint operator ~ (twiddle-wakka) để cân bằng giữa nhận patch/minor mới và tránh breaking change: Ràng buộc Nghĩa Khoảng hợp lệ --------- "~ 2.1" = 2.1, < 3.0 nhận 2.x mới "~ 2.1.0" = 2.1.0, < 2.2.0 chỉ nhận patch 2.1.x "=…
MRI Ruby (CRuby) có GIL (còn gọi GVL — Global VM Lock): chỉ 1 thread được thực thi Ruby bytecode tại một thời điểm, ngay cả trên multi-core CPU. Lý do tồn tại: đơn giản hoá garbage collector và C extension — không cần lock…
Method Trả true khi Lưu ý --------- nil? chỉ khi object là nil có trên mọi object (kế thừa Object) empty? string/array/hash có độ dài = 0 nil.empty? → NoMethodError blank? nil, false, empty?, hoặc chỉ khoảng trắng chỉ có trong Rails (ActiveSupport) Quy tắc…
load require requirerelative ------------ Đường dẫn Phải có đuôi .rb Không cần đuôi Không cần đuôi Caching Không — load lại mỗi lần Có — chỉ load 1 lần Có — chỉ load 1 lần Đường dẫn gốc $LOADPATH $LOADPATH Tương đối so với file…
&. (lonely operator / safe navigation, Ruby 2.3+) gọi method chỉ khi receiver không phải nil — nếu nil thì trả về nil thay vì raise NoMethodError. Khác .try (Rails): - &. là Ruby core — vẫn raise NoMethodError nếu method không tồn tại trên…
& trước một object sẽ gọi toproc trên nó rồi truyền kết quả như một block. Symbol implement toproc để tạo block gọi method cùng tên trên mỗi phần tử. Khi dùng &method(:name): khi muốn pass một method (không phải method của element) vào iterator…
Cả hai đều yield self vào block, nhưng return value khác: Method Return Dùng khi --------- tap self (object gốc) debug, side-effect giữa chain then / yieldself giá trị block trả về transform, tích hợp non-chainable func vào pipeline yieldself là tên gốc (Ruby 2.5),…
Cả hai đều gọi method cùng tên ở superclass, nhưng khác nhau về argument: super super() --------- Argument truyền lên Tự động forward tất cả arg của method hiện tại Gọi superclass method không có argument Lưu ý: dùng super không tường minh khi signature…
Cả hai tạo shallow copy của object — instance variable được sao chép theo tham chiếu (nested object vẫn là cùng 1 object). Điểm khác biệt: dup clone --------- Giữ frozen state Không — luôn tạo object mutable Có — copy vẫn frozen nếu original…
alias aliasmethod --------- Loại Keyword (cú pháp ngôn ngữ) Method của Module Cú pháp alias newname oldname (không dấu phẩy, chỉ symbol/bare word) aliasmethod :newname, :oldname (symbol/string, dấu phẩy) Tên động Không hỗ trợ Có — nhận biến/expression Kế thừa Alias được resolve tại thời…
respondto?(methodname) — kiểm tra object có thể respond với method đó không (duck typing). Trả false với private method mặc định, trừ khi truyền true làm arg thứ 2. isa?(klass) / kindof?(klass) — kiểm tra object thuộc class/module đó không (type checking). Cả hai là…
Method chaining là kỹ thuật gọi nhiều method liên tiếp trên cùng một object bằng cách mỗi method trả về self. ActiveRecord, Arel và hầu hết Ruby DSL đều dùng pattern này.
Ruby có module Singleton trong stdlib — include nó để tạo class chỉ có đúng 1 instance, thread-safe: Singleton module dùng Mutex nội bộ để đảm bảo instance chỉ được tạo 1 lần dù nhiều thread cùng gọi lần đầu. Ứng dụng: config object, connection…
Marshal là module serialization built-in của Ruby — chuyển đổi object thành binary string (dump) và khôi phục lại (load). Hoàn toàn Ruby-specific, không portable qua ngôn ngữ khác. Khi dùng: cache phức tạp (Rails session store mặc định là Marshal), queue serialization (Sidekiq với…
Enumerator.new nhận một block với yielder — gọi yielder << value (hoặc yielder.yield value) để emit từng giá trị. Giá trị chỉ được tính khi caller yêu cầu (lazy-compatible). enumfor(:methodname) (alias toenum) là cách tiêu chuẩn cho method each trả về Enumerator khi không có…
Railway-Oriented Programming (ROP) áp dụng Result pattern — mỗi bước trả về success hoặc failure, chain chỉ tiếp tục khi success. Cách đơn giản nhất trong Ruby là dùng gem dry-monads hoặc tự implement với Struct: Gem dry-rb (dry-monads, dry-validation) cung cấp full ROP/monad cho…
yield gọi block ẩn mà method nhận được; &block chuyển block thành một object Proc để có thể lưu, truyền tiếp hoặc kiểm tra. Khác biệt cần biết: - yield không cấp phát object; &block tạo một Proc mỗi lần gọi method → chậm hơn…