Это мой новый канал с заметками для разработчиков.
Я стараюсь делать их короткими, ёмкими и интересными, охватывая плюс-минус все темы, которые должен знать настоящий сеньор 💪 По крайней мере, на мой взгляд.
Заметки выходят каждый день.
Подписывайся, чтобы расширять кругозор и прокачиваться каждый день. Надеюсь, тебе понравится! 🤗
Автор — Олег Громов, программист с 15-летним стажем, тимлид, стартапер.
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Олег Громов печатает...
о программировании, стартапах, UK и о жизни в целом
🔥4
🔍 Технический долг — это плохой, неподдерживаемый код, который обычно возникает, когда разработчики идут на компромиссы с качеством под давлением руководства или заказчика:
1️⃣ плохая архитектура и преждевременные или же "протекающие" абстракции
2️⃣ непродуманные пограничные случаи (edge cases) в важной бизнес-логике, отсутствие тестов
Если активно не заниматься уменьшением техдолга, ваш код превратится в "легаси". Его будет страшно поломать, и с ним никто не захочет работать.
Стоимость поддержки и разработки поползёт вверх.
📖 Например: вы работаете над интернет-магазином, и продакт-менеджер просит вас добавить "бандлы" — группы товаров, которые продаются со скидкой.
Это нужно сделать как можно скорее, чтобы не пропустить сезон распродаж.
У вас не хватает времени на продумывание новой схемы данных и правильное заведение бандлов в БД, поэтому вы просто хардкодите идентификаторы товаров в функции
🔗 https://ru.wikipedia.org/wiki/Технический_долг
1️⃣ плохая архитектура и преждевременные или же "протекающие" абстракции
2️⃣ непродуманные пограничные случаи (edge cases) в важной бизнес-логике, отсутствие тестов
Если активно не заниматься уменьшением техдолга, ваш код превратится в "легаси". Его будет страшно поломать, и с ним никто не захочет работать.
Стоимость поддержки и разработки поползёт вверх.
📖 Например: вы работаете над интернет-магазином, и продакт-менеджер просит вас добавить "бандлы" — группы товаров, которые продаются со скидкой.
Это нужно сделать как можно скорее, чтобы не пропустить сезон распродаж.
У вас не хватает времени на продумывание новой схемы данных и правильное заведение бандлов в БД, поэтому вы просто хардкодите идентификаторы товаров в функции
get_total_price
, которая рассчитывает цену попупки.🔗 https://ru.wikipedia.org/wiki/Технический_долг
👍6🤔3👎2🔥2
🚀 Хейзенбаг (heisenbug) — это тип ошибки, которая исчезает или меняет поведение при отладке.
Название происходит от принципа неопределённости Гейзенберга, утверждающего, что сам процесс измерения может повлиять на измеряемый объект.
Хейзенбаги возникают в распределённых системах, многопоточных программах, бывают связаны с отказами железа, средой (prod, staging) или временем выполнения кода.
😭 Их сложно исправить, и даже опытные разработчики часто опускают руки, не сумев воспроизвести проблему.
📚 Пример хейзенбага:
Из-за отсутствия синхронизации между потоками значение счётчика будет отличаться от запуска к запуску.
🔗 https://ru.wikipedia.org/wiki/Гейзенбаг
Название происходит от принципа неопределённости Гейзенберга, утверждающего, что сам процесс измерения может повлиять на измеряемый объект.
Хейзенбаги возникают в распределённых системах, многопоточных программах, бывают связаны с отказами железа, средой (prod, staging) или временем выполнения кода.
😭 Их сложно исправить, и даже опытные разработчики часто опускают руки, не сумев воспроизвести проблему.
📚 Пример хейзенбага:
#include <stdio.h>
#include <pthread.h>
int c = 0;
void* inc(void* arg) {
for (int i = 0; i < 1000; ++i) c++;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, inc, NULL);
pthread_create(&t2, NULL, inc, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("%d\n", c);
}
Из-за отсутствия синхронизации между потоками значение счётчика будет отличаться от запуска к запуску.
🔗 https://ru.wikipedia.org/wiki/Гейзенбаг
👍4🔥4
❤️ Поток — единица выполнения в многозадачной ОС, позволяющая программе совершать несколько операций одновременно.
Каждый поток имеет собственный стек и регистры, но использует одно адресное пространство с другими потоками, чтобы эффективно обмениваться данными.
Потоки абсолютно необходимы в десктопных и мобильных приложениях, чтобы вычисления не блокировали отрисовку UI.
❤️ Плюсы: многопоточность значительно повышает скорость вычислений в задачах, которые можно обсчитывать параллельно.
⛔️ Минусы: неправильное управление может привести к состояниям гонки (race condition) и взаимным блокировкам (deadlock).
📝 Например, создадим несколько потоков в python:
🔗 https://ru.wikipedia.org/wiki/Поток_выполнения
Каждый поток имеет собственный стек и регистры, но использует одно адресное пространство с другими потоками, чтобы эффективно обмениваться данными.
Потоки абсолютно необходимы в десктопных и мобильных приложениях, чтобы вычисления не блокировали отрисовку UI.
❤️ Плюсы: многопоточность значительно повышает скорость вычислений в задачах, которые можно обсчитывать параллельно.
⛔️ Минусы: неправильное управление может привести к состояниям гонки (race condition) и взаимным блокировкам (deadlock).
📝 Например, создадим несколько потоков в python:
from urllib import request
from multiprocessing.dummy import Pool
urls = [
'http://python.org',
'http://python.org/about/',
'http://python.org/doc/',
'http://python.org/download/',
'http://python.org/community/',
]
pool = Pool(4)
pool.map(request.urlopen, urls)
pool.close()
pool.join()
🔗 https://ru.wikipedia.org/wiki/Поток_выполнения
👍5❤3🔥1
🚩 Хеш-таблица — структура данных, которая хранит пары ключ-значение и даёт быстрый доступ к данным по ключу.
Операции поиска, вставки и удаления элементов в
Хеш-таблица — одна из самых популярных структур данных. Она известна как ассоциативный массив, словарь (dictionary), "мапа" (map), объект (в JS) или просто массив (в PHP).
⏳ Сложность основных операций : вставка и получение элемента — от
📚 Пример использования хэш-таблицы (словаря или
При каждом обращении к словарю по ключу, он превращается в числовой ключ с помощью хеш-функции и используется, чтобы найти область в памяти, где хранится значение.
🔗 https://ru.wikipedia.org/wiki/Хеш-таблица
Операции поиска, вставки и удаления элементов в
hashmap
почти мгновенны благодаря использованию быстрой хеш-функции.Хеш-таблица — одна из самых популярных структур данных. Она известна как ассоциативный массив, словарь (dictionary), "мапа" (map), объект (в JS) или просто массив (в PHP).
⏳ Сложность основных операций : вставка и получение элемента — от
O(1)
до O(n)
, в зависимости от выбранной функции.📚 Пример использования хэш-таблицы (словаря или
dict
в терминах python):phones = {
"Oleg": "+123456789",
"Dima": "+987654321",
"Alex": "+192837465"
}
phones["Dima"] = "+564738291"
print(phones["Alex"])
del phones["Oleg"]
if "Oleg" in phones:
print("Oleg найден в телефонной книге")
При каждом обращении к словарю по ключу, он превращается в числовой ключ с помощью хеш-функции и используется, чтобы найти область в памяти, где хранится значение.
🔗 https://ru.wikipedia.org/wiki/Хеш-таблица
👍3🔥2
🚩 Хеш-функция — алгоритм, который принимает входные данные произвольной длины и преобразует их в число фиксированной разрядности.
Это число обычно представляют как шестнадцатеричную строку:
Даже небольшое изменение входных данных приводит к значительному изменению хеша.
Хеш-функции используются в алгоритмах шифрования и цифровых подписях, в хеш-таблицах, для создания контрольных сумм и уникальных идентификаторов (UUID, например).
⏳ Сложность по времени :
💾 Сложность по памяти :
👍 Плюсы: универсальность, относительно высокая скорость.
😞 Минусы: возможность коллизий, необратимость — имея хеш, восстановить исходные данные невозможно. Только перебором.
🔍 Пример использования sha256 в python:
🔗 https://ru.wikipedia.org/wiki/Хеш-функция
Это число обычно представляют как шестнадцатеричную строку:
0xC0FFEE
.Даже небольшое изменение входных данных приводит к значительному изменению хеша.
Хеш-функции используются в алгоритмах шифрования и цифровых подписях, в хеш-таблицах, для создания контрольных сумм и уникальных идентификаторов (UUID, например).
⏳ Сложность по времени :
O(1)
для вычисления хеша.💾 Сложность по памяти :
O(n)
, где n
— размер input.👍 Плюсы: универсальность, относительно высокая скорость.
😞 Минусы: возможность коллизий, необратимость — имея хеш, восстановить исходные данные невозможно. Только перебором.
🔍 Пример использования sha256 в python:
import hashlib
h = hashlib.sha256()
h.update(b'@bitmap18 - best channel on Telegram!')
# db67ff18bdcf98ae9410dbd459c19cd79c15664e39bcc10cddb163142b084b0f
print(h.hexdigest())
🔗 https://ru.wikipedia.org/wiki/Хеш-функция
👍4🔥1
🌍 CRC32 (cyclic redundancy check, 32 бит) — алгоритм для быстрого вычисления контрольной суммы.
Принимает на вход поток данных и возвращает 32-битный
CRC32 используется для проверки целостности данных в ZIP-архивах, Ethernet, жёстких дисках.
⏳ Сложность по времени :
💾 Сложность по памяти :
🥇 Плюсы: высокая скорость вычисления, простота реализации.
👎 Минусы: не защищает от преднамеренных изменений данных (алгоритм простой, и его легко "надуть"), вероятны коллизии.
📖 Для примера, функция
🔗 https://ru.wikipedia.org/wiki/Циклический_избыточный_код
Принимает на вход поток данных и возвращает 32-битный
int
.CRC32 используется для проверки целостности данных в ZIP-архивах, Ethernet, жёстких дисках.
⏳ Сложность по времени :
O(n)
, где n
— количество байт данных.💾 Сложность по памяти :
O(1)
.🥇 Плюсы: высокая скорость вычисления, простота реализации.
👎 Минусы: не защищает от преднамеренных изменений данных (алгоритм простой, и его легко "надуть"), вероятны коллизии.
📖 Для примера, функция
CRC32
на JavaScript:function crc32(str) {
let crc = -1;
for (let i = 0; i < str.length; i++) {
crc = crc ^ str.charCodeAt(i);
for (let j = 0; j < 8; j++) {
if ((crc & 1) !== 0) {
crc = (crc >>> 1) ^ 0xedb88320;
} else {
crc = crc >>> 1;
}
}
}
return (crc ^ (-1)) >>> 0;
}
// выведет 1846494140
console.log(crc32('подпишись на @bitmap18 в телеге'));
🔗 https://ru.wikipedia.org/wiki/Циклический_избыточный_код
👍6
🌍 Минимально жизнеспособный продукт (MVP, Minimum Viable Product) — это версия продукта с самым необходимым функционалом.
🔥 Задача MVP: проверить гипотезы о продукте, понять потребности пользователей и оценить спрос без больших рисков и затрат.
🤔 Не путайте MVP и прототип: оба используются для тестирования идей, но MVP должен быть полезен пользователям — а прототип может просто показывать техническую возможность реализации задумки.
📚 Например, ваш стартап разрабатывает новое мобильное приложение для заказа еды.
Вместо приложения с множеством функций ваша команда решает выпустить MVP, включащий только самое важное: выбор ресторана, просмотр меню и оформление заказа.
Это позволяет вам закончить разработку за несколько месяцев (вместо года), а бизнесу — получить обратную связь от первых клиентов и решить, стоит ли инвестировать в полноценную разработку.
🔗 https://ru.wikipedia.org/wiki/Минимально_жизнеспособный_продукт
🔥 Задача MVP: проверить гипотезы о продукте, понять потребности пользователей и оценить спрос без больших рисков и затрат.
🤔 Не путайте MVP и прототип: оба используются для тестирования идей, но MVP должен быть полезен пользователям — а прототип может просто показывать техническую возможность реализации задумки.
📚 Например, ваш стартап разрабатывает новое мобильное приложение для заказа еды.
Вместо приложения с множеством функций ваша команда решает выпустить MVP, включащий только самое важное: выбор ресторана, просмотр меню и оформление заказа.
Это позволяет вам закончить разработку за несколько месяцев (вместо года), а бизнесу — получить обратную связь от первых клиентов и решить, стоит ли инвестировать в полноценную разработку.
🔗 https://ru.wikipedia.org/wiki/Минимально_жизнеспособный_продукт
👍4🔥1
📋 Продакт-маркет фит (PMF, product-market fit) — это важный момент в развитии стартапа, когда продукт начинает хорошо продаваться.
📌 Без PMF не будет продаж, серьёзных инвестиций, а также гарантий роста и развития бизнеса.
🧐 Не путайте продакт-маркет фит с первыми продажами. PMF — это более глубокое понятие, означающее устойчивый спрос и
📝 Скажем, вы разработали приложение для составления фитнес-программ.
После первой обратной связи от пользователей вы обнаружили, что спортсмены хоть и пользуются приложением, но не готовы платить.
В погоне за PMF вы делаете пивот в сторону платных персонализированных программ. Их покупают, но привлечение клиентов остаётся дорогим.
Тогда вы фокусируетесь на новой аудитории: профессиональных фитнес-тренерах, которым нужно приложение для разработки тренировочных программ, которые готовы за него платить.
Похоже на продакт-маркет фит 🔥
🔗 https://gopractice.ru/product/product-market-fit/
📌 Без PMF не будет продаж, серьёзных инвестиций, а также гарантий роста и развития бизнеса.
🧐 Не путайте продакт-маркет фит с первыми продажами. PMF — это более глубокое понятие, означающее устойчивый спрос и
CAC < LTV
— стоимость привлечения клиента ниже, чем выручка, которую он принесёт.📝 Скажем, вы разработали приложение для составления фитнес-программ.
После первой обратной связи от пользователей вы обнаружили, что спортсмены хоть и пользуются приложением, но не готовы платить.
В погоне за PMF вы делаете пивот в сторону платных персонализированных программ. Их покупают, но привлечение клиентов остаётся дорогим.
Тогда вы фокусируетесь на новой аудитории: профессиональных фитнес-тренерах, которым нужно приложение для разработки тренировочных программ, которые готовы за него платить.
Похоже на продакт-маркет фит 🔥
🔗 https://gopractice.ru/product/product-market-fit/
🔥6
🧩 Владение кодом — это когда разработчик или команда несёт ответственность за конкретную часть кода.
Это позволяет принимать обдуманные решения по развитию, быстро исправлять ошибки, консультировать других разработчиков.
Явное владение кодом чаще встречается в крупных компаниях.
🔥 Плюсы: улучшение качества кода, ускорение процесса разработки.
⛔️ Минусы: изоляция знаний, более сильная зависимость от одного человека или команды. Избыточность для маленьких проектов.
📖 Например, в команде разработки интернет-магазина Саша отвечает за модуль аутентификации.
Он знает все нюансы его работы и может быстро вносить изменения или исправлять баги.
Когда кто-то самостоятельно вносит изменения в эту часть системы, GitHub автоматически назначает Сашу ревьюером во все связанные пул-реквесты (если в репозитории есть
🔗 https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
Это позволяет принимать обдуманные решения по развитию, быстро исправлять ошибки, консультировать других разработчиков.
Явное владение кодом чаще встречается в крупных компаниях.
🔥 Плюсы: улучшение качества кода, ускорение процесса разработки.
⛔️ Минусы: изоляция знаний, более сильная зависимость от одного человека или команды. Избыточность для маленьких проектов.
📖 Например, в команде разработки интернет-магазина Саша отвечает за модуль аутентификации.
Он знает все нюансы его работы и может быстро вносить изменения или исправлять баги.
Когда кто-то самостоятельно вносит изменения в эту часть системы, GitHub автоматически назначает Сашу ревьюером во все связанные пул-реквесты (если в репозитории есть
.github/CODEOWNERS
).🔗 https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
👍4🔥3
🧩 Код-фриз (code freeze) — это когда разработка новых фич и внесение изменений в код временно останавливаются.
Во время код-фриза команда сосредотачивается на исправлении багов и улучшении производительности, чтобы обеспечить максимальную стабильность и качество продукта.
Так делают перед очередным крупным релизом или важным запуском.
🚀 Плюсы: повышает стабильность и качество выпускаемого продукта, особенно с нечастыми большими релизами.
❌ Минусы: может замедлить внедрение новых функций. Нет особого смысла применять в простых и понятных системах или маленьких командах.
📖 Представьте, что ваша команда разрабатывает десктоп-приложение, и вы планируете выпустить 13-ю версию через месяц.
За две недели до релиза менеджмент объявляет код-фриз.
Это означает, что все новые функции откладываются, а команда фокусируется на тестировании и исправлении ошибок, чтобы убедиться, что новая версия может быть выпущена в свет.
🔗 https://ru.wikipedia.org/wiki/Заморозка_(программное_обеспечение)
Во время код-фриза команда сосредотачивается на исправлении багов и улучшении производительности, чтобы обеспечить максимальную стабильность и качество продукта.
Так делают перед очередным крупным релизом или важным запуском.
🚀 Плюсы: повышает стабильность и качество выпускаемого продукта, особенно с нечастыми большими релизами.
❌ Минусы: может замедлить внедрение новых функций. Нет особого смысла применять в простых и понятных системах или маленьких командах.
📖 Представьте, что ваша команда разрабатывает десктоп-приложение, и вы планируете выпустить 13-ю версию через месяц.
За две недели до релиза менеджмент объявляет код-фриз.
Это означает, что все новые функции откладываются, а команда фокусируется на тестировании и исправлении ошибок, чтобы убедиться, что новая версия может быть выпущена в свет.
🔗 https://ru.wikipedia.org/wiki/Заморозка_(программное_обеспечение)
❤3
🚀 Бинарный поиск (binary search) — алгоритм поиска элемента в отсортированном массиве.
На каждом шаге он ищет элемент в центре массива, а затем делит его пополам и продолжает в левой или правой половине.
Процесс повторяется, пока элемент не будет найден или не закончится массив.
Он используется в базах данных, поисковых системах и
⏳ Сложность по времени :
💾 Сложность по памяти :
❤️ Плюсы: высокая скорость поиска в больших отсортированных массивах.
👎 Минусы: требует предварительной сортировки.
📖 Пример на python:
🔗 https://ru.wikipedia.org/wiki/Бинарный_поиск
На каждом шаге он ищет элемент в центре массива, а затем делит его пополам и продолжает в левой или правой половине.
Процесс повторяется, пока элемент не будет найден или не закончится массив.
Он используется в базах данных, поисковых системах и
git bisect
.⏳ Сложность по времени :
O(log n)
.💾 Сложность по памяти :
O(1)
.❤️ Плюсы: высокая скорость поиска в больших отсортированных массивах.
👎 Минусы: требует предварительной сортировки.
📖 Пример на python:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
print(binary_search([1, 3, 5, 7, 9, 11, 13], 7))
🔗 https://ru.wikipedia.org/wiki/Бинарный_поиск
👍2
🌍 CDN (content delivery network, сеть доставки контента) — это распределённая сеть серверов, которая ускоряет доставку контента пользователям.
CDN кэширует статические файлы: изображения, видео, CSS, на edge-серверах, расположенных ближе к пользователям.
🏆 Плюсы: уменьшение сетевых задержек и увеличение скорости загрузки, что важно для любого мало-мальски популярного сайта. Снижение нагрузки на ваши веб-серверы.
😢 Минусы: дополнительные затраты на настройку и поддержание инфраструктуры, возможные сложности с кэшированием динамического контента.
📖 Скажем, вы разрабатываете новостной сайт на разных языках.
Понимая, что у вас будет большой объём трафика из разных стран, вы решаете использовать CDN (Cloudflare или Amazon Cloudfront), чтобы закэшировать картинки и видео.
Это позволит пользователям получать контент быстрее, так как он будет поступать с ближайшего к ним сервера, а вы не будете волноваться, что ваш
🔗 https://ru.wikipedia.org/wiki/Сеть_доставки_контента
CDN кэширует статические файлы: изображения, видео, CSS, на edge-серверах, расположенных ближе к пользователям.
🏆 Плюсы: уменьшение сетевых задержек и увеличение скорости загрузки, что важно для любого мало-мальски популярного сайта. Снижение нагрузки на ваши веб-серверы.
😢 Минусы: дополнительные затраты на настройку и поддержание инфраструктуры, возможные сложности с кэшированием динамического контента.
📖 Скажем, вы разрабатываете новостной сайт на разных языках.
Понимая, что у вас будет большой объём трафика из разных стран, вы решаете использовать CDN (Cloudflare или Amazon Cloudfront), чтобы закэшировать картинки и видео.
Это позволит пользователям получать контент быстрее, так как он будет поступать с ближайшего к ним сервера, а вы не будете волноваться, что ваш
nginx
не справится с пиковой нагрузкой.🔗 https://ru.wikipedia.org/wiki/Сеть_доставки_контента
👍1