Битмап / словарь разработчика
510 subscribers
71 photos
1 video
71 links
Всё, что должен знать настоящий сеньор — короткие, но ёмкие заметки о разработке, инструментах, практиках, бизнесе. Выходят каждый день. Подписывайся!
加入频道
👍 git bisect — это способ найти коммит с ошибкой в git-репозитории.

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

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

🔍 Например, вы знаете, что в текущем HEAD-коммите баг есть, а в версии 3.5 его не было.
git bisect start
git bisect bad
git bisect good v3.5

Потом, на каждом шаге, проверяйте наличие бага в данной версии и используйте git bisect good или git bisect bad.

Остановить процесс в любой момент поможет git bisect reset.

🔗 https://git-scm.com/book/ru/v2/Инструменты-Git-Обнаружение-ошибок-с-помощью-Git#r_binary_search
🔥92
🚩 Xerox Alto — это первый компьютер, который предложил пользователям графический интерфейс.

Он произвёл настоящую революцию: вместе с GUI (graphic user interface) появилась концепция окон и пиктограмм (иконок), с которыми можно взаимодействовать с помощью мышки.

Его разработали в 1973 году в исследовательском центре Xerox PARC, а одним из главных разработчиков был Alan Key (снова он!).

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

P.S. Любопытно, что Xerox произносится по-английски "зиракс", с ударением на первый слог, а вовсе не "ксерокс" 🤪

🔗 https://www.youtube.com/watch?v=M0zgj2p7Ww4
🔥5
Спагетти-кодом называют плохо структурированный код, в котором сложно проследить порядок исполнения, взаимосвязи, отделить важное от неважного.

У него есть множество разных признаков:

1️⃣ перемешаны бизнес-логика и представление, "чистая" и императивная часть

2️⃣ взаимозависимость компонентов: всё зависит от всего, нет явной иерархии и слоёв

3️⃣ нарушена инкапсуляция, отсутствуют или неправильно созданы абстракции (типичный PHP)

4️⃣ состояние разбросано по всей программе, не получается изолировать разные компоненты

5️⃣ глубоко вложенные условия, циклы, callback-функции (классический jQuery)

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

📝 Например, вот кусочек jQuery-кода, который подходит под описание спагетти-кода.

Или вот чей-то кусок кода для Wordpress, который выводит комментарии к посту.

Общее у них то, что ничего невозможно понять 💩 Не пишите так.

🔗 https://ru.wikipedia.org/wiki/Спагетти-код
👍4🤔1
Amazon S3 (Simple Storage Service) — сервис хранения "объектов".

В отличие от файлов в иерархической файловой системе, объекты хранятся в key-value хранилище с определённым именем (bucket).

В нём нет каталогов, а "пути" являются частью ключа-строки.

🤌 Объекты нельзя модифицировать, только заменить новой копией. Например, не получится открыть текстовый файл и изменить в нём один символ.

S3 является де-факто стандартом для хранения разной статики: видео, фото, аудио, бэкапов. Его API также поддерживается большинством аналогов.

❤️ Плюсы: надёжность, практически бесконечная масштабируемость.

⛔️ Минусы: S3 может оказаться очень дорогим для хранения данных большого объёма, особенно при неверном исплоьзовании. Зависимость (вендор-лок) от AWS.

Чтобы сэкономить, рассмотрите более "холодные" классы хранения (storage classes), а также взгляните на Backblaze B2.

Используйте CDN, например, Cloudfront или Cloudflare, чтобы уменьшить egress fees.

🔗 https://yandex.cloud/ru/docs/storage/s3/api-ref/
4👍1
CORS (Cross-Origin Resource Sharing) — это способ ограничения доступа к ресурсам веб-сервера (картинкам и пр.).

Включает в себя набор HTTP-заголовков, которые можно использовать в ответе, например:

Access-Control-Allow-Origin для указания разрешённого домена
Access-Control-Allow-Methods для разрешённых HTTP-методов

📌 Только современные браузеры учитывают CORS-ограничения.

CORS нужен, чтобы разрешить кросс-доменные XHR-запросы, например, в API, а также ограничить нагрузку на сервер.

🧐 Не путайте CORS и CSP, Content Security Policy, которые используется для ограничения со стороны страницы (см. следующий пост).

📚 Например, вы делаете редактор мемов и загружаете картинку https://i.chzbgr.com/full/9699850496/h4640AF11 через XHR, чтобы вставить в canvas.

Браузер делает запрос, и получает следующий заголовок в ответе:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: i.chzbgr.com

У вашего сайта другой домен, поэтому картника не загрузится.

🔗 https://ru.wikipedia.org/wiki/Cross-origin_resource_sharing
🔥6👍4
CSP (Content Security Policy) — это способ разрешить странице загружать только определённые ресурсы.

Ограничения выставляются через HTTP-заголовок Content-Security-Policy или meta-теги.

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

Так же, как и CORS, CSP учитываются только современными браузерами.

🤔 Но, в отличие от CORS, CSP-ограничения работают наоборот: они указываются для страницы, а не ресурса.

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


Вы хотите начать показывать рекламу Яндекса, которая грузится с an.yandex.ru, поэтому вам нужно обновить заголовок:


⚠️ Лучше явно указывать директивы script-src, style-src, img-src и подобные вместо default-src.

🔗 https://developer.mozilla.org/ru/docs/Web/HTTP/CSP
👍10🤔1
CAC (Customer Acquisition Cost) — стоимость привлечения клиента.

Расчитывается по формуле: CAC = затраты на маркетинг и продажи / кол-во привлечённых клиентов.

🧩 Используется при планировании и анализе маркетинговых кампаний, в юнит-экономике.

Также полезно держать в уме CAC при планировании cтоимости сетки продуктов.

Для стартапов важно отношение CAC:LTV (life-time value, сколько денег принесёт клиент компании за всё время) — чем оно меньше, тем лучше.

Если CAC > LTV, то юнит-экономика не сходится, а значит бизнес нестабилен, не может расти и, скорее всего, долго не протянет.

🔍 Допустим, SaaS-компания тратит в месяц на маркетинг и отдел продаж $50,000.

В среднем ей удаётся привлекать 200 новых клиентов в месяц, то есть:
CAC = $50,000 / 200 = $250

Если при этом средний чек cоставляет $1000, то у компании всё в порядке.

Если же они продают B2C продукт со стоимостью подписки в $10, то всё очень плохо ☠️

🔗 https://en.wikipedia.org/wiki/Customer_acquisition_cost
👍5
А еще есть программисты, которые не используют copilot!
😁8
Ретеншн (retention, удержание клиентов) — это способность компании сохранять клиентов на протяжении определённого времени.

🎯 Удержание клиентов важно в отраслях, где существуют повторные продажи или продают подписки.

Retention — показатель, обратный churn, оттоку клиентов. Если компания теряет в месяц 10% клиентов (сhurn), то её retention составляет 90%.

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

🤷‍♀️ Не путайте retention с NPS (net promoter score — вероятность, что клиент будет рассказывать про ваш продукт).

📝 Например, в компании, продающей онлайн-курсы считают retention по когортам:
| Когорта | Янв | Фев | Мар |
|---------|-----|-----|-----|
| Январь | 100 | 80 | 70 |
| Февраль | 120 | 90 | 70 |

Видно, что январская когорта более лояльна компании, чем февральская: в ней 70% пользователей остались после 3 месяцев (а не 58%).

🔗 https://ru.wikipedia.org/wiki/Удержание_клиентов
👍6
Canary — это способ выкатки новых версий ПО только для маленькой части пользователей.

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

🔥 Canary-релизы помогают получить быструю обратную связь и уменьшают цену ошибки.

Пользователи, которые получат canary-версию, могут выбираться с помощью:

🦜 фича-флагов (feature flag)
🦅 ID, тарифа, геолокации и т.д.
🦩 сервера, на котором находится их сессия

💔 Минусы: сложность инфраструктуры и настройки, мониторинга результатов. Можно поломать привычный UX.

🔍 Представьте, что вы работаете в команде Google Chrome.

Ваша фича попадает в релизную ветку и следующей ночью оказывается в Canary-cборке.

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

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

🔗 https://yandex.cloud/ru/docs/api-gateway/concepts/extensions/canary
3🤔1
RPC (remote procedure call, удалённый вызов процедур) — это способ клиент-серверного взаимодействия, при котором клиент отправляет команды серверу и получает их результаты.

Может работать поверх HTTP, HTTP/2, TCP или UDP. Самые известные реализации RPC: XML-RPC, JSON-RPC, gRPC, Apache Thrift и его форк fbthrift, trpc.

Запросы и ответы сериализуются в текстовые (JSON, XML) или бинарные форматы (protobuf).

🏆 Плюсы: более гибкий в отличие от, например, REST, который оперирует "ресурсами" и строго привязан с CRUD-cемантике.

⚠️ Минусы: сильная взаимная зависимость клиента и сервера.

🔍 Например, используем OpenWeatherMap API, выполненному в виде JSON-RPC:
curl https://api.openweathermap.org/data/3.0/onecall/overview?lon=-11.8092&lat=51.509865&appid={key}

И получаем ответ:
{
"lat": 51.509865,
"lon": -0.118092,
"tz": "+01:00",
"date": "2024-05-13",
"units": "metric",
"weather_overview": "The current weather is overcast..."
}


🔗 https://ru.wikipedia.org/wiki/Удалённый_вызов_процедур
👍101
iCalendar — стандартизированный в RFC 5545 формат описания календарных данных:

📅 встречи и их настройки
📝 задачи
🔔 напоминания
🌴 выходные, отпуска и т.п.

Это текстовый формат, который используется в Google и Apple Calendar, MS Outlook, для импорта/экспорта и обмена календрными событиями, а также в их API.

📝 К примеру, так задаётся день рождения одного из моих друзей:
BEGIN:VEVENT
DTSTART;TZID=Europe/London:20240602T080000
DTEND;TZID=Europe/London:20240602T090000
RRULE:FREQ=YEARLY
DTSTAMP:20240901T133201Z
UID:[email protected]
CREATED:20240602T195932Z
LAST-MODIFIED:20240602T195932Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:День рождения друга
TRANSP:OPAQUE
END:VEVENT

Обратите внимание на RRULE, который задаёт частоту повторения.

Кроме RRULE есть также RDATE для указания списка дат, а таже EXRULE и EXDATE для задания исключений.

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

🔗 https://datatracker.ietf.org/doc/html/rfc5545
👍113
— Давай, разработчик, скажи это снова.
— Всё почти готово.
— Будет в проде через 2 дня 🤣
😁10
ngrok — это утилита, которая позволяет создавать HTTPS- или TCP/TLS-тоннели до локального компьютера.

Например, вы запускаете ngrok http 8080 и получаете публичный URL вида https://5bda-92-236-115-181.ngrok-free.app/, который доступен кому угодно в интернете.

Это подходит для тестирования локальных версий веб-сервисов без выкладки их куда-либо.

🚀 Плюсы: ngrok удобный, не требует настройки, существует в бесплатной версии.

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

Мне лично больше нравится Cloudflare Tunnels, которые работают через cloudflared.

📝 Создание тоннелей выглядит практически идентично ngrok:
cloudflared tunnel --url http://localhost:8080

Их также можно прикрепить к поддомену, чтобы получить постоянный URL. Только не оставляйте такой тоннель открытым надолго 🤭

🔗 https://ngrok.com/docs
👍15
Поэтапные, или пошаговые Docker-сборки ускоряют процесс и делают финальные образы меньше.

Плюсы: явное разбиение на этапы позволяет сохранить артефакты сборки в отдельном образе.

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

👎 Минусы: чуть-чуть дольше, сложнее в настройке, особенно если проект использует какие-то глобальные, недоступные в урезанном образе зависимости — например, imagemagick.

📖 Допустим, вы собираете Node-приложение и разбиваете Dockerfile на части:
FROM node:22 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/build ./build
CMD ["node", "build/index.js"]

Обратите внимание на AS build, а также явное копирование из этого слоя в компактный alpine-образ.

🔗 https://docs.docker.com/develop/develop-images/multistage-build/
👍51🤔1
Интерактивный ребейз — мощная штука, которая позволяет:

squash — совместить несколько комитов
drop — исключить из истории
edit — отредактировать сообщение и т.д.

В отличие от обычного git commit --amend, с помощью git rebase -i можно изменить любой коммит.

🫣 Коммиты в git неизменяемые, поэтому даже небольшое изменение истории потребует делать форс-пуши: git push --force, а лучше git push --force-with-lease.

Это не порадует ваших коллег, а также, как и любой rebase, может привести к длинному циклу исправления конфликтов.

👌 Я обычно использую git rebase -i в feature-ветках, чтобы сделать историю комитов более логичной и удобной для восприятия.

В качестве альтернативы можно использовать squash & merge в пул-реквестах на GitHub, если вы им пользуетесь.

📖 К примеру, чтобы изменить последние 3 коммита, используйте:
git rebase -i HEAD~3

Обратите внимание, что коммиты перечислены в обратном порядке.

🔗 https://git-scm.com/book/ru/v2/Инструменты-Git-Перезапись-истории#r_changing_multiple
🔥9👍1
ARPANET — это компьютерная сеть, которая была запущена 29 октября 1969 года между 3 университетами в Калифорнии (UCLA, UCSB и Stanford) и университетом штата Юта.

Первым сообщением, доставленным через сеть, стало lo (часть слова login), но после этого передача оборвалась 😁

Его отправили с компьютера в UCLA (университет в Лос-Анджелесе) на компьютер в Menlo Park в Stanford.

Разработка велась в течение 1960-х годов подразделением экспериментальных проектов DARPA (Defense Advanced Research Projects Agency) американского министерства обороны.

📝 Посмотрите видео, в котором профессор UCLA показывает ARPANET-свитч в корпусе "миникомпьютера" Honeywell DDP-516, с которого было отправлено первое сообщение 👇

🔗 https://www.youtube.com/watch?v=yU9oMOcRsuE
👏7
🌟 Посты прошедшей недели:

- Спагетти-код
- Amazon S3
- CORS
- CSP
- CAC
- Retention
- Canary
- RPC
- iCalendar
- ngrok
- Поэтапные Docker-сборки
- git rebase -i
- ARPANET

👀 А вам что понравилось?
👍8
Задача двух генералов — мысленный эксперимент о синхронизации состояния 2 систем, соединённых ненадёжным каналом связи.

⚔️ Суть: два генерала подвели армии к вражескому городу и договариваются об атаке.

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

☠️ Посыльных может перехватить враг, а значит гарантии доставки сообщения нет.

📚 Представьте, что военачальник Скобелев пишет генералу Драгомирову:

С: атакуем на рассвете 9 сентября.

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

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

Д: подтверждаю атаку 9 сентября на рассвете.

Но и этого посыльного могут поймать, и генералы не смогут скоординировать атаку.

Получается, невозможно гарантировать доставку 100% сообщений и полный консенсус через ненадёжный канал связи.

🔗 https://ru.wikipedia.org/wiki/Задача_двух_генералов
👍7🔥1
Сериализация — преобразование структуры данных или объекта в памяти в последовательность байт.

🚨 Важно, что сериализованный объект можно восстановить без потерь с помощью десериализации (парсинга).

Сериализация происходит в момент передачи данных между сервисами в сети, перед сохранением объекта в БД или на диск.

🔗 Распространнёные форматы сериализации: JSON и YAML, XML, protobuf.

📚 Например, словарь в python превращается в JSON:
import json

c = {
'handle': '@bitmap18',
'subscribers': 10000,
}

print(json.dumps(c))
# {"handle": "@bitmap18", "subscribers": 10000}

⚠️ Ещё одно важное свойство сериализации: переносимость формата.

JSON, XML, protobuf и другие форматы стандартизированы. Их понимают сотни разных систем и языков программирования.

А вот, скажем, у PHP свой формат сериализации массивов, не являющийся кросс-платформенным.

Также не является переносимой наивная сериализация C-структур на диск в бинарном формате — хоть она и очень компактная.

🔗 https://ru.wikipedia.org/wiki/Сериализация
👍8