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

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

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

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

Бинарный поиск.

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

Так почему я рассказываю вам о методе поиска чисел в списке? Потому что вы можете применить эту мысленную структуру для отладки программы за меньшее количество шагов.

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

Отладка с использованием двоичного поиска.

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

Для отладки с использованием двоичного поиска вы можете выполнить следующие действия.

  • Воспроизведите ошибку и определите минимальные шаги, необходимые для ее возникновения. Это важный шаг независимо от того, как вы устраняете проблему.
  • Определите площадь поверхности. Площадь поверхности - это часть вашего приложения, где находится ошибка. Что еще более важно, это позволяет игнорировать части приложения. При двоичном поиске списка чисел вы не хотите проверять каждое число. Точно так же при двоичном поиске в приложении вы не хотите читать каждую строку кода. Вы можете разделить поверхность на причинную и пораженную зоны.
  • Определите пораженный участок. Поверхность включает в себя все, к чему прикасались в процессе воспроизведения ошибки. Пораженная область - это конкретный момент, когда возникает ошибка. Это позволяет вам еще больше сузить фокус.
  • Двоичный поиск в затронутой области с помощью отладчика или операторов печати, чтобы следить за ходом работы вашего приложения, игнорируя пути, которые не вызывают ошибки. Найдите самый маленький фрагмент кода, который может содержать ошибку.
  • Определите причинную зону. Причинно-следственная область включает в себя любые части вашего приложения, которые связаны с вашей проблемой или связаны с ней. Понимание причинной области поможет вам понять, почему ваша ошибка вообще существует.
  • Разработайте решение, основанное на вашем понимании площади поверхности. Как только вы поймете, почему существует ошибка, вы обычно можете использовать эти знания для разработки решения для нее.

Воспроизведите ошибку.

Чтобы определить площадь ошибки, вы должны иметь возможность воспроизводить ее последовательно. Это первый шаг в устранении любой проблемы. Если вы не можете постоянно воспроизводить ошибку, решить ее будет нелегко.

Создав список шагов для воспроизведения ошибки, вы можете определить начало и конец области поверхности ошибки. Шаги воспроизведения могут выглядеть примерно так:

1. Откройте приложение.

2. Войдите как пользователь-владелец.

3. Заполните форму оплаты.

4. Войдите как сотрудник-пользователь.

5. Перейдите на страницу оплаты.

6. Наблюдайте за ответом 404 Unauthorized.

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

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

Определите площадь поверхности ошибки.

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

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

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

Определите пораженную область ошибки.

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

5. Перейдите на страницу оплаты.

6. Наблюдайте за ответом 404 Unauthorized.

Определив эту область, вы можете ограничить начальный поиск от начального запроса до конца неавторизованного ответа.

Бинарный поиск пораженной области.

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

Рассмотрите возможность использования отладчика.

Некоторые разработчики помещают операторы печати в свои приложения, чтобы проверять значения и определять, когда возникает ошибка. Это нормально работает, но еще лучше, если вы можете использовать отладчик. Отладчик позволяет пошагово выполнять код по мере его выполнения, чтобы вы могли свободно наблюдать за его потоком и проверять значения.

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

Избегайте рассуждений о Кодексе.

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

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

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

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

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

В моем интервью контроллер отвечает за выполнение программы, когда пользователь переходит на страницу оплаты. Он обеспечивает авторизацию пользователя и отправляет ему информацию, необходимую его браузеру для просмотра страницы оплаты.

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

if (payment_form.user_id !== current_user.id) 
     send_unauthorized_response()

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

Поймите причинно-следственную связь.

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

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

1. Откройте приложение.

2. Войдите как пользователь-владелец.

3. Заполните форму оплаты.

4. Войдите как сотрудник-пользователь.

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

3. Заполните форму оплаты.

Понимание причинно-следственной области поможет вам генерировать теории и найти хорошее решение ошибки.

Создавайте и проверяйте теории, соответствующие данным.

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

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

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

В моем примере пользователь, заполняющий форму оплаты, может быть либо владельцем, либо сотрудником. Оба должны иметь доступ к странице оплаты. Однако, если идентификатор в платежной форме не совпадает с идентификатором текущего пользователя, приложение отправляет неавторизованный ответ 404.

Я разработал теорию, согласно которой нам необходимо проверить как идентификатор сотрудника, так и идентификатор владельца. Ради интервью они дали мне понять, что я был прав, и мы двинулись дальше.

Вывод

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

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

В следующий раз, когда вы будете устранять проблему, попробуйте этот метод. Чем больше вы практикуете этот метод, тем лучше вы его адаптируете. Надеюсь, это сэкономит ваше время на следующей ошибке!