Дневник тимлида C++
27 subscribers
46 photos
1 video
1 file
14 links
Откровенные заметки из жизни лида C++ разработчиков. Ситуации, проблемы, открытия и решения. Для обсуждения заходите в чатик https://t.me/teamLeadDiaryChat
Download Telegram
Иллюзия 90% уверенности

Эксперимент: людям дали тест из 10 вопросов. Нужно указать диапазон ответа с «90% уверенностью».
Результаты:

Средний балл: 2.8 из 10
Только 2% получили 8+ правильных ответов
Никто не ответил верно на все 10

Когда я впервые прочитал про этот эксперимент, подумал:
Ну это же они, обычные люди. Мы-то в IT поумнее


Провёл похожий тест в своей команде. Угадайте результат? Правильно, точно такой же провал 😅

Вывод:
интуитивное ощущение «90% уверенности» на деле соответствует примерно «30% уверенности».

То же самое в проектах. Команды регулярно представляют графики с «90% уверенностью» и регулярно их превышают — в 50-60% случаев, а не в 10%.

Был у меня один тимлид, золотой человек. На каждой планёрке: «Я на 90% уверен, что закончим к пятнице». Знаете, сколько раз из десяти он укладывался? Три. ТРИ, Карл! Это вообще 30%, а не 90%.
Я его спросил:
Слушай, а ты понимаешь, что значит 90%?

Он посмотрел на меня и честно ответил:
Ну... я просто так чувствую

Вот она, вся наша «уверенность» 🙃

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

Сейчас, когда кто-то в команде говорит «я на 90% уверен», я достаю блокнот и говорю:
Отлично! Давай запишем. Будем проверять калибровку твоей уверенности

.Обычно после этого люди начинают говорить более честно: «Ну... наверное, половина на половину» 😁

А вы когда-нибудь ловили себя на таком? Говорили «я уверен на 90%», а потом оказывалось совсем не так?
2
Конус неопределённости

Точность оценок меняется предсказуемо на разных этапах проекта.

Погрешность по этапам:


Первоначальная концепция:
±300% (диапазон 0.25x - 4x)
=> Оценка «100 дней» = реально 25-400 дней

Утверждённое определение:
±100% (0.5x - 2x)
=> «100 дней» = 50-200 дней

Завершённые требования:
±50% (0.67x - 1.5x)
=> «100 дней» = 67-150 дней

Детальное проектирование:
±10% (0.9x - 1.1x)
=> «100 дней» = 90-110 дней

Помню встречу с инвесторами на самом старте проекта. Они спросили: «Сколько времени займёт разработка?» Я честно ответил: «От трёх месяцев до года». Знаете, что они сказали? «Нам нужна точная цифра».
Я нарисовал им этот конус на доске. Объяснил про ±300%. Они посмотрели друг на друга и снова: «Ну хорошо, но примерно?»
В итоге я сказал «полгода», они записали это как обязательство, и через восемь месяцев были очень удивлены 😅

Эталонная точность ±10% достигается только на финальной стадии проектирования.


То есть когда проект практически готов. Парадокс, да? Когда тебе больше всего нужна точность - в самом начале - её меньше всего. А когда она наконец появляется - уже всем всё равно, потому что релиз через неделю.

Критично:
Конус представляет ЛУЧШУЮ возможную точность для квалифицированных оценщиков. Хуже — легко. Точнее - только случайно.

Это моё любимое. Видел я команды, которые на стадии «у нас есть идея» давали оценку с точностью до дня. Спрашиваю: «Ребят, а как вы так точно посчитали?» Ответ: «Ну, мы подумали».

Подумали. На стадии ±300% погрешности. И самое грустное - иногда они попадают в цель. И потом годами рассказывают, какие они крутые оценщики, не понимая, что им просто повезло 🙃
Сейчас я всегда показываю этот конус заказчикам в самом начале. Да, некоторые уходят искать того, кто «оценит точнее». Но те, кто остаётся, понимают игру и работать с ними - одно удовольствие.

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

Читать сразу после Таннебаума ахах

Ждем новой версии: «Как быть 10х крысой»))
3
Claude AI и Z AI (glm)

Помимо привычного текстового чата, современные платформы Claude.ai (от Anthropic) и Z.ai (от Zhipu AI) превратились в полноценные рабочие среды с широким набором инструментов для визуализации, анализа данных и автоматизации.

Инструменты и возможности Claude

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

1️⃣Артефакты (Artifacts): Это отдельная интерактивная панель в правой части экрана, где Claude создает и обновляет структурированный контент. В этой панели можно:

📌Запускать код: Claude может написать игру (например, «Змейку») на HTML/JavaScript, и в нее можно играть прямо в интерфейсе.

📌Работать с React-компонентами: Создавать интерактивные элементы интерфейса с анимациями и фильтрами.

📌Генерировать диаграммы и схемы: Создавать векторные SVG-схемы архитектур или организационных структур, которые можно скачивать и масштабировать.

📌Просматривать документы: Markdown-файлы и ТЗ отображаются с красивым форматированием, а не в виде сырого текста.

2️⃣Проекты (Projects): Это выделенные рабочие пространства, которые позволяют сохранять контекст между разными чат-сессиями.

📌В проект можно загружать базу знаний (PDF, таблицы, текстовые документы) объемом до 30 МБ на файл.

📌Можно задавать системные инструкции, которые определяют роль Claude и правила его поведения для всех диалогов внутри проекта.

3️⃣Claude Code: Инструмент для разработчиков, работающий через терминал. Он имеет доступ к файловой системе, может выполнять bash-команды, делать git-коммиты и проводить глубокий рефакторинг кода.

4️⃣Claude Design: Экспериментальный инструмент для визуального дизайна. Он помогает создавать прототипы приложений, слайды и макеты на основе текстового описания, позволяя менять цвета и шрифты в реальном времени. Результаты можно экспортировать в PDF, PPTX или передавать в Canva для дальнейшей правки.

5️⃣Инструменты анализа и интеграции:

📌Analysis Tool: Позволяет загружать CSV-файлы для проведения эксплораторного анализа данных (EDA), очистки данных и построения графиков прямо в чате.

📌Claude for Sheets: Плагин для Google Таблиц, позволяющий использовать формулы Claude для массовой обработки данных в ячейках.

📌MCP (Model Context Protocol): Протокол, позволяющий подключать Claude к внешним сервисам, таким как базы данных Postgres, Figma, Slack или Google Drive.
Z.ai (ранее известная как Zhipu AI) — это крупная китайская ИИ-платформа, которая является одним из лидеров на рынке больших языковых моделей (LLM). Система базируется на семействе моделей GLM (General Language Model) и ориентирована на создание автономных агентов, сложную разработку кода и профессиональную визуализацию.
Ключевые возможности и модели
Платформа предлагает доступ к нескольким поколениям моделей, включая флагманские GLM-4.7 и GLM-5/5.1.

Программирование (Agentic Coding): Модели Z.ai демонстрируют результаты на уровне мировых лидеров (например, Claude Sonnet 4.5), занимая первые места в бенчмарках SWE-bench Verified и Terminal Bench 2.0. Модель не просто пишет фрагменты кода, а способна автономно проектировать архитектуру, интегрировать технологические стеки и проводить отладку в терминальных сценариях.
Мультимодальность: Система работает с текстом и изображениями, а также поддерживает генерацию видео.
Генерация готовых файлов: В отличие от многих чат-ботов, Z.ai выдает результаты в форматах .pptx (презентации), .docx, .pdf и .xlsx.
Инструменты поиска: Платформа включает Web Search API для LLM, поиск с цитированием веб-источников в чате и интеллектуальных поисковых агентов.

Дизайн и визуальные возможности
Z.ai делает ставку на «эстетику по умолчанию», стремясь минимизировать время пользователя на ручную правку стилей.

Генерация UI и веб-страниц: Модель понимает современные спецификации UI и создает визуально привлекательные макеты страниц, подбирая гармоничные цветовые схемы и структуры слоев.
Профессиональные презентации: GLM-4.7 значительно улучшила верстку слайдов. Совместимость с форматом 16:9 достигла 91%, а результаты описываются как «почти готовые к использованию».
Постеры: Улучшена типографика и гибкость цветовых решений для создания рекламных и информационных плакатов.

Режимы мышления (Thinking Modes)
Одной из уникальных технических особенностей Z.ai является гибкое управление процессом «размышления» модели:

Interleaved Thinking (Перемежающееся мышление): Модель думает перед каждым ответом или вызовом внешнего инструмента. Это позволяет корректировать стратегию на основе промежуточных результатов.
Preserved Thinking (Сохраненное мышление): Модель кэширует свои рассуждения между разными ходами диалога. Это критично для долгосрочных проектов: при добавлении функции на третий день работы ИИ может ссылаться на архитектурные решения, принятые в первый день.
Turn-level Thinking (Уровневое мышление): Пользователь может включать режим глубокого раздумья для сложных задач и отключать его для простых запросов, чтобы снизить задержку и стоимость.

Режим Agent Mode
Agent Mode — это режим автономного выполнения задач, где ИИ действует как «цифровой сотрудник».

Автономность: Вместо пошаговых уточнений система получает глобальную цель, сама разбивает её на этапы и выполняет тысячи вызовов инструментов для достижения результата.
Длинные циклы оптимизации: Модель GLM-5.1 специально оптимизирована для работы «вдолгую». Например, она способна за 600 итераций и 6000 вызовов инструментов в 6 раз ускорить работу базы данных, самостоятельно анализируя логи и исправляя ошибки.
Создание сложных систем: В этом режиме ИИ смог за 8 часов с нуля собрать в браузере Linux-подобный рабочий стол с файловым менеджером и приложениями, используя внешний цикл самопроверки.
inline constexpr

Для правильного объявления глобальных констант в заголовочных файлах в современном C++ (начиная со стандарта C++17) следует использовать комбинацию ключевых слов inline constexpr. Этот подход позволяет избежать нарушения правила одного определения (ODR) и гарантирует, что во всей программе будет существовать только одна копия переменной.
Ниже приведены подробные инструкции и лучшие практики, основанные на источниках.

1. Основной синтаксис и размещение
Наилучшим способом организации констант является их размещение внутри именованного пространства имен (namespace) прямо в заголовочном файле.
// constants.h #ifndef CONSTANTS_H #define CONSTANTS_H namespace MyConstants { inline constexpr double Pi = 3.14159; inline constexpr int MaxConnections = 100; } #endif

Почему это правильно:
constexpr: Гарантирует, что переменная является константой времени компиляции, что позволяет компилятору оптимизировать код, подставляя значения непосредственно в места вызова.

inline: Сообщает компоновщику (линкеру), что переменная может быть определена в нескольких единицах трансляции (файлах .cpp), и он должен объединить их в одну общую переменную в итоговом бинарном файле.

Namespace: Защищает от конфликтов имен с другими частями проекта.

2. Особенности для разных версий стандарта и типов
До C++17: Константы constexpr по умолчанию имели внутреннее связывание (internal linkage). Это означало, что каждый .cpp файл, включающий заголовок, получал свою независимую копию переменной, что могло приводить к раздуванию бинарного файла и лишнему расходу памяти.

C++17 и выше: Использование inline дает переменной внешнее связывание (external linkage). Линкер дедуплицирует определения, и программа использует один экземпляр данных.

Статические члены классов: Важно помнить, что в C++17 статические члены класса, объявленные как static constexpr, являются неявно встраиваемыми (inline). Для них ключевое слово inline можно не указывать.

3. Работа со строковыми константами в Qt

В контексте Qt-разработки важно учитывать типы данных:
QString нельзя объявить как constexpr: Этот класс имеет нетривиальный конструктор и не является литеральным типом, поэтому его нельзя вычислить на этапе компиляции.

Рекомендуемый подход: Для строковых констант используйте inline constexpr const char* или std::string_view (C++17).

Производительность в Qt:

Известно, что использование QLatin1String или QStringLiteral предпочтительнее для часто используемых строк, так как это снижает нагрузку на преобразование кодировок (UTF-8 в UTF-16) во время выполнения.

Преимущества этого метода
Эффективность памяти: Только одна копия каждой константы в памяти приложения.

Безопасность типов: В отличие от макросов #define, константы имеют строгую типизацию и область видимости.

Удобство поддержки: Изменение значения в одном заголовочном файле автоматически распространяется на весь проект.

Скорость: Компилятор может использовать значение константы для вычислений прямо во время сборки (например, для задания размеров массивов).

Лучшая практика: Если ваш компилятор поддерживает C++17, всегда отдавайте предпочтение inline constexpr для глобальных констант в заголовочных файлах.
1🔥1
В стандарте C++26 реализована статическая (компиляционная) рефлексия (предложение P2996), которая позволяет программе «инспектировать» саму себя и генерировать новый код во время компиляции. Это крупнейшее обновление языка со времен введения шаблонов, которое Херб Саттер назвал «ракетным двигателем для выражения эффективных абстракций».
Ниже приведен детальный разбор того, как устроена эта технология согласно источникам:
1. Ключевые операторы и синтаксис
Механизм рефлексии в C++26 строится вокруг двух новых базовых операций:
Оператор рефлексии (^): Применяется к сущности языка (типу, объекту, пространству имен, члену класса) и превращает её в объект метаданных. Результат этой операции всегда имеет один и тот же тип — std::meta::info (так называемое «стирание типов» или type-erased metadata).
Сплайсер или оператор «распаковки» ([: ... :]): Выполняет обратное действие — превращает объект метаданных обратно в грамматический элемент C++ (тип, выражение или имя), который можно использовать прямо в коде. Например, [: ^T :] вернет сам тип T.
2. Пространство имен std::meta
Для работы с метаданными в стандартную библиотеку добавлен набор функций времени компиляции (метафункций), находящихся в std::meta. Основные инструменты включают:
members_of: Извлекает вектор объектов рефлексии для всех членов типа или пространства имен.
nonstatic_data_members_of: Позволяет получить список только нестатических полей данных структуры или класса.
enumerators_of: Возвращает все значения перечисления (enum).
name_of (или identifier_of в новых ревизиях): Позволяет получить строковое имя объекта рефлексии.
3. Компиляционный цикл template for
Для эффективной обработки полученных метаданных вводится новая управляющая конструкция — template for. Она позволяет итерироваться по набору объектов рефлексии прямо во время компиляции, разворачивая тело цикла для каждого элемента. Это избавляет разработчиков от необходимости использовать сложные рекурсивные шаблоны или макросы для обхода полей структур.
4. Дополнительные возможности: Аннотации и Параметры
Рефлексия в C++26 выходит за рамки простого перечисления полей:
Рефлексия параметров функций (P3096): Позволяет получать типы и имена параметров функций, работать с конструкторами и операторами.
Пользовательские аннотации (P3394): Разработчики могут помечать элементы кода собственными аннотациями в формате [[=constant-expression]]. Эти аннотации доступны для чтения через рефлексию и позволяют настраивать логику кодогенерации (например, переопределять имена полей при сериализации).
5. Особенности реализации и преимущества
Императивный стиль: В отличие от старого метапрограммирования на шаблонах, работа с рефлексией идет в привычном стиле с использованием циклов и условий.
Безопасность и ошибки: Ошибки рефлексии теперь обрабатываются через compile-time исключения, которые можно ловить и обрабатывать в процессе сборки.
Zero-overhead: Рефлексия не увеличивает размер бинарного файла и не замедляет работу программы в рантайме, так как вся магия происходит на этапе компиляции.
Универсальность: Стандартная рефлексия решает задачи автоматической сериализации (в JSON и др.), создания ORM (маппинг объектов в базу данных) и конвертации enum в строку без внешних инструментов генерации кода.
Статус поддержки: На текущий момент (март 2026 года) техническая работа над C++26 завершена. Рефлексия уже частично реализована в ветках разработки компиляторов GCC 16 и Clang (проект clang-p2996). Попробовать её можно в Compiler Explorer (godbolt.org), используя флаги -std=c++26 -freflection.
Инверсия зависимостей в Chromium.
Часть 1 .

Давно ничего не писал. Пост про прошлое лето так и остался в блокноте. Напишу немного про архитектуру.

Решил запилить серию постов про инверсию зависимостей.
Подойти к вопросам, связанным с DI.

Но сначала хотелось бы рассмотреть примеры реализаций IoC в опенсорсе.

Он часто крутится на слуху. Крутится и при обучении нейросетей в ускорителях. Пусть у нас в канале крутится также - для насмотренности. Обучим наши биологические сети в мозгу.

Проекты демонстрировал новичкам. До Chromium browser уже дошли. Хотелось еще рассмотреть парочку повседневных программ. Знаю музыкальные и видео редакторы.

Кажется, что весь опенсорс очень сложный. Справедливо для Chromium. Посмотрели другие проекты и остались довольны. Код очень структурирован комментариями вставками и пометками. Буду добавлять ссылки. Чтоб читали не только меня.

Следите...
Инверсия зависимостей в Chromium.

ЧАСТЬ 1.1 — ВСТУПЛЕНИЕ

Заходим в исходники Chromium с джуном. Там достаточно большой проект на C++.

Джун говорит: «куда мне смотреть?».
Я говорю: «на services/service_manager».
Джун уходит ковырять chrome/browser.

Далее мы видим 2 сервиса. Живут в разных процессах, общаются через Mojo, регистрируются в Service Manager.

Зависимости инвертированы, абстракции через IDL, lifecycle управляется извне. Все четко и красиво, но сложно.
ВСТАВКА: Что такое Service Manager в Chromium

Service Manager — это компонент, который управляет сервисами в многопроцессной архитектуре Chromium. По сути - распределённый IoC-контейнер. Он не знает про конкретные реализации сервисов, он знает про интерфейсы (Mojo IDL). Сервис реализует service_manager.mojom.Service — это контракт. Менеджер решает, когда сервис запускается, в каком процессе живёт и когда умирает. Это DIP на уровне всей системы.

Новички часто думают, что IoC-контейнер - это что-то маленькое и локальное. В Chromium он распределённый: один процесс управляет сервисами в других процессах. Это как твой ServiceLocator, только вместо shared_ptr - межпроцессное взаимодействие.

📎 Service Manager README
Service Manager & Services (experimental)
Chromium Architecture Overview (Sprocket)

#chromium #IoC
Инверсия зависимостей в Chromium.

ЧАСТЬ 1.2

«Какая тут архитектура?» - мой стандартный первый вопрос.

Джун отвечает что-то про мультипроцесс, про sandbox, про то что «там какой-то Mojo». И ему становится интересно. Потому что каждый, кто открывает исходники Chromium, чувствует себя потерянным.

Но признаваться в своей потерянности нельзя - все же «разбираются» (споилер - можно, если тимлид разрешает).

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

ВСТАВКА: Mojo — это IPC с интерфейсами

Mojo — это язык, или межпроцессное взаимодействие (IPC) в Chromium, но с контрактами. Определяешь интерфейс в .mojom-файле (IDL), а генератор делает C++-биндинги, и два процесса общаются через этот интерфейс. Ни один процесс не знает про реализацию другого — только про контракт. Это DIP, только между процессами, а не классами.


Новички часто путают Mojo с «каким-то там IPC» (linux). Mojo - на первый взгляд выглядит как передача сообщений. На самом деле - это интерфейсный контракт с типизацией, версионированием и жизненным циклом. Определяется в .mojom файлах и работает между процессами.

📎 Google Mojo IDL (Medium) · Chromium IPC README (GitHub) · Mojo mailing list