Ruby Logo

Ruby Implementations Quiz

Test your knowledge of Ruby implementations including MRI, JRuby, TruffleRuby, and native integration techniques.

Home Ruby Ruby Implementations Quiz

Ruby Implementations Quiz

Test your knowledge of Ruby implementations including MRI, JRuby, TruffleRuby, and native integration techniques.

Quiz Instructions

  • Choose the best answer for each question
  • Click "Show Answer" to reveal the correct answer and explanation
  • Try to answer before looking at the solution
  • Each question focuses on practical implementation knowledge

Question 1: Global Interpreter Lock

Which statement about MRI's Global Interpreter Lock (GIL) is correct?

Show Answer

Answer: B) The GIL is released during I/O operations, allowing I/O concurrency

Explanation: While the GIL prevents true parallel execution of Ruby code across threads, it is released during I/O operations (file reads, network requests, etc.). This allows Ruby threads to achieve concurrency for I/O-bound operations, making MRI well-suited for web applications and other I/O-heavy workloads.

Question 2: JRuby Advantages

What is the primary advantage of JRuby over MRI for CPU-intensive applications?

Show Answer

Answer: B) No Global Interpreter Lock, enabling true parallel threading

Explanation: JRuby's biggest advantage for CPU-intensive applications is the absence of a Global Interpreter Lock. This allows multiple threads to execute Ruby code in parallel, potentially providing significant performance improvements for multi-threaded, CPU-bound workloads. However, this also means you need to be more careful about thread safety.

Question 3: TruffleRuby Characteristics

Which statement best describes TruffleRuby's performance characteristics?

Show Answer

Answer: C) Slow startup but can achieve exceptional peak performance after warmup

Explanation: TruffleRuby is designed for peak performance rather than quick startup. It requires a significant warmup period (often 30+ seconds) for the GraalVM JIT compiler to analyze and optimize the code. However, once warmed up, it can be 10-100x faster than MRI for optimizable code, making it ideal for long-running applications.

Question 4: Code Example

Consider this CPU-intensive Ruby code:

def fibonacci(n)
  return n if n <= 1
  fibonacci(n - 1) + fibonacci(n - 2)
end

threads = []
4.times do
  threads << Thread.new { fibonacci(35) }
end
threads.each(&:join)

Which Ruby implementation would likely show the best performance improvement compared to running the same code sequentially?

Show Answer

Answer: B) JRuby

Explanation: This is a CPU-intensive, pure computation task that can benefit from parallel execution. JRuby would show the best improvement because it has no GIL and can truly run the four threads in parallel. MRI would be limited by the GIL, while TruffleRuby, despite its eventual speed, would need significant warmup time and the parallel execution benefit might not outweigh the startup cost for this short-running example.

Question 5: FFI vs C Extensions

When would you choose FFI over writing a C extension?

Show Answer

Answer: B) When you need cross-Ruby implementation compatibility

Explanation: FFI's main advantage is portability across Ruby implementations (MRI, JRuby, TruffleRuby, etc.). C extensions are typically MRI-specific and need to be rewritten for other implementations. FFI also provides better safety, easier development (no compilation step), and automatic memory management, though at the cost of some performance compared to direct C extensions.

Question 6: C Extension Memory Management

In a C extension, what's the correct way to ensure Ruby objects are not garbage collected while being used in C code?

typedef struct {
    VALUE ruby_object;
    int some_data;
} my_struct_t;
Show Answer

Answer: B) Call rb_gc_mark() on the ruby_object in a mark function

Explanation: When storing Ruby objects in C structures, you must provide a mark function that calls rb_gc_mark() on any Ruby VALUE fields. This tells the garbage collector that these objects are still referenced and should not be collected. The mark function is registered when defining the data type and is called during garbage collection cycles.

Question 7: TruffleRuby Native Images

What is the main benefit of compiling a TruffleRuby application to a native image?

Show Answer

Answer: B) Instant startup time and lower memory usage

Explanation: Native images trade peak performance for instant startup and lower memory usage. They eliminate JVM startup overhead and the warmup period, making them ideal for serverless functions, CLI tools, and containerized applications where fast startup is more important than peak performance. However, they can't perform runtime JIT optimization.

Question 8: Implementation Selection

You're building a Ruby-based data processing service that needs to:

  • Process large datasets with heavy mathematical computations
  • Run continuously for hours
  • Use multiple CPU cores effectively
  • Integrate with existing Java infrastructure

Which Ruby implementation would be the best choice?

Show Answer

Answer: B) JRuby for true threading and Java integration

Explanation: JRuby is the best choice here because it provides: 1) True multi-threading without GIL limitations, allowing effective use of multiple CPU cores, 2) Seamless integration with existing Java infrastructure, 3) Good performance for long-running processes due to JVM optimizations, and 4) Access to Java's excellent mathematical and data processing libraries. While TruffleRuby might achieve higher peak performance, the Java integration requirement makes JRuby the practical choice.

Question 9: FFI Memory Safety

Which FFI code pattern is the safest for memory management?

Show Answer

Answer: B) Block-based automatic cleanup

Explanation: Block-based allocation with FFI::MemoryPointer ensures automatic cleanup when the block exits, even if an exception occurs. This pattern prevents memory leaks and is exception-safe. Manual allocation (A) is error-prone and can leak memory if exceptions occur. Global storage (C) can lead to memory leaks and makes cleanup timing unclear. Relying on GC (D) is unreliable because GC timing is unpredictable.

Question 10: Performance Trade-offs

Which statement best describes the performance trade-offs between Ruby implementations?

Show Answer

Answer: B) MRI has the best startup time while TruffleRuby has the best peak performance

Explanation: This correctly captures the fundamental trade-off: MRI starts quickly and is immediately productive, making it ideal for short-lived scripts and development. TruffleRuby requires significant warmup time but can achieve exceptional performance for long-running, computation-heavy applications. JRuby falls in between, with moderate startup time but good steady-state performance and the advantage of true threading. The best choice depends on your specific use case and performance requirements.

Quiz Complete! 🎉

Great job working through the Ruby implementations quiz! You've covered:

Core Concepts:

  • MRI's Global Interpreter Lock
  • JRuby's true multi-threading
  • TruffleRuby's performance characteristics
  • Native image compilation

Native Integration:

  • C extensions vs FFI trade-offs
  • Memory management best practices
  • Cross-platform compatibility
  • Performance considerations

💡 Key Takeaway: The best Ruby implementation depends on your specific needs. Consider startup time, peak performance requirements, threading needs, ecosystem compatibility, and deployment constraints when making your choice.

Quick Navigation

Related Topics

Video Tutorial

Watch and learn ruby implementations quiz

Pro Tip: After reading through the content above, watch this video to reinforce your understanding and see the concepts in action!