Every now and then, I stumble upon some post that raises interesting questions worth to be answered or commented upon, hence the *"My Answers to..." series.*
This one in particular is worth the name since they're explicitly relating to interview questions, which were formulated in a very interesting blog post follow-up by Sohan back in 2010.
1. What is Rack
Rack is a web server interface for Ruby frameworks. It provides a common interface and middleware to provide a common HTTP-to-application-server communication layer regardless of the backend server implementation. It's a very minimal interface, specifying that a Rack application is any Ruby object responding to a
#call method, this method gets passed an environment (ENV) of HTTP-specific data coming from the web server in the form of a Hash-like interface, and it expects the method to return a server status code, headers, and response body.
Despite the fact of some implementation issues (like invoking
call..., a problem which Aaron Patterson has described in the past), the simple interface was a welcomed addition to the world of Ruby web development, as you can expect your Rack applications to run on the majority of Ruby web application servers untouched.
Through this minimal interface Rack ensures a protocol between web and application servers, releasing the latter from having to deal with straight HTTP "semantics" as it provides enough information for the request/response lifecycle. One of the main benefits of Rack is its stacked middleware approach, which are like interceptors that get before, between or after a request/response, manipulate or inspect it, totally transparent from the application code.
Examples of Rack-compatible application servers are wide, and the most common examples are Thin, Unicorn, Passenger and Puma. Examples of useful middleware are JSONP, Profiler, Cache, and of course the ones that Rails applications include by default.
2. Sketch out a deployment architecture of a Ruby on Rails application utilizing multiple servers.
3. How can you secure a rails application to counter for Session Fixation?
Ensure to reset the session ID on every successful login attempt, as a result the attacker won't be able to use a fixed session ID after the user logs in since the server will issue a new session ID for every single valid login, effectively replacing the old one. It's strictly necessary as well to analyze and purge Cross Site Scripting (XSS) vulnerabilities from the application, as this effectively removes the exploitation vector entirely as the attacker won't be able to inject the session ID replacement into the user's browser. Both counter-measures are not exclusive and need to be implemented on any Rails application.
4. Where can I get the core rails framework source code?
From the GitHub repository at https://github.com/rails/rails. In the interest of contributing to Rails source the best way to get started appears to be populating a Vagrant virtual machine made specifically for Rails development, which can be found at https://github.com/rails/rails-dev-box.
5. How can you reuse the models from one rails project into another?
There are many ways and patterns to get this accomplished. Since we're talking about a Rails project, the particular way of doing it in Rails which doesn't relate to other patterns is through the use of Rails Engines, where you can reuse models, views and controllers across different apps.
6. Explain one plugin that you extracted out of your source code.
I haven't extracted any plugins to date.
7. What is the difference between pre-initializers and initializers?
I have never had the need to use a so-called pre-initializer. However, in my understanding the pre-initializer code (which is any code you place at
RAILS_ROOT/config/preinitializer.rb) would be executed before any of the Rails components get loaded (such as ActionPack, ActiveRecord, etc). Initializers on the other hand, run their code after the framework and any plugins or gems your application uses gets loaded, there can be multiple of them, and they're stored under the
8. How can you easily switch your logger to use Log4r?
I don't remember how to use this, but as with any configurable part of Rails, you would create or copy your Log4r configuration into your Rails project (in case it requires one), then switch the logger in your application config (after you've required the specific Ruby libraries),
config.logger being the variable that needs to be touched.
9. How would you design the logging standard for your rails application?
Through well-established conventions, log tagging, and instrumentation-based logging.
10. How can you implement asynchronous messaging in Rails?
Most-likely through the use of a message queue such a RabbitMQ.
11. What will you do to look for a possible memory leak in Rails application?
This is not an exact science, you need to graph, map, get usage stats, isolate, and scope. Oink is a tool that can help you to log memory-related usage patterns to your production log. NewRelic has tools to display memory usage. The operating system itself would provide some great low-level tools such as
12. How can you run a profiler?
mini-profiler, is a Rack middleware that shows you response time as well as some inner processing times within the Rails stack. Now, in the real world I use NewRelic. You can also go the
ruby-prof way, patch your Ruby version for Garbage Collection statistics,
perftools.rb or my recently preferred way a mixture which starts with
13. What is lambda?
A lambda is a closure, it's a specified block of code that gets defined inline and preserves the surrounding scope of where it was defined.
14. What is Proc? When did you use this?
A proc is something like a lambda which is a little bit looser. Procs are close to blocks where lambdas are close to methods. Both are Ruby blocks of code which retain the enclosing scope, and despite a few differences when it comes to argument checking and what happens when you return from such of block they're pretty much the same. I've learned by force to always use
#call on such blocks. In Ruby-code the question would be "where don't you use them".
15. How can you use before and after callbacks of your rails methods to halt a database insert/update/delete?
If my understanding is correct major ORMs in Rails are using
ActiveModel::Callbacks behavior which defines that every callback method which returns false would halt the execution of any other callbacks scheduled to run later, so effectively if you return false on a
before_destroy would prevent the operation. I also think if the method code raises an exception it will have the same effect.
16. How can you reuse your before and after callback methods across multiple models?
You would extract them to a module which either defines the methods to be run on callbacks, or registers the callbacks itself after inclusion (such as when using
17. Define an architecture to store files uploaded to an application so that they are only accessible to valid users.
I'm not sure about an architecture, but the trick here is to never put the files on public-accessible locations (such as the public directory inside your Rails application), instead you put them in some private location outside of your web server's root, then make a controller which would run any kind of validation as filters (actions in Rails 4 parlance), and if all succeed then will serve the file directly through the use of the
18. How would you change your asset storage to use a static server?
If the question is how to serve the static files within Rails (which is off by default on production, obviously, as no application server should serve static files by itself, and most are not designed for that), you would set
config.serve_static_assets = true in your application config. If you're using a cookie-less domain or a CDN and you want to specify where your assets are served from (so you can properly link using the Rails URL helpers) then you would set config.asset_host in your application configuration to the address of your server.
19. Explain one situation when you used rails caching.
You should be using Russian-Doll caching everywhere when it doesn't introduces more problems than speed.
20. What kinds of caching comes in-built with Rails?
Since Rails 4, only fragment caching. Action caching (per controller action but allowing filters) and Page caching (skips the Rails stack entirely) are available through separate gems.
21. Can you explain the use of 'dynamic' features of Ruby on the core Rails framework?
Rails is a framework built because of the dynamic features of Ruby, so I don't even know where to start. I think the most fundamental one is that through the use of blocks, and clever meta-programming (such as defining dynamic finders, or invoking a list of callbacks, or avoiding similar method definitions), and the everywhere-openess of Ruby, have allowed them to built a web domain specific language that just feels right.
22. How can you call a SOAP web service from a rails application?
I have no idea. I used to do that on Java, not anymore, soap4r I suppose.
23. Your application needs to send a lot of email notifications. How would you design the notification so that the end user doesn't get stuck for email sending delays?
You out-band it, which basically means you move it out of the request/response lifecycle by using some sort of background processor or messaging solution.
24. What is a mongrel cluster?
I honestly don't remember. I feel something in the stone age of when Rack wasn't along and Ruby app servers were starting that would allow you to run multiple instances of your application through different process. Most app servers today support this forking model and can let you run as many "workers" (instances of your application) as you configure them to, the only exception I can remember now might be Puma on threading mode.
25. Can you explain if the clusters share a same memory? Can one cluster handle a request from a client that was handled by another?
I don't think so.
26. How would you internationalize your application interface?
Through the use of the i18n library bundled with Rails (or an alternative), and the use of helpers in views, model translations and of course locale files.
27. How can you create a rails generator?
rails g generator <generator_name>, if you want to use a generator to build a generator .
28. Have you ever used a polymorphic association?
Yes, who hasn't had a
Commentable in their lifetime?
29. How can you define a plugin that adds a new class method to
ActiveRecord::Base to include your module, most likely one that includes
ActiveSupport::Concern and has a nested
ClassMethods module which is the one that defines the class method in question.
30. What are the three most significant changes in Rails 3 in your eyes?
Rails 3 is old-school, I'll talk about Rails 4: Strong parameters instead of mass-assignment,
ActionController::Live and streaming, concerns, but my favorite is Russian-Doll Caching.
31. How can you implement complex reporting using ruby on rails?
For starters, you should be pre-computing on the fly and doing a lot of caching, and definitely not doing the report at the web layer. However, apparently the preferred way in the SQL world would be employing what's called "views", some of which you can map to models. In the NoSQL world (my favorite BTW) you'll most-likely do various kind of map-reduce operations to get the desired results.