Битмап / словарь разработчика
510 subscribers
71 photos
1 video
71 links
Всё, что должен знать настоящий сеньор — короткие, но ёмкие заметки о разработке, инструментах, практиках, бизнесе. Выходят каждый день. Подписывайся!
加入频道
Пятница! Наработались уже? 🙃
Кидаем мемы в коменты!
😁9
SELECT FOR UPDATE — способ избежать состояния гонки (race condition) и взаимных блокировок в UPDATE, исполняющихся одновременною

Поддерживается в Postgres, MySQL c InnoDB, Oracle.

📚 Например, пользователь покупает товары 1 и 4 в интернет магазине, и нам надо обновить остатки в БД:
BEGIN;

SELECT *
FROM product_qty
WHERE product_id IN (1,4)
ORDER BY product_id
FOR UPDATE;

UPDATE product_qty
SET qty = qty - 1
WHERE product_id IN (1,4);

COMMIT;

🎯 Как это работает:

1️⃣ начинаем транзакцию

2️⃣ делаем SELECT ... FOR UPDATE: обновляем несколько строк, значит нужно использовать ORDER BY

3️⃣ дальше обычный UPDATE

4️⃣ наконец, COMMIT, чтобы завершить транзакцию и снять блокировки

Без ORDER BY в п.2 одновремено исполняющиеся транзакции могут попытаться взять блокировки в разном порядке, что может привести к дедлоку.

⚠️ В зависимости от уровня изоляции транзакций, другие SELECT без FOR UPDATE могут получить устаревшие значения.

🔗 https://ru.wikipedia.org/wiki/Select_for_update
👍13
Транзистор — полупроводниковый компонент, который используется для усиления и преобразования аналоговых сигналов (например, звука), а также в качестве переключателя (ключа, switch) для цифровых сигналов.

📅 Изобретен в 1947 году в Bell Labs тремя учеными: Джоном Бардином, Уолтером Браттейном и Уильямом Шокли.

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

🥇 Его создатали получили за своё изобретение Нобелевскую премию по физике в 1956 году.

Количество транзисторов в процессорах увеличилось от всего 2,250 штук в Intel 4004, выпущенном в 1971 году, до сотен миллиардов в самых современных процессорах.

Их размеры за это же время уменьшились до всего лишь десятков атомов: транзистор произведённый по 5-нм техпроцессу имеет размер около 70 атомов в ширину.

А вот как выглядит первый в мире транзистор ⬇️

🔗 https://www.youtube.com/watch?v=xvrjIJw3OSU
👍11
🤗 На прошлой неделе мы писали про:

- Задача двух генералов
- Сериализация
- Парное программирование
- DFS
- Lean-стартап
- Same-origin policy
- JSON5
- SELECT FOR UPDATE
- Транзистор

❤️‍🔥 Может, уже что-то пригодилось?
🔥6👍2
Десериализация — воссоздание объекта или структуры данных в памяти из его представления в виде строки байт/символов. Обратный сериализации процесс.

В отличие от парсинга, который обычно работает на произвольных входных данных — например, создаёт AST (abstract syntax tree) из исходного кода, десериализация чаще подразумевает использование определённой схемы.

Очевидно, что JSON или XML не ограничивают схему — потребуется JSON Schema или подобное решение.

🔍 Или можно попробовать взять protobuf, где типы обязательны. Создадим вот такой channel.proto:
syntax = "proto3";

message Channel {
string handle = 1;
int32 subscribers = 2;
}

Скомпилируем его для использования в python: protoc channel.proto --python_out=.

А затем десериализуем строку байт в объектное представление этого типа:
import channel_pb2

channel = channel_pb2.Channel()
channel.ParseFromString(b'\n\x07@bitmap\x10\x90N')

print(channel)

# handle: "@bitmap"
# subscribers: 10000


🔗 https://ru.wikipedia.org/wiki/Десериализация
👍2
Суррогатный ключ — сгенерированный уникальный идентификатор строки в реляционной БД.

💎 Зачем они нужны?

Скажем, в таблице Users натуральным ключом может быть:
email или phone
username
• комбинация first_name, last_name, birthday

⛔️ Натуральные ключи имеют недостатки:

• при обновлении ключа придётся обновлять и связанные таблицы

• требования к уникальности меняются: бизнес может разрешить разным клиентам использовать один email или телефон

• их опасно использовать в публичных URL, API и т.п.

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

• они гарантированно уникальны
• просты в использовании
• не меняются вместе с данными
• индексы по ним обычно работают быстрее

📖 Суррогатный ключ можно сделать из монотонно растущего INTEGER:

CREATE TABLE Users (
user_id SERIAL PRIMARY KEY,
username VARCHAR(255),
email VARCHAR(255) NOT NULL,
);

Или же взять рандомный или около-рандомный идентификатор, например, UUID.

🔗 https://ru.wikipedia.org/wiki/Суррогатный_ключ
👍8
Пивот (pivot) — это серьёзное изменение в бизнес-модели или стратегии стартапа.

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

• продукт и его позиционирование
• целевую аудиторию
• способ привлечения и удержания клиентов

Пивоты важно совершать вовремя, пока есть ресурсы, и на основе обратной связи от реальных пользователей.

🔑 Ключевая задача разработки: уметь быстро превращать продукт из ужа в ежа и докатывать изменения до пользователей.

📚 Например, ваш стартап изначально делал приложение для фитнеса, ориентированное на профессиональных спортсменов.

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

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

🔗 https://ru.wikipedia.org/wiki/Пивот
👍5😁4
Stack overflow — ошибка, когда программа пытается использовать больше памяти на стеке, чем разрешено операционной системой.

📌 Обычно случается при:

• слишком большой глубине рекурсивных вызовов
• большом количестве локальных переменных

📖 Например, на моей MacOS максимальная глубина стека — 8172 Кб (ulimit -s). Если какая-то программа попробует использовать больше, ОС прервёт её выполнение.

Скомпилируем простейшую программу:

#include <stdio.h>

void go(int n) {
printf("%d\n", n);
go(n + 1);
}

int main() {
go(1);
return 0;
}

без оптимизаций (gcc -o test test.c) и запустим:

...
261471
[1] 78367 segmentation fault ./test

Программа попыталась занять больше памяти на стеке, чем разрешено ОС, и была завершена.

Если увеличить размер стека, например, до 16 Мб (ulimit -s 16384), то ошибка случится позже.

А если включить оптимизации через флаг -O2 в gcc, то она сможет работать бесконечно, т.к. комплиятор "развернёт" рекурсию в цикл — cм. комментарии.

🔗 https://en.wikipedia.org/wiki/Stack_overflow
🔥5
sort — это утилита в unix-подобных ОС для сортировки строчек в текстовых файлах.

🧩 Полезные ключи:

-t, — указать разделитель колонок ,
-k5,5 — сортировка по 5-й колонке
-n — числовая, а не лексикографическая (алфавитная) сортировка
-g — поддержка чисел с плавающей запятой
-r — обратная сортировка

📚 Возьмём файл с заказами orders.csv:
id,fname,lname,pid,qty,date,addr,price
1,Иван,Иванов,101,2,2024-09-01,Ленина 123,4000
2,Анна,Смирнова,202,1,2024-09-02,Пушкина 45,1999
3,Борис,Петров,303,3,2024-09-03,Гоголя 78,5998
4,Ольга,Кузнецова,404,1,2024-09-04,Чехова 90,2999
5,Алексей,Морозов,505,2,2024-09-05,Толстого 123,5000

Отсортируем по цене: sort -t, -k8,8nr orders.csv.

По фамилии: LC_ALL=C.UTF-8 sort -t, -k3,3 orders.csv.LC_ALL=C.UTF-8 необходим для поддержки юникода.

🌟 Как и другие unix-утилиты, sort удобно объединять с другими командами через |.

Например, отсортируем заказы по pid и возьмём только 3 поля: sort -t, -k4,4 orders.csv | cut -d, -f4,3,8

🔗 https://ru.wikipedia.org/wiki/Sort_(Unix)
👍6
hash в python позволяет получить хэш любого неизменяемого объекта, например, int, float, строки или tuple.

Скажем, hash('@bitmap18 лучше всех') == -952311228443755449.

🎯 Используется в словарях (dict), чтобы определить, где хранится значение (в каком bucket) для ключа, и множествах (set), чтобы понять, есть ли в нём данный ключ.

Также можно определить дандер-метод __hash__ для любого класса.

📖 Скажем, у нас есть класс Customer, и хочется создать список пользователей без дубликатов.

Для этого отлично подойдёт set():
class Customer:
def __init__(self, id, email):
self.id = id
self.email = email

def __hash__(self):
return self.id

customers: Iterable[Customer] = get_customers()
unique_customers = set(customers)

Без заданного Customer.__hash__ получилось бы создать set, только используя идентификаторы напрямую:
unique_customers = set(c.id for c in customers)

Что, конечно, менее элегантно.

🔗 https://www.programiz.com/python-programming/methods/built-in/hash
👍5
Мне кажется, это очень хорошо!

А вы говорите "на русском"?
🏆9😁5
IBM PC (5150) — легендарный персональный компьютер, выпущенный IBM в 1981 году.

📝 Спецификации:
• Процессор Intel 8088 с частотой 4,77 МГц
• Оперативная память: 16 или 64 Кб, с возможностью расширения до 640 Кб
• Постоянная память: 1 или 2 дисковода для 5,25" дискет

Несмотря на существование других ПК (например, Altair 8800 или Apple I), именно IBM PC завоевал рынок и стал тем устройством, которое массово покупали для бизнеса и дома.

🎖️ Для сравнения, IBM продавала по 200 тысяч компьютеров в месяц уже во второй год его существования, в то время как Apple I купили всего около 200 раз.

Завоевать рынок удалось, вероятно, по нескольким причинам:

Открытая архитектура, благодаря которой появилось огромное количество комплектующих и клонов
• Простота и доступность MS-DOS, которую IBM продавала под названием PC-DOS, а Microsoft в то же время могла продавать конкурентам IBM
Сильный маркетинг и сам бренд IBM

❤️ Посмотрите интересную документалку про IBM PC:

🔗 https://www.youtube.com/watch?v=0PceJO3CAGI
👍52
🌟 Вот что было на прошлой неделе:

- Де­сериализация
- Суррогатный ключ
- Пивот
- Stack overflow
- sort
- hash() в Python
- IBM PC

🔥 А вам что понравилось?
🔥4
А тем временем, канал уходит на каникулы!
До связи 👋
👍11🎉91
Media is too big
VIEW IN TELEGRAM
Попробовал в качестве редактора кода Zed, рекомендую!
Летит с полпинка с удобной AI-интеграцией, есть REPL-режим для многих языков, всё быстро-краcиво.

PS Обычно пользовался VSCode, но что-то он начал утомлять своей монструозностью.
👍3🤔1
Помогаю классному UK стартапу найти фулстек-разработчика в команду. Ребята делают AI-помощника в сфере employment law.

- Удалённая фултайм-позиция на долгий срок.
- Современный стек: Next.js, Strapi и MySQL, DigitalOcean, интеграции в несколько сервисов вроде Pipedrive CRM.
- В команде ещё один фулстек, несколько разработчиков на контракте.
- Работать можно откуда угодно, получать деньги в фунтах банковским переводом. В РФ платить не смогут.
- Общение в команде на английском
- До £80k в год для подходящего кандидата

Дальше слово Дмитрию, Head of Operations:

Мы делаем революционный продукт, который потенциально изменит employment law в ЮК и Европе через пару лет. У нас хорошая команда с правильной культурой. Мы слушаем всех, не ругаем за ошибки, если они признаются и служат почвой для выводов, не держим в команде токсичных людей, приветствуем инициативы и хотим, чтобы каждый человек делал вклад в конечный продукт.

У нас год преимущества над всеми ИИ-legal стартапами для физических лиц, не SaaS для корпораций. За спиной юридическая компания с 10-летним опытом, разработка ИИ решений с 2019 (мы пробовали разрабатывать модели сами). Мы четко понимаем свой product-market fit.


Нам важно умение объясняться с non tech людьми и разговаривать в плоскости бизнеса, логики и здравого смысла вместо просто технического языка. Нужен человек, который понимает зачем делается продукт и для кого.

Пересылайте сообщение знакомым, которым позиция может подойти.

Резюме шлите мне в личку: @oleggromov 🙏
🔥1
Этот простой способ поможет вам...

Думаю каждый раз, когда пишу код:
- А тут взять существующий тип или создать новый?
- А вдруг в базе NULL, потому что я схему без гарантий сделал, а мне нужно значение?
- Вернуть ошибку или как-то обработать?

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

Теперь в начале работы я пишу себе небольшой TODO. Прям буквально по пунктами, что нужно сделать. Особенность каждого из этих пунктов в том, что я отлично понимаю, как его сделать. Достать ID из payload — да пожалуйста. Дифнуть 2 слайса — util.SliceDiffRight наготове.

Кайф в том, что такой подход позволяет работать по "прогрессивному джипегу". В задаче обычно 80-90% очевидных шагов, а над оставшимся нужно поразмышлять. Но если сразу схватиться кодить, то есть шанс перепутать одно с другим и потратить кучу времени на какую-то ерунду.

И вот, всего каких-то полтора десятилетия — и я допёр до работающего процесса.

👍 всегда так делаю
❤️ кайф, полезно
🌚 код пусть агенты пишут
4👍1
Кстати. Заметки про код в формате как было пока выходить не будут, как вы уже догадались. Поэтому подписывайтесь на основной канал t.me/gromov_com
Чего не могу создать, того не понимаю — так Ричард Фейнман говорил.

John Ousterhout, автор курса CS 190: Software Design Studio в Стенфорде и прекрасной книги A Philosophy of Software Design, учит студентов на своём курсе так же: даёт задание написать реализацию протокола Raft или текстового редактора, проводит код-ревью и отправляет дорабатывать.

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

Пару лет назад, когда у меня был перерыв в работе, я решил вспомнить C и написать простейшую хешмапу, динамические массивы и парсер JSON (ссылка). До этого баловался и "свой реакт" делал, HTML-парсеры всякие.

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

Решил поделиться размышлениями, т.к. попалась хорошая статья с десятком идей для реализации: ядро ОС, виртуальная машина, компилятор, async-рантайм, эмулятор NES и проч. Правда, написать эмулятор Нинтендо за 3 недели (автор даёт свою оценку каждому проекту) кажется нереальным.

Может только кажется? Как только появится время, обязательно попробую ❤️
🔥3
AI-революция в разработке софта

Все только и твердят о ней. Половина новостей на HackerNews про AI/LLM, деньги поднимают только AI-cтартапы, причём какими-то неприличными раундами. Агенты и копайлоты повсюду. Я согласен с оценкой "AI изменит разработку софта"; вероятно, даже уже изменил. И сам очень стараюсь победить формировавшиеся десятилетиями привычки и использовать LLM для всё большего количества тупых или неинтересных мне задач. Это всё-таки процентов 80-90 программирования.

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

🫣 Пример с работы: разработчик несколько дней подряд говорит, что работает над задачей, в последний день отсылает PR, где десяток комитов на полторы тысячи строк сделаны за 2 часа. Глаз цепляется за сообщения об ошибках с эмоджи (этого мы не делаем) и на русском (это провал, проект полностью англоязычный). Говорит, что "курсор написал", а русский язык "перевести забыл".

Да, хорошо, курсор написал — но он не проверил, а на ревью отправил. Мне, как техлиду, такой код зачем? Я и сам так написать могу.

🫠 Пример с собеседований: парень достаточно бодро начинает решать задачку, исследует доки на API, в это время копайлот в режиме агента создаёт ему шаблон проекта, добавляет всякие зависимости. Я впечатлён: выглядит как очень толковый, разумный подход.

Шаблон создан, какие-то кусочки кода написаны, разработчик тем временем путается в синтаксисе destructuring в JS (найм на JS/TS позицию) и, что ещё смешнее и печальнее, долго возится с отладкой ошибки от его собственной (ну, копайлотом написанной) ручки. Потому что там ответ от внешнего API обёрнут в ответ от cобственного бэкенда, и ошибка где-то по пути потерялась. Интуиции посмотреть именно туда, разумеется, нет, потому что код-то писал не он!

Закончить задачу он не успел, интервью не прошёл. Хотя люди, которые пишут код сами, успевают.

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

Если допустить — а это гигантское допущение!, — что код писать будут только машины, нам всё-таки придётся его читать, ведь ответственность не может быть на машине. А если самому не писать, то скоро и понимать разучишься. Причём происходит это, видимо, с той же пугающей скоростью, с какой Т9 убил орфографию, а телефоны — пунктуацию в сообщениях.

Что думаете об AI-революции в нашей профессии?
👍5