Задачки с собеседований и не только
Материал в этом посте справедлив для многих языков программирования. Но, как всегда, примеры буду показывать на JS, так как мне просто нравится это магический, напичканный костылями, язык ☺
В мире программирования есть общие вопросы, которые задаются на разные позиции в разных областях. Один из таких вопросов: как работает перехват исключений, а именно рассказать как поведет себя блок:
try {} catch {} finally {}
Многие знают как ловить исключения и как работает блок try/catch. Но вот добавление блока finally может сильно поменять логику и, даже, удивить, если не знать правил его работы. Этот вопрос можно услышать на собеседовании по Java, C#, PHP и нашем любимом JavaScript.
Вроде бы не такой-то уж и сложный вопрос, но в нем легко запутаться. Рассмотрим такой случай:
Что вернется? В принципе все просто, вернется 2, так мы выбросили исключение, то отработает блок catch и из него будет возврат.
Что если добавить блок finally ?
Здесь уже интереснее и вы видите, что даже если в блоке catch есть возврат, то он игнорируется и возврат происходит из блока finally.
Finally и success
А что если у нас не выбрасывается исключение?
Вот тут уже возникают сомнения, что и как должно отработать, если нет опыта работы с finally или вы еще не запомнили эти правила. Вывод будет следующий:
"try block"
"finally block"
5
Да, у нас блок finally отрабатывает всегда.
Усложняем вопрос: 2 блока finally
Ответ: после первого блока finally далее уже код не будет отрабатываться (если мы выходим из блока через return)и там может быть все что угодно.
Выносим return из finally блока, и что же будет тогда?
Ответ:
"try block"
"finally block"
1
Возврат будет из блока try, но finally будет отрабатывать всегда, так что в этом блоке можно даже что-то еще посчитать хоть ответ уже и вернулся:
А как отработает такой Node.js код?
Интересный вопрос, м?
Как мы видим тут уже исключение в исключении. Код отработает точно так же, как и, к примеру, в Java. В Java вызов System.exit() не позволяет сработать блоку finally.
В Node.js аналогичная ситуация: process.exit() не дает отработать блоку finally.
Для тех, кто пишет на PHP, вопрос как отработает этот код:
<?php declare(strict_types=1);
try {
var_dump('try');
foo();
}
catch (Error $e) {
var_dump('catch');
exit(1);
}
finally {
var_dump('finally');
}
Ответ не даю. Догадаетесь сами ?