Skip to content

Вопросы на собеседовании: Ruby-разработчик

100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior Ruby-разработчик.

Смотреть пример резюме: Ruby-разработчик

Тренировка флешкарточками

Интервальное повторение · Hunter Pass

Вопросы

ruby

В Ruby каждое значение является объектом, а поведение вызывается через методы.

  • 7.class возвращает Integer, а "ruby".class возвращает String.
  • Даже операторы являются методами, поэтому 2 + 3 эквивалентно 2.+(3).
  • Классы тоже являются объектами, поэтому User.new отправляет метод new объекту User.

Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы единую объектную модель Ruby, а не считаете числа или классы особыми случаями.

ruby

Ruby определяет тип объекта во время выполнения, а переменные не имеют фиксированного объявленного типа.

  • value может сначала ссылаться на 10, а затем на "ten" без объявления.
  • Код может принимать любой объект с методом each вместо проверки точного класса.
  • Вызов 10.upcase приводит к NoMethodError во время выполнения, поэтому важны тесты и понятные интерфейсы.

Зачем это спрашивают: Интервьюер проверяет, можете ли вы объяснить и гибкость, и риск ошибок во время выполнения в системе типов Ruby.

ruby

В Ruby ложными считаются только false и nil, а любой другой объект является истинным.

  • 0, пустой String и пустой Array попадают в истинную ветку if.
  • if users.any? проверяет наличие элементов, а if users только проверяет nil или false.
  • value || "default" заменяет и nil, и false, поэтому используйте value.nil?, если false имеет смысл.

Зачем это спрашивают: Этот вопрос показывает, не переносит ли кандидат в Ruby неверные представления об истинности из других языков.

ruby

Ruby использует префиксы имён, чтобы различать область видимости и принадлежность.

  • name является локальной, @name принадлежит одному объекту, а @@count разделяется иерархией классов.
  • $stdout является глобальной переменной, а Billing::MAX_RETRIES является константой в пространстве имён.
  • Повторное присваивание константе выдаёт предупреждение, но выполняется, а объект по ссылке остаётся изменяемым без freeze.

Зачем это спрашивают: Сильный ответ различает принадлежность переменных и учитывает, что константы не становятся автоматически неизменяемыми.

ruby

Метод Ruby возвращает последнее вычисленное выражение, если явно не использован return.

  • def double(n); n * 2; end возвращает 8 для double(4).
  • Явный return подходит для раннего выхода, например return nil if user.nil?.
  • Вопросительный знак в active? является соглашением для предикатов, а не особым синтаксисом возврата.

Зачем это спрашивают: Интервьюер проверяет базовую семантику методов и уместное применение явного return.

ruby

Методы Ruby могут сочетать позиционные аргументы, значения по умолчанию и явные именованные аргументы.

  • def greet(name, loud = false) имеет один обязательный и один необязательный позиционный аргумент.
  • def create(name:, role: "member") требует name: и задаёт role: по умолчанию.
  • create(name: "Ira") понятно читается в месте вызова, а отсутствие обязательного ключа приводит к ArgumentError.

Зачем это спрашивают: Сильный ответ показывает актуальный синтаксис именованных аргументов Ruby и ошибку при неверном вызове.

args-kwargs

*args собирает дополнительные позиционные аргументы в Array, а **kwargs собирает именованные аргументы в Hash.

  • def sum(*numbers) получает sum(1, 2) как [1, 2].
  • def build(**options) получает build(color: "red") как { color: "red" }.
  • Splat также разворачивает значения, поэтому sum(*[1, 2]) передаёт два позиционных аргумента.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы собирать и разворачивать аргументы, не смешивая позиционные и именованные данные.

blocks

Блок является поведением, переданным методу, а yield выполняет это поведение.

  • [1, 2].each { |n| puts n } передаёт блок с параметром n.
  • Метод может вызвать yield(value), чтобы передать значение в полученный блок.
  • block_given? проверяет наличие блока перед yield и позволяет избежать LocalJumpError.

Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы блоки как переданное поведение, а не только как синтаксис итераторов.

lambdablocks

Оба варианта превращают блок в объект, но lambda ведёт себя ближе к методу.

  • square = proc { |n| n * n }; square.call(4) возвращает 16.
  • Lambda строго проверяет число аргументов, а обычный Proc допускает расхождения.
  • return завершает только lambda, но в обычном Proc пытается выйти из окружающего метода.

Зачем это спрашивают: Для джуниора главный сигнал состоит в знании строгой проверки аргументов и поведения return без обсуждения внутреннего устройства.

enumerable

Enumerable добавляет переиспользуемые методы обхода классу, который выполняет его контракт итерации.

  • Класс должен подключить Enumerable через include и определить each, передающий элементы.
  • После этого select и map могут фильтровать и преобразовывать переданные значения.
  • reduce может объединить значения, например [1, 2, 3].reduce(0, :+) вернёт 6.

Зачем это спрашивают: Интервьюер ожидает обе части контракта Enumerable и конкретные методы, которые он предоставляет.

each обходит элементы, а map строит новый Array из результатов блока.

  • [1, 2].each { |n| puts n } выполняет вывод и возвращает исходный Array.
  • [1, 2].map { |n| n * 2 } возвращает [2, 4].
  • Используйте map для преобразования вместо ручного добавления результатов внутри each.

Зачем это спрашивают: Этот вопрос проверяет, выбираете ли вы метод коллекции по возвращаемому значению и назначению.

ruby

Array является упорядоченной коллекцией с индексами от нуля и может хранить объекты разных типов.

  • items[0] читает первый элемент, а items[-1] читает последний.
  • items << "book" добавляет на месте, а items.pop удаляет и возвращает последний элемент.
  • items[1, 2] возвращает срез из двух элементов, начиная с индекса 1.

Зачем это спрашивают: Интервьюер проверяет практическое владение самой распространённой упорядоченной коллекцией Ruby.

ruby

Hash хранит пары ключ-значение и возвращает значение по ключу.

  • user = { name: "Mina" }; user[:name] возвращает "Mina".
  • user[:role] возвращает nil при отсутствии, а user.fetch(:role) вызывает KeyError без значения по умолчанию.
  • user.each do |key, value| передаёт обе части каждой пары.

Зачем это спрашивают: Сильный ответ джуниора описывает обычное чтение и более безопасный fetch для обязательных ключей.

Интерполяция вставляет выражение в String с двойными кавычками, а конкатенация соединяет строки.

  • "Hello, #{name}" вычисляет name, а одинарные кавычки сохраняют #{name} буквально.
  • "Hello, " + name создаёт новый String, а text << name изменяет text.
  • При использовании + число требует преобразования, например "Age: " + age.to_s.

Зачем это спрашивают: Интервьюер проверяет синтаксис строк и умение распознавать изменяющие операции.

symbols

Symbol является неизменяемым идентификатором, а String представляет изменяемый текст.

  • В ключах Hash часто используют символы, например { name: "Ana" }[:name].
  • Символы подходят для состояний и ключей опций вроде :pending или :json.
  • Пользовательский текст должен оставаться String, а не превращаться в произвольные символы.

Зачем это спрашивают: Хороший ответ выбирает символы по смыслу и неизменяемости, а не называет их более быстрыми строками.

Range представляет интервал, по которому можно итерироваться или проверять принадлежность.

  • 1..5 включает 5, а 1...5 исключает 5.
  • (18..65).cover?(age) удобно читается как проверка границ.
  • array[1..3] использует Range для выбора последовательных элементов.

Зачем это спрашивают: Интервьюер ожидает знание включающей и исключающей форм и одного практического применения.

Изменяющий метод меняет получателя, а неизменяющий возвращает другое значение.

  • name.upcase возвращает новый String, а name.upcase! меняет name на месте.
  • array.sort возвращает отсортированную копию, а array.sort! переставляет тот же Array.
  • Восклицательный знак часто обозначает опасность, но Ruby не навязывает это соглашение.

Зачем это спрашивают: Интервьюер проверяет, можете ли вы предсказать изменение объекта и избежать случайных ошибок с общим состоянием.

ruby

freeze запрещает дальнейшую мутацию этого объекта, но защита является поверхностной.

  • name = "Ruby".freeze приводит к FrozenError при name << "!".
  • Заморозка Array не замораживает изменяемые объекты внутри него.
  • frozen? сообщает состояние, а dup обычно создаёт незамороженную поверхностную копию.

Зачем это спрашивают: Интервьюер ожидает практическое назначение защиты и ограничение: freeze не даёт глубокой неизменяемости.

Класс Ruby объединяет поведение, а initialize настраивает каждый новый экземпляр.

  • class User; def initialize(name); @name = name; end; end сохраняет переменную экземпляра.
  • User.new("Ada") создаёт объект и вызывает initialize.
  • attr_reader :name создаёт геттер, не открывая неограниченную запись.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы создавать инкапсулированный объект, а не открывать всё состояние.

ownershipoop

Класс Ruby наследуется от одного суперкласса и может переиспользовать или переопределять его методы.

  • class Admin < User объявляет Admin подклассом User.
  • Если Admin определяет greet, эта реализация выбирается раньше User#greet.
  • super вызывает следующую реализацию; super передаёт текущие аргументы, а super() не передаёт их.

Зачем это спрашивают: Сильный ответ джуниора объясняет одиночное наследование и передачу аргументов через super.

Закрытые вопросы

  • 21

    Для чего используют модули и mixin?

    modules
  • 22

    Что означают public, protected и private в Ruby?

    ruby
  • 23

    Чем методы экземпляра отличаются от методов класса?

  • 24

    Как обрабатывать исключения в Ruby?

    error-handlingrubysoft-skills
  • 25

    Как безопасно читать и записывать файлы в Ruby?

    ruby
  • 26

    Как вместе работают require, RubyGems и Bundler?

    bundlinggems
  • 27

    Чем отличаются ==, eql? и equal? в Ruby?

    ruby
  • 28

    Как if, unless и case выражают условия?

  • 29

    Что делает оператор безопасной навигации?

  • 30

    Как Ruby ищет вызываемый метод?

    ruby
  • 31

    Что относится к Model, View и Controller в MVC Rails?

    rails
  • 32

    Как роутинг Rails связывает URL с действием?

    rails
  • 33

    Что должно делать базовое действие контроллера Rails?

    rails
  • 34

    Что такое strong parameters?

  • 35

    Что такое модель ActiveRecord?

    orm
  • 36

    Как работают валидации моделей Rails?

    validationrails
  • 37

    Что такое миграция базы данных Rails?

    databasemigrationsrails
  • 38

    Как работают belongs_to и has_many?

  • 39

    Как выполнять базовые CRUD-операции через ActiveRecord?

    orm
  • 40

    Чем отличаются where, find_by и find?

  • 41

    Что такое scope в ActiveRecord?

    orm
  • 42

    Что такое проблема N+1 запросов в Rails?

    queriesn+1rails
  • 43

    Как ресурсные маршруты сопоставляются с REST-действиями?

    rest
  • 44

    Какие HTTP-коды должен возвращать базовый Rails API?

    httpstatus-codesrails
  • 45

    Как ERB-представление рендерит данные контроллера?

  • 46

    Что такое partial в Rails и как работают locals?

    rails
  • 47

    Для чего полезна Rails console?

    rails
  • 48

    Чем отличаются окружения Rails?

    rails
  • 49

    Как написать базовый пример RSpec для модели?

    testing
  • 50

    Что должна проверять request spec RSpec?

    testing
  • 51

    user.name вызывает NoMethodError, потому что user равен nil. Как искать причину?

  • 52

    Необязательный профиль приводит к падению user.profile.city. Какое небольшое исправление внести?

  • 53

    Почему {"name" => "Ana"}[:name] возвращает nil и как это исправить?

  • 54

    После copy = original.dup изменение copy[:settings][:theme] меняет и original. Почему?

  • 55

    Метод должен удвоить массив без изменения входа, но использует map!. Как исправить?

  • 56

    Как должен вести себя пользовательский EventLog#each, если вызывающий код не передал блок?

    blocks
  • 57

    Почему def calculate; yield(4); 10; end возвращает 10, если блок вернул 8?

    blocks
  • 58

    Что вернёт formatter = proc { |name| name.strip.upcase } для formatter.call(" Ada ")?

    blocks
  • 59

    Почему Proc, созданный внутри build_formatter, помнит локальный prefix после завершения build_formatter?

    blocks
  • 60

    Что вернёт [1, 2, 3, 4].select(&:even?).map { |n| n * 10 }?

  • 61

    Нужно найти первого активного администратора в массиве. Почему лучше find или detect, а не select.first?

  • 62

    В CSV-импорте нет обязательных заголовков. Как сообщить об этом ожидаемом сбое своим исключением?

    error-handling
  • 63

    CSV.parse(File.read(path)) вызывает invalid byte sequence in UTF-8 для клиентского файла, хотя File.read выполнился успешно. Как обработать файл?

    soft-skills
  • 64

    Обёртка API логирует таймаут, а вызывающий код считает запрос успешным. Чего не хватает?

    resilienceapi
  • 65

    File.read("config/settings.json") работает локально, но в тестах даёт Errno::ENOENT. Что проверить?

    config
  • 66

    require "csv_importer" даёт LoadError, хотя файл есть в lib/. Что проверить?

  • 67

    Приложение падает с Bundler::GemNotFound. Каковы первые проверки?

    bundlinggems
  • 68

    Bundler сообщает: gem A требует Rack ниже 3, а gem B требует Rack 3+. Что делать?

    bundlinggemsrack
  • 69

    RSpec сообщает expected: 201, got: 422. Как использовать этот вывод?

    testing
  • 70

    Спека проходит отдельно, но находит двух пользователей в полном наборе. Что проверить?

  • 71

    После merge Git показывает маркеры конфликта в orders_controller.rb. Что делать?

    git
  • 72

    Вы слили не ту ветку и ещё не закоммитили конфликтный merge. Что безопасно сделать?

  • 73

    Rails возвращает 404 для /orders/42, но OrdersController#show существует. Что проверить первым?

    rails
  • 74

    GET /orders работает, но форма получает ошибку маршрута для POST /orders. Почему?

    forms
  • 75

    Rails пишет Unpermitted parameter: :role, и role не меняется. Как реагировать?

    rails
  • 76

    User.create(email: "bad") возвращает несохранённый объект. Как найти ошибку валидации?

    validation
  • 77

    Когда при отладке записи Rails использовать save! вместо save?

    rails
  • 78

    post.author.name падает для одной записи при belongs_to :author. Что исследовать?

  • 79

    Как смоделировать участие пользователей во многих проектах, если каждая связь хранит ещё и роль участника?

  • 80

    После получения кода Rails даёт PG::UndefinedColumn для orders.status. Что проверить?

    railsfundamentals
  • 81

    Конкретная локальная миграция добавила неверный столбец, но после неё уже выполнились новые миграции. Как отменить только её?

    migrationsschema
  • 82

    Почему Order.where(status: "paid") не показывает SQL до вызова to_a?

    sql
  • 83

    Задача обслуживания должна обработать 200 000 активных пользователей. Как не загружать их всех сразу?

    concurrency
  • 84

    Дашборду нужно только число активных пользователей. Почему стоит вызвать User.active.count вместо User.active.to_a.length?

  • 85

    Вы добавили includes(:author), но страница всё ещё медленная. Какие данные собрать?

  • 86

    Несколько Rails view повторяют order.created_at.strftime("%d %b %Y"). Куда вынести форматирование?

    rails
  • 87

    Почему form_with model: @article на странице редактирования отправляет PATCH /articles/7, а не POST /articles?

  • 88

    Rails-запрос возвращает 500 только для одного payload. Как логи сузят ошибку?

    rails
  • 89

    Как экспериментировать с обновлениями моделей в Rails console без сохранения изменений базы?

    experimentsdatabaserails
  • 90

    GET /articles возвращает все 10 000 строк и расходует слишком много памяти. Какую базовую пагинацию добавить?

    memorypagination
  • 91

    Отсутствующий API-ресурс превращается в 500. Как исправить ответ?

    api
  • 92

    Order#subtotal суммирует произведения количества и цены каждой позиции. Как протестировать этот обычный метод модели?

  • 93

    Request spec ожидает JSON от POST /orders, но response.parsed_body падает, потому что контроллер вернул HTML redirect. Что вы проверите?

    html
  • 94

    Sidekiq job остаётся в очереди, а worker пишет Redis::CannotConnectError. Что проверить?

    redisdata-structuresbackground-jobs
  • 95

    Что произойдёт при вызове ReportJob.perform_async(user) с объектом User в нативном Sidekiq и что нужно передать?

    background-jobs
  • 96

    Повторная Sidekiq job дважды добавляет 10 кредитов. Как сделать её идемпотентной?

    background-jobsidempotency
  • 97

    Turbo-ссылка заменяет всю страницу вместо frame comments. Что проверить?

  • 98

    Опишите успешный HTML-запрос Rails GET /products/7.

    htmlrails
  • 99

    PostgreSQL даёт PG::NotNullViolation, когда у заказа нет currency. Как исправить?

    postgres
  • 100

    Удаление пользователя вызывает PG::ForeignKeyViolation, потому что заказы всё ещё ссылаются на него. Что проверить до изменения constraint?