Обновить
256K+

Качество кода *

Как Макконнелл завещал

105,94
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Деградация кода — это результат неправильной организации процессов

Время на прочтение7 мин
Охват и читатели30K

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

На своей должности руководителя разработки я стал непосредственным свидетелем разницы между командой, которой предоставили мощь и… какой антоним у мощи? Они были не слабыми, а, скорее, немощными.

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

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

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

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

Давайте изучим это на примере деградации кода.
Читать дальше →

Как улучшить время сборки в iOS с помощью модуляризации

Время на прочтение9 мин
Охват и читатели1.7K
image


Большинство команд мобило понимают и ценят преимущества быстрой сборки. Возможность быстро компилировать и тестировать код означает ускорение разработки и итераций, что, в свою очередь, позволяет команде осуществлять доставку новых версий более регулярно и эффективно. Но на самом деле бывает сложно добиться стабильно быстрой сборки и внедрить долгосрочное решение, позволяющее поддерживать высокую скорость сборки по мере роста кодовой базы. Существует множество различных тактик, и если некоторые из них относительно тривиальны — например, уменьшение размера доставляемых ресурсов, — то другие могут быть гораздо более сложными и даже опасными (вспомните сомнительные трюки с компилятором)!
Читать дальше →

Почему комментарии в коде — базовый инструмент, упрощающий поддержку и развитие проекта

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели5.3K

Привет, Хабр! На связи C#-разработчик компании SimbirSoft Георгий. В этой статье поговорим о том, как с помощью комментариев кода можно ускорить погружение новых разработчиков в проект, упростить написание документации и найти общий язык с коллегами-разработчиками.

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

Читать далее

Формат описания идентификатора зависимости в JS DI

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели583

Эта статья для тех, кто знает, что такое “внедрение зависимостей” и имеет практический опыт его использования. Меня зовут Алекс Гусев и я являюсь автором библиотеки “@teqfw/di”. Цель моей библиотеки - дать возможность использовать функционал “внедрение зависимостей через конструктор” в проектах на JS (фронт и бэк) и TS (бэк). Минимальной единицей внедрения является отдельный экспорт es6-модуля. Поэтому библиотека не может использоваться с модулями CJS или UMD.

В основу внедрения зависимостей заложена идея о том, что вместо статического связывания исходного кода на этапе написания (через import) применяется динамическое связывание объектов программы в режиме выполнения. В моей библиотеке это достигается за счёт размещения в коде конструкторов (или фабричных функций) инструкций по созданию нужных им зависимостей, которые интерпретируются Контейнером Объектов при работе программы и на основании которых загружаются нужные исходники и создаются нужные зависимости.

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

Читать далее

Реализация сапёра в 100 строках чистого Ruby

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели10K

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

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

В нашем случае мы проделаем это на примере старого доброго «Сапёра». Помню, как играл в него на Windows XP ещё пацаном. Если и вы разделяете аналогичные воспоминания, то приветствую вас, мои друзья-миллениалы!
Читать дальше →

Мои взгляды на программирование на июль 2024 года

Время на прочтение5 мин
Охват и читатели14K
Эта статья – собрание убеждений о разработке ПО, которые выработались у меня на сегодняшний день. Всё основано на личном опыте.

Подход к задачам


Основная часть моей работы – разбираться с тикетами, и я до сих пор продолжаю совершенствоваться в этом деле. Вот несколько вещей, которые я открыл для себя в процессе.
  • Разные задачи, проекты и команды требуют разных подходов. Например, сделать пейсмейкер без автоматических тестов было бы безответственным решением – кто-то может от этого пострадать. И вместе с тем, глупо изводиться по поводу автоматических тестов на геймджеме, куда вы отправились на выходных. Содержание понятия «хороший код» меняется в зависимости от контекста, и нужно адаптировать свой подход под конкретную ситуацию.
  • Делайте марш-броски. Бывает, что я ставлю себе цель довести какую-то функциональность до готовности в кратчайшие сроки, пусть даже срезая углы где только можно, с кодом ужасного качества и TODO на каждом шагу. Когда у меня появится что-то рабочее, тогда и буду приводить всё в должный вид. Я пришел к выводу, что это хороший способ обозначить для себя проблемные зоны, а также неплохой путь к ускорению процесса разработки. На эту тему есть статья «Выбросьте первый набросок кода».
  • Если я бьюсь головой об задачу и никак не могу сдвинуться с мертвой точки, значит, необходимо оторваться от нее на какое-то время.
  • Прежде чем начать работу над сложной задачей, я задаю себе вопрос: «А что если вообще этого не делать?» Как правило, вопрос оказывается глупым и выполнять задачу все-таки приходится. Но примерно в пяти процентах случаев я осознаю, что определенную часть работы можно спокойно пропустить.

Читать дальше →

Работает — не трожь: зачем обновлять Python в долгоживущих проектах

Время на прочтение15 мин
Охват и читатели35K

Всем привет! Меня зовут Сергей Яхницкий. Я пишу на Python уже больше шести лет, техлид в Яндекс Такси, Python-евангелист и член Python-комитета Яндекса (аналог Python Steering Council).

Человек я простой, звёзд с Гитхаба не хватал: до того, как я устроился в Такси, я мирно писал маленькие бэкенды на Python. А потом меня прорвало: кодогенерации, CI/CD, кучи тестов, монорепа и прочее. Вот тут-то моя питоничья душа и воспряла. Решил я всё автоматизировать, обновить всё, что движется, а что не движется — подвигать и обновить. Из этого вышел мой рассказ.

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

Читать далее

Программисты не должны доверять никому, даже себе

Время на прочтение7 мин
Охват и читатели3.3K
Программисты должны быть параноиками.

  • “Я дважды проверил код”
  • “Код прошел тесты”
  • “Ревьюер одобрил мой код”
“Мой код верен?”

Писать правильный код сложно, а проверить его корректность невозможно. Вот несколько причин, почему:

  • Универсальность: Даже если ваш код работает правильно один раз, будет ли он работать так во всех случаях, на всех машинах, во всех ситуациях?
  • Ложноположительные результаты: Неудачные тесты указывают на наличие ошибок, но пройденные тесты не обещают их отсутствия.
  • Отсутствие уверенности: Вы могли бы написать формальное доказательство корректности вашего кода, но теперь вы должны задаться вопросом, верно ли это доказательство. Вам нужно будет подтвердить доказательство. Эта цепочка проверки доказательств никогда не закончится.
Глупо добиваться абсолютной уверенности в правильности своего кода. Ошибка может скрываться в зависимостях, которые вы никогда не найдете. Тем не менее, не стоит отчаиваться. Мы все еще можем снизить риск возникновения ошибок, добиваясь глубокого понимания кода и добросовестно работая с ним.
Читать дальше →

Четыре принципа разработки ПО, которым я научился на горьком опыте

Время на прочтение4 мин
Охват и читатели44K
Недавно я спроектировал и написал огромный сервис, и в прошлом месяце (наконец-то) состоялся его запуск. В процессе проектирования и имплементации я обнаружил, что ряд закономерностей, которые я приведу ниже, раз за разом всплывает в самых разных сценариях.

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

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

SOLID в Go и щепотка паттернов

Уровень сложностиСредний
Время на прочтение23 мин
Охват и читатели20K

SOLID-ная статья о принципах SOLID, которую вы можете предложить тем, кто хочет понять эти принципы в контексте языка Go. Или прочитать самостоятельно, если это интересно и вам.

И да, как сказал бы волк из небезызвестного мультика: «SOLID? Шо, опять?»

Читать далее

Программист никому не должен доверять, и даже самому себе

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели11K

Программисты должны быть параноиками.

  • «Я дважды проверил код»
  • «Код проходит все тесты»
  • «Ревьюер одобрил мой код»

«Так ли корректен мой код?»

Писать код корректно трудно, а подтвердить корректность кода невозможно.
Вот некоторые из причин этого:

  • Всеобщность: даже если код правильно вёл себя один раз, будет ли он вести себя так во всех случаях на всех машинах и всегда?
  • Ложное прохождение теста: непрохождение тестов указывает на наличие багов, но прохождение тестов не гарантирует их отсутствия.
  • Отсутствие определённости: можно написать формальное доказательство корректности кода, но теперь нужно задаться вопросом, корректно ли доказательство. Потребуется доказать доказательство. Эта цепочка проверки проверок никогда не закончится.

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

Как в Google выполняют ревью кода

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели32K

Critique и Gerrit

У Google есть два собственных инструмента для ревью кода: Critique, используемый большинством инженеров, и Gerrit, — опенсорсный, который продолжают применять в публичных проектах.

(Вы можете сами поэкспериментировать с Gerrit в опенсорсных репозиториях Chromium и Android.)

Дэшборды

Когда инженеры логинятся с утра или когда устраивают перерыв для ревью пул-реквестов, внутри Google называемых change list, или CL, и в Critique, и в Gerrit они работают с дэшбордами, в которых можно легко вкратце просмотреть все актуальные изменения (это похоже на окно пул-реквестов репозитория GitHub, только более сложное и информационно насыщенное).

В дэшборде Gerrit есть единичный поиск, извлекающий такую информацию, как размер изменения и более подробные сведения о статусе CL (три столбца справа).

Читать далее

Решаем задачу уровня «Невозможно». Сжатие хаотического бинарного кода. Суперпозиционные системы счисления

Уровень сложностиСложный
Время на прочтение10 мин
Охват и читатели4.8K

Для наилучшего восприятия выделим основные пункты изложенного материала:

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

Читать далее

Ближайшие события

Опасность устарела: несколько важных нюансов в новых стандартах C++

Время на прочтение16 мин
Охват и читатели31K
Undefined behavior (UB) — боль, знакомая каждому разработчику со стажем; эдакий «код Шредингера», когда не знаешь, правильно тот работает или нет. К счастью, стандарты языка С++20/23/26 привнесли относительно неопределенного поведения кое-что новое. И довольно важное, если вы — архитектор ПО, а «плюсы» — ключевой стек вашей компании (подробнее о том, как и почему мы в «Лаборатории Касперского» много используем С++, читайте здесь).

В этой статье я со своих позиций Senior Software Architect и Security Champion в микроядерной операционной системе KasperskyOS рассмотрю кейсы-ловушки, в которые можно попасть практически в любом из стандартов, и покажу, что меняется в С++20/23/26, — уменьшается ли количество кейсов с неопределенным поведением, и становится ли С++ безопаснее.


Читать дальше →

Чистый код: Данные

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели12K

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

Неизменяемым называется объект (англ. immutable object), состояние которого не может быть изменено после создания(1). Это понятие не так широко используется в различной литературе, поэтому начну с более подробного разбора этого понятия и обоснования, почему стоит применять этот шаблон.

Классическое определение гласит - Объектно ориентированное программирование (ООП), парадигма программирования, в рамках которой программа представляется в виде совокупности объектов, а её выполнение состоит во взаимодействии между объектами. Объектом называется набор из данных и операций, которые можно выполнить над этими данными(2).

Практика программирования показывает, что не все операции которые можно выполнить над данными стоит помещать в один объект. Например, формулу расчет угла в прямоугольном треугольнике можно представить как константное выражение. Вероятность её изменения приближается к нулю, поэтому ее можно смело применять как часть объекта с данными. Другой пример, формирование цены на товар в магазине, тоже формула, но она может меняться в соответствии с требованиями маркетинга. Такую формулу не следует помещать в метод принадлежащий объекту с данными.

Читать далее

Исправляем следующие 10 000 багов, связанных с наложением ссылок

Время на прочтение18 мин
Охват и читатели5.7K

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

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

Читать далее

Пишем анти-легаси приложение

Время на прочтение7 мин
Охват и читатели20K

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

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

Я даже предположил, что Elm MVU — это тот путь, который данные потребности закроет.

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

Под словом «естественный» я подразумеваю нечто, что коррелирует с языком, который мы используем в повседневной жизни. Функциональное программирование не всегда можно описать таким языком (например, несмотря на то, что монады, включая Observable streams, являются относительно простым понятием, мы вряд ли сможем выразить это понятие на таком языке). Я убедился, что программирование, которое лучше коррелирует с естественным языком — это многопарадигменное программирование, где вещи не строго OOP и не строго функциональны, а то или другое в зависимости от ясности и удобства работы.

Читать далее

Основы архитектуры для джунов: построение масштабируемых и чистых приложений на python (Туториал)

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели35K

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

Читать далее

UB or not UB: дублируем элемент std::vector

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели12K

В статье выясним, можно ли с точки зрения стандарта языка C++ тривиальным вызовом push_back продублировать элемент std::vector. Отвечая на простой вопрос, столкнемся с более интересными: что собой представляет внутренний мир вектора, как "протухают" итераторы при реаллокации, какие ограничения добавляют гарантии безопасности относительно исключений...

Читать далее

Подготовка к техническому собеседованию Senior/Team Lead backend

Уровень сложностиСредний
Время на прочтение3 мин
Охват и читатели42K

Недавно появились мысли походить на собеседования чем я успешно занялся. Если конкретно - смотрел лидовскую/сеньерскую позиции на Python и Golang(но статья может пригодиться backend разработчикам в целом). Не ставлю целью статьи объять все не объятное и дать какие-то гарантии. Я лишь зафиксирую данные для себя на будущее.

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

Сразу сделаю пометку, что некоторые навыки/ресурсы специфичны(по типу нарешивания Leetcode), но отталкиваемся от текущих реалий рынка.

Читать далее