- Ruby là gì? Điểm nổi bật so với các ngôn ngữ khác?
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…
- Symbol và String trong Ruby khác nhau thế nào?
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…
- `freeze` trong Ruby dùng để làm gì?
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 (`@`) và biến class (`@@`) trong Ruby khác nhau thế nào?
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…
- Public, private, protected trong Ruby khác nhau thế nào?
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ụ…
- Duck typing trong Ruby là gì? Tại sao đây là điểm mạnh của ngôn ngữ?
"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 trong Ruby là gì? `yield` dùng thế nào?
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.
- Phân biệt `proc` và `lambda` trong Ruby?
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 module trong Ruby cung cấp những gì? Cho ví dụ `map`, `select`, `inject`.
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 trong Ruby là gì? Khi nào nên dùng?
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…
- Giải thích Closure trong Ruby. Block có phải closure không?
- Module trong Ruby là gì? Khác class ở điểm nào?
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…
- `include`, `extend`, và `prepend` trong Ruby khác nhau thế nào?
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 module trong Ruby dùng để làm gì?
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.…
- Open class (Monkey Patching) trong Ruby là gì? Ưu và nhược điểm?
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…
- Singleton method trong Ruby là gì? `self.` và eigenclass liên quan thế nào?
- Metaprogramming trong Ruby là gì? Cho ví dụ thực tế.
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ì…
- `method_missing` trong Ruby hoạt động thế nào? Cần lưu ý gì?
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?…
- `define_method` khác gì `def` thông thường? Khi nào dùng `define_method`?
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ừ…
- Hook methods trong Ruby là gì? Nêu ví dụ `inherited`, `included`, `extended`.
- `send` và `public_send` trong Ruby khác nhau thế nào? Khi nào nên dùng?
- Cấu trúc xử lý exception trong Ruby như thế nào? `begin/rescue/ensure` hoạt động ra sao?
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 ý:…
- Cây phân cấp Exception trong Ruby như thế nào? Tại sao không nên `rescue Exception`?
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ể).
- Cách tạo custom exception trong Ruby? Best practice là gì?
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` và `retry` trong Ruby dùng thế nào? Cần lưu ý gì khi dùng `retry`?
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 và Bundler là gì? `Gemfile` dùng thế nào?
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…
- Garbage Collection trong Ruby hoạt động thế nào? Generational GC là gì?
- Bốn toán tử so sánh bằng trong Ruby (`==`, `eql?`, `equal?`, `===`) khác nhau thế nào?
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…
- Mutable và immutable trong Ruby: những type nào mặc định immutable?
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` và `map` khác nhau thế nào trong Ruby? Khi nào dùng cái nào?
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…
- Fiber trong Ruby là gì? Khác Thread thế nào?
- `attr_accessor`, `attr_reader`, `attr_writer` trong Ruby là gì?
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ơ…
- Method lookup chain (MRO) trong Ruby hoạt động thế nào khi có module mixin?
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…
- Struct trong Ruby là gì? Khi nào nên dùng Struct thay vì class?
- `class_eval` và `instance_eval` trong Ruby dùng để làm gì?
- 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…
- `throw`/`catch` trong Ruby khác gì `raise`/`rescue`?
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ư…
- Semantic versioning trong Gemfile: `~>`, `>=`, `=` khác nhau thế nào?
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 "=…
- Tại sao Ruby có GIL (Global Interpreter Lock)? Ảnh hưởng thế nào đến concurrency?
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…
- ObjectSpace trong Ruby là gì? Dùng để làm gì trong thực tế?
- Pattern matching trong Ruby (Ruby 3.0+) là gì? Cho ví dụ `in` và `case/in`.
- `nil?`, `empty?` và `blank?` trong Ruby khác nhau thế nào?
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` và `require_relative` trong Ruby khác nhau thế nào?
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…
- Safe navigation operator `&.` trong Ruby là gì? Khác gì so với `.try`?
&. (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…
- Symbol#to_proc và `&` operator hoạt động thế nào? Khi nào dùng `&method(:name)`?
& 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…
- `tap` và `then`/`yield_self` trong Ruby dùng để làm gì? Khác nhau thế nào?
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),…
- `super` và `super()` trong Ruby khác nhau thế nào?
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…
- `dup` và `clone` trong Ruby khác nhau thế nào?
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` và `alias_method` trong Ruby khác nhau thế nào?
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…
- Refinement trong Ruby là gì? Khác Monkey Patching thế nào?
- `respond_to?` và `is_a?` / `kind_of?` trong Ruby dùng để làm gì? Khi nào dùng cái nào?
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 trong Ruby là gì? Cách implement một chainable API?
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.
- Thread-safe Singleton pattern trong Ruby implement thế nào?
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 trong Ruby là gì? Khi nào dùng và khi nào không nên dùng?
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…
- Cách implement một custom Enumerator trong Ruby? `Enumerator.new` dùng thế nào?
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ó…
- Ractor trong Ruby (3.0+) là gì? Giải quyết vấn đề gì mà Thread không làm được?
- `frozen_string_literal: true` magic comment trong Ruby là gì? Ảnh hưởng thế nào đến performance?
- Làm thế nào để implement method chaining với exception handling an toàn trong Ruby (Railway-Oriented Programming)?
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…
- `Data.define` trong Ruby 3.2 là gì? Khác Struct ở điểm nào?
- `yield` và nhận block tường minh bằng `&block` khác nhau thế nào? Khi nào dùng cái nào?
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…
- Puma nên cấu hình bao nhiêu worker và bao nhiêu thread? GVL ảnh hưởng thế nào tới quyết định đó?
- Process Puma/Sidekiq tăng RAM dần rồi không tụt lại. Đây có phải memory leak không? Xử lý thế nào?