Топ-25 вопросов для телефонного собеседования. Часть 2

В предыдущей части этой статьи мы уже рассмотрели 25 вопросов, которые вам могут задать на телефонном собеседовании на должность программиста. В этой части мы рассмотрим еще 17. Диапазон сложности вопросов достаточно широкий, так что рекомендуем ознакомиться со всеми ними, а если вопросы покажутся вам простыми, обратите внимание на нашу подборку задач.

26. Что такое разработка через тестирование (англ. test-driven development)?

Это один из популярных подходов к разработке, при котором тесты пишутся перед тем, как начнет писаться какой-либо код. По сути, в таком случае ваш код подстраивается под написанные тесты. Пуристы вообще никогда не напишут строчку кода без теста для нее. Такой подход сильно улучшает качество вашей программы и зачастую считается признаком профессионализма.

Кстати, мы уже писали небольшой материал о доводах за использование TDD.

27. В чем разница между бинарным деревом и бинарным деревом поиска?

Бинарное дерево поиска — это упорядоченное дерево поиска, в котором все значения левее своего предка меньше него, а правее — больше или равны ему. Это важная структура данных, которая может использоваться для представления упорядоченных данных.

Мы рассказывали подробнее о деревьях поиска здесь.

28. Перечислите способы разрешения коллизий в хэш-таблице.

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

29. Что такое принцип открытости/закрытости? (ответ)

Принцип открытости/закрытости подразумевает, что любая система должна быть открыта для расширения, но закрыта для модификации. То есть, если у вас есть отлично работающая протестированная система, и в нее нужно добавить новую функциональность, то это следует делать с помощью добавления новых классов, а не изменения старых (как известно, если что-то работает, то не надо это трогать).

30. Как получить последнюю цифру числа? (ответ)

Если поделить число на 10 с остатком, то получившийся остаток будет последней цифрой числа. Так, например, 2345 % 10 будет равно 5, а 567 % 10 — 7. Это работает и в другую сторону — целочисленное деление может использоваться для того, чтобы избавиться от последней цифры числа: 2345 / 10 равно 234, а а 567 / 10 — 56.

31. Можете дать практический пример рекурсивного алгоритма? (ответ)

Существует много примеров использования рекурсивных алгоритмов на практике — например, в бинарных деревьях поиска и связных списках. Рекурсию можно использовать при вычислении чисел Фибоначчи, перевороте строки или связного списка, обходе графа и быстрой сортировке.

Кстати, рекурсию важно уметь оптимизировать.

32. Что такое временная сложность алгоритма?

Временная сложность алгоритма показывает соотношение между количеством входных данных и временем работы программы. Временная сложность дает вам примерное представление о быстродействии программы и о том, насколько возрастет время ее работы при увеличении кол-ва входных данных с десяти до десяти миллионов.

33. В чем разница между связным списком и массивом? (подробный ответ)

Связный список и массив — одни из основных структур данных в программировании. Память для массива выделяется одним непрерывным куском, а элементы связного списка могут быть раскиданы по всей памяти, что дает ему возможность расширять себя практически бесконечно до тех пор, пока есть свободная память. Может возникнуть такая ситуация, что вы не сможете хранить один миллион целых чисел в массиве, но сможете сделать это с помощью связного списка. Все остальные различия между связным списком и массивом вытекают из этого основного различия. Например, вы можете найти в массиве элемент за О(1), если у вас есть индекс этого элемента, но в связном списке это займет О(n).

34. Что такое «принцип подстановки Барбары Лисков»? (ответ)

Принцип подстановки Барбары Лисков подразумевает, что каждый тип должен быть полностью заменяемым его подтипами, если они есть. Например, если метод принимает в качестве аргумента объект класса Parent, то он должен принимать и объект класса Child, унаследованного от Parent. Каждый класс, который не может заменить своего родителя, нарушает принцип Барбары Лисков. Это трудный вопрос, и если вы сможете на него ответить, то наверняка произведете хорошее впечатление на интервьюера.

35. Что такое «регулярное выражение»? (ответ)

Регулярное выражение — способ осуществлять сопоставление с образцом больших текстовых данных. Например, с помощью регулярок можно проверить, существует ли некий символ в очень длинной строке, или содержит ли книга искомое слово. Почти все языки программирования поддерживают регулярные выражения, но среди них выделяется Perl. Java поддерживает Perl-овые регулярные выражения при использовании java.util.regex. Вы можете использовать регулярные выражения, чтобы проверить email-адрес, zip-код или даже SSN-число на валидность. Один из самых простых примеров использования — проверка на то, является ли строка числовой (то есть содержит только цифры).

Рекомендуем почитать материал об использовании регулярных выражений в Python (для новичков), а если вы уже знакомы с этих инструментом, то взгляните на нашу подборку лучших статических анализаторов «регулярок».

36. Что такое система «без состояния»?

У такой системы нет какого-либо внутреннего состояния, а значит, при одних и тех же входных данных будет получаться одни и те же выходные данные. Систему без состояния всегда легче программировать и оптимизировать, а значит, стоит разрабатывать ПО таким образом, чтобы состояние в нем присутствовало минимально.

37. Напишите SQL-запрос, чтобы получить из базы данных работников вторую по размеру зарплату (решение)

Классический, но от этого не менее интересный вопрос, с помощью которого можно проверить степень познания кандидата в SQL. Эту задачу можно решить с помощью коррелированного и некоррелированного подзапроса. Также вы можете использовать ключевые слова TOP или LIMIT, если вы используете SQL-сервер или MySQL, в зависимости от того, про что спрашивает интервьюер. Простейший способ решения задачи:

SELECT MAX(Salary) FROM Employee WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee)

Этот запрос найдет высочайшую зарплату, исключит ее из списка и найдет следующую максимальную, то есть вторую по размеру.

38. Можете описать разницу между коррелированным и некоррелированным подзапросом? (ответ)

В коррелированном подзапросе внутренний запрос зависит от внешнего, а значит, оба запроса выполняются последовательно, в то время как в некоррелированном подзапросы не зависят друг от друга и могут выполняться независимо друг от друга. В связи с этим коррелированный запрос медленнее некоррелированного, зато у коррелированного есть несколько замечательных применений — например, получение второй по высоте зарплаты из БД (см. предыдущий вопрос).

39. Как проверить, является ли число степенью двойки, не используя арифметические операторы? (решение)

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

public static boolean powerOfTwo(int x) {
        return (x & (x - 1)) == 0;
}

А еще в контексте такого вопроса могут спросить: чему равно 264? У нас есть подробный разбор этой задачи.

40. Как найти запущенный процесс в UNIX? (команда)

Вы можете использовать комбинацию команд ps и grep для того, чтобы найти любой запущенный процесс в UNIX. Предположим, что у необходимого вам процесса есть имя или какой-то текст, с помощью которого вы можете найти его:

ps -ef | grep "myProcess"

P.S. -e будет искать все процессы, а не только запущенные под текущим пользователем, а -f выдаст полную информацию о процессе, включая PID, который вы можете использовать для того, чтобы убить процесс с помощью kill.

Вообще, есть очень много полезных команд Linux, которые здорово экономят время – и вы о них, наверное, даже не знали.

41. Как найти в UNIX большие файлы (например, больше 1 Гб)? (команда)

Вы можете запросто сделать это с помощью команды find, потому что она дает возможность искать файлы по их размеру. Следующая команда позволяет найти все файлы размером больше 1 Гб, но очевидно, что размер искомых файлов легко менять. Например, для того, чтобы команда искала файлы меньше 100 Мб, достаточно заменить +1G на +100M.

find . - type f -size +1G -print

 42. Что такое shell-скрипт?

Shell-скрипт — это набор команд с некоторыми фичами из программирования — например, конструкции if и for. Таким образом, с помощью shell-скриптов вы можете автоматизировать рутинную работу вроде ежедневной чистки логов, создания бэкапов и т.д.

Список вопросов подошел к концу. Мы совсем немного не дотянули до 50. Вместо оставшихся 8 вопросов автор рекомендует вам почитать следующие статьи, где вы сможете найти оставшиеся вопросы и ответы на них:

Перевод статьи «Top 50 programmer phone interview questions with answers»