Привет, Хабрюзеры.

Недавно я устроился на вакансию Golang junior разработчика в новую компанию. Ранее я несколько лет программировал на PHP, пока не познакомился с Go. Думал, что моя мечта сбылась: я набрался опыта, стал более опытным специалистом и теперь могу продолжать развиваться. Однако, после выполнения задачи код, написанный мной, нужно было отправить на код-ревью. После этого мне приходили правки, которые я должен был исправить и снова отправить на ревью. Раньше я не понимал, зачем нужен этот процесс. На форумах и в сообществах многие писали, что код работает — и слава Богу, так зачем нужны эти ревью?

Теперь, после некоторого времени работы, я хотел бы поделиться своим мнением о код-ревью и объяснить, почему этот процесс важен.

Что такое код-ревью и зачем оно нужно?

Код-ревью (code review) — это процесс проверки кода другим разработчиком, который не писал этот код. Код-ревьюер играет важную роль в процессе разработки программного обеспечения по нескольким причинам:

  1. Повышение качества кода: Код-ревью помогает выявить ошибки и недочеты, которые могли быть пропущены автором кода. Это включает баги, потенциальные проблемы с производительностью и нарушения стиля кодирования.

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

  3. Обучение и обмен знаниями: Код-ревью — это возможность для обмена знаниями между разработчиками. Младшие разработчики могут учиться у более опытных коллег, а также узнавать о лучших практиках и новых подходах.

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

  5. Выявление потенциальных уязвимостей безопасности: Код-ревьюеры могут заметить и предотвратить потенциальные уязвимости безопасности в коде, которые могли быть упущены автором.

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

Основные задачи код-ревьюера

  1. Проверка логики и функциональности: Убедиться, что код работает правильно и соответствует требованиям, что не было упущено никаких важных деталей.

  2. Проверка тестов: Убедиться, что код покрыт тестами и что тесты написаны корректно.

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

  4. Проверка читаемости и поддерживаемости кода: Убедиться, что код легко читается и поддерживается, что соблюдаются принципы чистого кода (clean code).

  5. Оценка соблюдения стандартов: Проверить, что код соответствует стандартам и стилям, принятым в команде или компании.

Например

Исходный код

Разработчик написал следующую функцию для вычисления суммы квадратов чисел от 1 до n:

package main

import "fmt"

func sumOfSquares(n int) int {
    result := 0
    for i := 1; i <= n; i++ {
        result += i * i
    }
    return result
}

func main() {
    fmt.Println(sumOfSquares(10))
}

Код-ревью

Теперь давайте рассмотрим, как код-ревьюер может проверить этот код и предложить улучшения.

Комментарий 1: Обработка граничных случаев

func sumOfSquares(n int) int {
    if n <= 0 {
        return 0
    }
    result := 0
    for i := 1; i <= n; i++ {
        result += i * i
    }
    return result
}

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

Заключение

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

Так что, если вы сталкиваетесь с код-ревью, примите это как шанс улучшить свои навыки и внести вклад в качество проекта.

Комментарии (9)


  1. qrdl
    25.07.2024 14:03
    +6

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

    Это изменение не дает ничего, код и так вернет 0 для n < 1. А вот проверки на переполнение тут нет, и ревьювер это пропустил. От такого ревью пользы никакой


    1. fllipy Автор
      25.07.2024 14:03

      1. Изменение, предложенное ревьюером, касающееся проверки на n <= 0, имеет смысл. Оно делает код более явным и понятным. Вместо того чтобы полагаться на неявное поведение цикла (который не выполнит ни одной итерации для n < 1), мы явно обрабатываем случай n <= 0 и возвращаем 0. Это улучшает читаемость и делает намерения автора кода более понятными для других разработчиков.


      1. Politura
        25.07.2024 14:03
        +5

        По мне, так оно делает код не более понятным, а более запутанным. Нет ничего страшного в том, чтоб полагаться на стандартное и очевидное поведение цикла, а вот добавлять масло маслянное во-первых раздувает код, во-вторых путает, ибо мозг при прросмотре кода на этом спотыкается, останавливается и начинает думать: "но зачем???"

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


        1. DoMoVoY
          25.07.2024 14:03

          хотел написать про int и меньше нуля... но ошибся. бывает...


      1. itmind
        25.07.2024 14:03

        неявное поведение цикла

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


        1. randomsimplenumber
          25.07.2024 14:03
          +1

          Такое было бы осмысленно, если бы вместо цикла из 2 строчек была простыня на 2 экрана с ifами. Тогда лучше явно изобразить early return.


  1. Gapon65
    25.07.2024 14:03

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

    func sumOfSquares(n int) (int, error) {
        result := 0
        var err error = nil
        if n < 0 {
            err = errors.New("sumOfSquares: negative argument")
        } else if n != 0 {
            for i := 1; i <= n; i++ {
                result += i * i
            }
        }
        return result, err
    }
    
    func main() {
        sum, err := sumOfSquares(-1)
        if err != nil {
            // Complain ...
        } 
    }


  1. Daniel217D
    25.07.2024 14:03
    +1

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


  1. noRoman
    25.07.2024 14:03

    Можно микрооптимизировать ):

    …
    result := 1
    for i := 2; i <= n; i++ {
        result += i * i
    }
    …