Small programming tricks: как мелкие хитрости делают инженера сильнее
Маленькие трюки программиста — git-инкантации, sed, fzf, guard clauses — которые накапливаются и превращаются в суперсилу разработчика.
Почему мелочи решают всё
Есть расхожее мнение: чтобы стать хорошим инженером, нужно изучить алгоритмы, паттерны проектирования, архитектурные концепции. Всё верно — но этого недостаточно. Значительная часть повседневной инженерной продуктивности складывается из небольших «самородков» знаний: понимания того, что языковая фича существует; знания, что необъяснимая задержка TCP скорее всего связана с настройкой TCP_NO_DELAY и алгоритмом Нейгла; умения найти правильное git-заклинание, чтобы выбраться из затруднительного положения, или трюка с sed для перезаписи файла.
Именно об этом написал инженер Уилл Кехлер в своём посте, который разлетелся по HackerNews: «Большая часть эффективного инжиниринга — это накопление небольших самородков знаний». И в этом есть глубокая правда.
Есть такие крупицы знаний, которые особенно ценны и не требуют большой поддерживающей ментальной инфраструктуры. Их не преподают в университетах. Их не найти в одном учебнике. Они накапливаются — от коллеги через плечо, из HackerNews в 23:00, из случайного комментария в Stack Overflow.
В этой статье мы разберём конкретные трюки по категориям: терминал, код, отладка, командная работа. Каждый из них мал. Вместе они меняют всё.
1. Трюки с терминалом и CLI
Терминал — это то место, где программист проводит огромную часть рабочего времени. Здесь мелкие знания окупаются быстрее всего.
fzf: поиск по истории на стероидах
Вам не нужно знать Python, чтобы использовать python3 -m http.server для запуска простого сервера в директории — но это всё равно сделает вашу работу чуть легче. Вы, вероятно, знаете, что ctrl + r позволяет искать историю команд в терминале — но если установить fzf, можно настроить ctrl + r на интерактивный fuzzy-поиск по всей истории.
# Установка fzf (macOS)
brew install fzf
$(brew --prefix)/opt/fzf/install
# Теперь Ctrl+R — это интерактивный поиск по истории
# Можно фильтровать по словам в реальном времени
Алиасы — ваши личные сокращения
Один из лучших приёмов при работе с командной строкой — создавать алиасы и пользовательские функции для команд, которые сложно запомнить или которые слишком длинные.
# ~/.zshrc или ~/.bashrc
alias gs='git status'
alias gl='git log --oneline --graph --decorate'
alias gp='git pull --rebase'
alias serve='python3 -m http.server 8000'
# Функция: быстрое создание и переход в директорию
mkcd() { mkdir -p "$1" && cd "$1"; }
sed, awk и однострочники
Создайте культуру, в которой программисты делятся полезными CLI-трюками и shortcuts друг с другом. Вот несколько мощных однострочников:
# Заменить все вхождения слова в файле
sed -i 's/oldword/newword/g' file.txt
# Найти 10 самых больших файлов в директории
du -ah . | sort -rh | head -10
# Показать открытые порты
lsof -i -P -n | grep LISTEN
# Быстрый HTTP-запрос с форматированием
curl -s https://api.example.com/data | python3 -m json.tool
2. Трюки с кодом: пишем лучше, быстрее
Guard clauses: конец вложенным «пирамидам»
Один из самых эффективных трюков для читаемости кода — guard clause (ранний возврат). Вместо вложенных if-else мы проверяем граничные условия в начале функции и сразу выходим.
Используйте guard clauses, понятные имена и ранние возвраты.
# Плохо: вложенная пирамида
def process_user(user):
if user is not None:
if user.is_active:
if user.has_permission('admin'):
# основная логика
return perform_action(user)
else:
return 'No permission'
else:
return 'Inactive user'
else:
return 'No user'
# Хорошо: guard clauses
def process_user(user):
if user is None:
return 'No user'
if not user.is_active:
return 'Inactive user'
if not user.has_permission('admin'):
return 'No permission'
# основная логика — без вложенности
return perform_action(user)
Избегайте лишних ветвлений
Вот приём, о котором стоит знать большему числу людей: избегайте ветвлений. Если можно сделать то же самое без if-выражения и даже без логического выражения, код, как правило, становится понятнее для людей и эффективнее для CPU.
# Вместо if/else для маппинга:
status_map = {
'active': '✅ Активен',
'inactive': '❌ Неактивен',
'pending': '⏳ Ожидает',
}
result = status_map.get(status, '❓ Неизвестно')
# Вместо:
if status == 'active':
result = '✅ Активен'
elif status == 'inactive':
...
Структуры данных: правильный выбор меняет всё
Для поиска используйте множества (sets) и словари (maps) вместо списков. Для I/O — пакетируйте сетевые и дисковые вызовы. В алгоритмах стремитесь к O(n) прежде чем браться за экзотические решения.
# Медленно: O(n) поиск в списке
if item in my_list: # список из 10 000 элементов — перебор каждого
...
# Быстро: O(1) поиск в множестве
my_set = set(my_list) # один раз
if item in my_set: # мгновенно
...
3. Трюки с git: выбраться из любой ситуации
Git — это тот инструмент, незнание мелких команд которого регулярно стоит разработчикам нескольких потерянных часов.
# Откатить последний коммит, сохранив изменения в рабочей директории
git reset HEAD~1 --soft
# Убрать случайно добавленный файл из стейджинга
git restore --staged path/to/file
# Найти коммит, который сломал функциональность (бинарный поиск)
git bisect start
git bisect bad # текущий коммит плохой
git bisect good v1.0 # этот тег был рабочим
# git сам переключает коммиты, вы говорите bad/good
# Интерактивный rebase: переписать последние 5 коммитов
git rebase -i HEAD~5
# Посмотреть что изменилось в конкретном файле за всё время
git log --follow -p -- path/to/file
Система контроля версий — незаменимый инструмент для любого программиста. Git позволяет отслеживать изменения в кодовой базе, сотрудничать с коллегами и откатываться к предыдущим версиям. Освоив команды и рабочие процессы Git, вы упростите процесс разработки и обеспечите плавное взаимодействие с командой.
graph TD
A[Сломан код в продакшене] --> B{Когда это сломалось?}
B --> |Не знаю| C[git bisect start]
B --> |Знаю примерно| D[git log --oneline]
C --> E[Помечаем bad/good коммиты]
E --> F[Git находит виновный коммит]
D --> G[git show HASH]
F --> H[Анализируем изменения]
G --> H
H --> I[Чиним или откатываем]
4. Трюки с отладкой: найти баг быстрее
Отладка — это то, где знание мелких приёмов буквально экономит часы.
Метод бинарного поиска в логах
Воспроизведите ошибку с фиксированными входными данными и окружением. Изолируйте её с помощью переключателей или комментариев. Используйте бинарный поиск с логами. Напишите тест, который падает на этом баге, затем исправьте его и запустите снова.
# Бинарный поиск проблемного участка:
# Вместо того чтобы читать 1000 строк кода,
# добавьте print/log в середину:
print("--- CHECKPOINT 500 ---", variable_state)
# Работает? Проблема во второй половине.
# Не работает? Проблема в первой половине.
# Повторяем — O(log n) итераций вместо O(n).
Не логируйте секреты
Проверяйте все входные данные и типы файлов на стороне сервера. Никогда не логируйте секреты или полные токены.
# Плохо:
logging.info(f"Connecting with token: {api_token}")
# Хорошо:
logging.info(f"Connecting with token: {api_token[:4]}...{api_token[-4:]}")
5. Командные трюки: знание как актив
В компании ещё больше знаний оказывается именно такими небольшими высокорычажными самородками: «Чтобы отладить ПРОБЛЕМУ, используй ИСТОЧНИК_ДАННЫХ»; «ЧЕЛОВЕК знает многое об ОБЛАСТИ и готов помочь»; «Когда происходит ТО-ТО, это значит, что нужно масштабировать вручную»; «Чтобы сделать rolling restart сервиса, запусти ЭТУ_КОМАНДУ».
Эти знания редко попадают в документацию — они живут в головах людей. Задача технического лидера — извлекать их и фиксировать.
Сравнение подходов к накоплению знаний в команде
| Подход | Масштабируемость | Поиск | Актуальность | Усилия |
|---|---|---|---|---|
| Устная передача | ❌ Низкая | ❌ Нет | ✅ Высокая | ✅ Нулевые |
| Wiki / Confluence | ✅ Высокая | ✅ Есть | ❌ Устаревает | 🔶 Средние |
| README в репо | ✅ Высокая | ✅ Есть | ✅ Рядом с кодом | ✅ Низкие |
| Brownbag-сессии | 🔶 Средняя | ❌ Нет | ✅ Высокая | 🔶 Средние |
| Runbook в коде | ✅ Высокая | ✅ Есть | ✅ Высокая | 🔶 Средние |
Культура шеринга трюков
Поощряйте постепенное обучение: пусть разработчики изучают по одной новой команде в неделю, а не пытаются освоить всё сразу. Создавайте культуру, в которой программисты делятся полезными CLI-трюками и shortcuts в командных каналах.
Знание, которое живёт только в одной голове — это риск. Знание, которое задокументировано и передано — это рычаг для всей команды.
Возможно, вы уже знаете все эти трюки. Или работаете в области, где они совершенно бесполезны. Но даже если этот конкретный набор трюков не подходит вам — у вас наверняка есть собственный арсенал, накопленный за годы, который делает вашу работу легче.
Как накапливать трюки системно
Знать о важности мелких трюков — одно. Систематически их накапливать — другое.
Практический workflow:
graph LR
A[Наткнулся на трюк] --> B[Попробовал в деле]
B --> C{Работает?}
C -->|Да| D[Записал в TIL]
C -->|Нет| E[Понял почему — тоже записал]
D --> F[Поделился с командой]
E --> F
F --> G[Стало частью культуры]
Изучайте open-source проекты на GitHub, чтобы учиться у опытных разработчиков. Помните: продуктивность — это непрерывный путь, и важно регулярно пересматривать и адаптировать свои практики, чтобы найти то, что работает лучше всего для вас.
Заключение
Большая часть эффективного инжиниринга — это накопление небольших самородков знаний. Это не означает, что глубокие знания архитектуры или алгоритмов не важны. Они критичны. Но именно мелкие трюки — ctrl+r с fzf, git bisect, guard clauses, правильный выбор структуры данных — это то, что отличает разработчика, который постоянно «застревает», от того, кто движется плавно.
Ключевые выводы:
- Накапливайте осознанно — ведите TIL, записывайте каждый новый трюк
- Делитесь с командой — знание в одной голове умирает вместе с уходом человека
- Не игнорируйте инструменты — fzf, sed, git bisect окупятся за дни
- Читаемость важнее краткости — guard clauses и понятные имена снижают когнитивную нагрузку
- Измеряйте перед оптимизацией — не угадывайте, где узкое место
Хороший инженер — это не тот, кто знает всё. Это тот, кто знает, где искать и что искать. А ещё — у кого есть нужный трюк под рукой в нужный момент.