As entrevistas de Ruby seguem duas camadas: a própria linguagem — blocks, módulos, a cadeia de busca de métodos — e depois o Rails, onde a maioria das perguntas na verdade é sobre Active Record e o banco de dados por trás dele. Aqui estão as perguntas mais frequentes, cada uma com uma resposta modelo.
Cada pergunta vem com uma resposta modelo para você comparar com a sua.
1
O que é truthy e falsy em Ruby?
Resposta
Apenas nil e false são falsy. Tudo o resto é truthy — incluindo 0, uma string vazia e um array vazio, que é onde tropeçam os desenvolvedores vindos de outras linguagens. Por isso if items.empty? e if items significam coisas completamente diferentes, e a segunda quase nunca é o que você queria.
2
Qual é a diferença entre um symbol e uma string?
Resposta
Uma string é um objeto mutável e cada literal cria uma nova; um symbol é imutável e o mesmo symbol é sempre o mesmo objeto. Isso torna os symbols a escolha certa para identificadores — chaves de hash, nomes de métodos, estados — porque não são recriados a cada uso. Strings são para dados que você exibe ou modifica.
3
O que é um block, e o que `yield` faz?
Resposta
Um block é um trecho de código passado para um método, escrito com do...end ou chaves. yield o chama de dentro do método, e block_given? verifica se um foi passado. Blocks são o motivo pelo qual o código Ruby se lê como se lê — each, map, open e os wrappers de transação são todos métodos que recebem um block e controlam o que acontece ao redor dele.
4
Qual é a diferença entre um proc e uma lambda?
Resposta
Duas diferenças que importam. Uma lambda verifica a aridade e falha se o número de argumentos estiver errado; um proc silenciosamente preenche o resto com nil. E return dentro de uma lambda retorna da própria lambda, enquanto dentro de um proc retorna do método que o contém — é assim que um proc pode encerrar um método sem que você espere.
5
Qual é a diferença entre `include`, `extend` e `prepend`?
Resposta
include adiciona os métodos de um módulo como métodos de instância, extend os adiciona como métodos singleton naquele objeto — então usar extend no corpo de uma classe dá métodos de classe. prepend insere o módulo *antes* da classe na cadeia de busca, então o método do módulo prevalece e pode chamar super para chegar ao original. Verificar ancestors mostra exatamente o que aconteceu.
6
O que é o problema N+1 e como resolvê-lo?
Resposta
Uma consulta carrega uma lista, e então acessar uma associação dentro do loop dispara mais uma consulta por linha — 1 + N. A solução é carregar a associação com antecedência usando includes. preload sempre usa uma consulta separada, eager_load força um único LEFT JOIN, e includes escolhe entre os dois dependendo se você filtra pela associação. A gem bullet sinaliza isso em desenvolvimento.
7
Quando o Active Record realmente executa a consulta?
Resposta
Não ao construir a relation. User.where(active: true) devolve uma relation e não toca em nada; a consulta roda quando você precisa dos dados — each, to_a, first, count, ou uma view que os renderiza. Essa preguiça é o que permite encadear scopes, e também explica por que um where que parece lento costuma ser inocente e o custo real está mais adiante na cadeia.
8
Qual é a diferença entre uma validação e uma restrição de banco de dados?
Resposta
Uma validação vive no model e roda em Ruby; uma restrição vive no banco e vale para qualquer um que escreva. Validações dão erros amigáveis por campo, mas são ignoradas por update_column, insert_all, outra aplicação, e perdem numa corrida entre dois requests simultâneos. Unicidade em particular precisa de um índice único — a validação sozinha é uma checagem, não uma garantia.
9
O que são callbacks e por que têm má fama?
Resposta
Hooks disparados ao redor do ciclo de vida de um model — before_save, after_create e o resto. Ganham má fama quando acumulam efeitos colaterais: criar um registro o salva, isso dispara um e-mail, que enfileira um job, e um teste que só queria um registro agora precisa de um stub de e-mail. Qualquer coisa que não seja sobre o próprio estado do registro fica melhor como uma chamada explícita em um service object.
10
O que é o Bundler, e para que serve o `Gemfile.lock`?
Resposta
O Bundler resolve as versões de gems que satisfazem seu Gemfile e as instala. O Gemfile.lock registra exatamente o que foi resolvido, por isso é versionado: bundle install em outra máquina reproduz as mesmas versões em vez de pegar as mais recentes. bundle update é o ato deliberado de atualizá-las.