Чего мне больше всего не хватает, спустя 5 лет жизни в Лондоне?

Недавно исполнилось ровно 5 лет с тех пор, как я переехал в Лондон.

Чего мне больше всего не хватает в Лондоне, по сравнению с жизнью в Москве?
Это березки? Водка? Доставка за 10 минут? - Нет.

1) Сложно встретиться с родственниками. Живя в Москве, я мог относительно просто приехать к родственникам. Живя в Лондоне это затруднительно. Особенно в последние 5 лет.
2) Еда в кафе и ресторанах. Я бы не сказал, что в Лондоне она хуже, просто она другая. Вкусы и предпочтения в еде мало изменяются за жизнь.
3) Столовые. У нас есть столовая в офисе. Но столовых по городу нет или практически нет. Это снгшная тема. Тут только кафе и рестораны. Поесть борщ, пюрешку с котлеткой, гречку и две соски, компот можно только в русском ресторане или в доставке.
4) Фильмы и шоу на русском. В кинотеатрах фильмы только в оригинале на английском. Это, конечно, полезно, но приходится дополнительно напрягать свой мозг. Особенно, если у актера британский акцент. Про театры и постановки Шекспира я молчу, там происходящее понятно только из действий.
5) Покрытие мобильного интернета. Тут в метро практически нет интернета. Более того, даже на улице не везде ловит мобильный интернет.
6) Платные больницы и инвитро. Платные больницы и больницы по платной страховке тут есть, но экспириенс от них все же другой. Все более сложно устроено и сильно дороже. А прямого аналога инвитро нет. Есть разные аналоги, с разным набором услуг. Но большой, дешевой, во всеми возможными анализами и удобной сети нет.


Смотри также:
1) Бытовые особенности жизни в Лондоне. Часть 1.
2) Бытовые особенности жизни в Лондоне. Часть 2.
3) Бытовые особенности жизни в Лондоне. Часть 3.
👍2273
Laurent Simons получил PhD по квантовой физике в возрасте 15 лет

PhD - это аналог кандидатской диссертации.
В возрасте 8 лет он закончил школу, в 10 лет получил бакалавра, в 12 - магистра. И наконец в 15 защитил PhD.
Дальше планирует переключиться с квантовой физики на медицину и AI. У него IQ - 145.

Это вам не жаловаться на незнание того, как работает хеш-таблица и как инвертировать дерево.

Новость
😁38👍21🔥12🤯4🗿21
Mark Chen на подкасте у Ashlee Vance рассказал, что Марк Цукерберг пытался рекрутировать половину его подчиненных.
Он не только предлагал десятки и сотни миллионов долларов за переход, но и сам приготовил суп и сам его приносил домой потенциальным новым сотрудникам.
Mark Chen - Chief Research Officer в Open AI.
Его линкедин: Mark Chen
Он также является главным тренером сборной США на международной олимпиаде по информатике.

Представьте, вы просыпаетесь от звонка в дверь, а там Цукерберг с супом.

Подкаст: https://www.youtube.com/watch?v=ZeyHBM2Y5_4
🤣46👍8🔥4
Мета сокращает расходы на метаверс на 30%.

Последует ли очередная волна сокращений?

На Метаверс были потрачены огромные деньги (50+ миллиардов долларов). Даже переименовали компанию из Facebook в Meta. Результат на картинке.
😁60👻7
Рекомендую сериал Devs

Если еще не смотрели, рекомендую сериал Devs (Программисты/Разрабы).

Другие фильмы, документалки и сериалы про программистов, основателях компаний смотрите тут:
Подборка фильмов, сериалов и документалок о программистах, BigTech, стартапах и их основателях
💯12👍5
Какую документацию имеет смысл писать?

Смотри пост про комментарии в коде: Комментарии в коде

Я придерживаюсь мнения, что комментировать ваши POJO, и внутреннее API смысла никакого нет. Комментировать имеет смысл публичное API, которое используется другими командами или вне вашей компании.

Но что имеет смысл все таки документировать?

Обычно это делается во внутренней вики компании (Например, Confluence).

1) Цели команды, какие задачи (бизнес или не бизнес) она решает. Чтобы вас можно было легко найти по тексту проблемы, которую хочет решить другая команда. И зайдя на страницу вашей команды, сразу стало понятно, чем вы можете быть полезными кому-то еще.
2) Описание основного функционала, который может быть полезен другим командам или вне компании. Это описание фич, которые предоставляет ваша команда.
3) Customer onboarding. Если кто-то захочет использовать ваш функционал, как ему заонбордиться? нужно ли создать какой-то onboarding тикет, или просто начать использовать какое-то публичное API. Нужно подробно описать все шаги, как кастомеру стать вашим клиентом.
4) Public API. Детальное описание API, которое вы предоставляете внешним клиентам (внутри или вне компании).
5) SLOs, SLAs, SLIs. Если есть и применимо к вашему функционалу.
6) Support and Monitoring for Customers. Как ваши клиенты могут трекать состояние вашего сервиса? какие метрики или дашборды они могут использовать? Как связаться с саппортом если у них проблемы? Как поднять тикет, запейджить, написать кому-то и т.д.
7) Описание Архитектуры вашего решения. Не комментарии к коду i++, а диаграммы с описанием высокоуровневой архитектуры и архитектуры тех или иных фич.
8) Internal Support and Monitoring. Детальные метрики, алармы, дашборды, ранбуки для саппорта, которыми будет пользоваться тот, кто саппортит вашу функциональность.
9) Онбординг для новичка вашей команды. Документы, которые нужно прочитать человеку, который только пришел работать в вашу команду. Где найти код, как настроить среду разработки, как тестировать, запускать, деплоить и т.д. Как устроен процесс разработки, релиза и все что потребуется человеку для работы в вашей команде.
10) User Manual, FAQ. Детальное описание того, как пользоваться вашим функционалом со стороны клиента. Описание типичных проблем и их решения. Типичные уточняющие вопросы и ответы на них.
11) Внутренние дизайн доки. Когда вы дизайните новую фичу, компоненту и т.д. вы пишете дизайн док/RFC. Он проходит дизайн ревью и ложится в основу реализации фичи. Имеет смысл этот док сохранить для понимания причин того или иного решения + атачить ссылку на этот документ в code-review и коммитах. Чтобы в системе контроля версий видеть, почему что-то было сделано так и не иначе.
12) Code-style. Если вы создали и договорились про какие-то стили в кодирование, то можно это зафиксировать в виде документа. Это может быть список Code Smells.
13) Team and org chart. Кто менеджер, тим-лид, список всех членов вашей команды. С тем можно поговорить потенциальному клиенту. Как ваша команда вписывается в структуру компании? в каком орге она находится и т.д.
👍12🔥42👏2
Новая презентация про изменения продуктивности программистов благодаря AI

Это снова презентация от той же группы исследователей из Стэнфорда. Результаты исследований презентовал Yegor Denisov-Blanch.

Пост про его предыдущую презентацию тут: Еще одно исследование улучшения продуктивности программистов при помощи AI

Сама новая презентация: https://www.youtube.com/watch?v=JvosMkuNxF8

Основные результаты:

1) Внедрение AI увеличивает продуктивность программистов и это увеличение продуктивности растет со временем. Если в 2023 увеличение продуктивности от внедрения AI было около 0. В 2024 среднее изменение продуктивности от внедрения стало уже 5%, а в 2025 - около 10%.
2) Продуктивность от внедрения AI слабо коррелирует с числом используемых токенов. Т.е. важно не количество используемых токенов, а качество того, как вы используете AI.
3) Увеличение продуктивности от внедрения AI сильно зависит от изначального качества кода. Clean Code позволяет получить большее увеличение продуктивности от использования AI. (Мой комментарий: Но вообще, это скорее связано с его предыдущим результатом про маленькие репозитории, т.к. они в индексе качества кода использовали в том числе размер репозитория.)
4) Одинаковый доступ к AI тулам не означает одинаковое использование AI разными командами. Многие компании внедрили AI для повышения продуктивности программистов, но тем не менее разные команды используют AI в разной степени, хотя доступ к тулам одинаковый.
5) Число Code Review/PR увеличилось сильно, но увеличилось число Code Review/PR на Rework. Т.е. программисты пушат больше кода и сильно больше потом переделывают. Поэтому число PR может увеличиться на 40%, но 20%-30% - переделывание предыдущих PR сгенерированных при помощи AI. Поэтому на 2025 год среднее увеличение продуктивности находится на уровне 10%.
6) Качество кода уменьшилось от внедрения AI. Не смотря на увеличение продуктивности, качество кода уменьшилось на 9%.

Основные результаты из предыдущей презентации:

1) Нет корреляции между тем, как программисты сами оценивали изменение своей продуктивности и тем как продуктивность изменилась в реальности. Т.е. нельзя использовать опросники программистов про влияние AI на свою продуктивность. Нужно делать реальные замеры и не опираться на опросы.
2) Продуктивность менялась от уменьшения продуктивности на десятки процентов до увеличения продуктивности на 40% в зависимости от условий, типов задач, сложности задачи и языка программирования.
3) В задачах, на которых продуктивность увеличилась на 40%, половину пришлось переделывать. Т.е. увеличилась продуктивность, но и потребовалось существенную часть переделывать. Это как два шага вперед и один шаг назад. В реальности продуктивность на этих задачах выросла на 15%-20%.
4) Продуктивность выросла на следующих типах задач: простые задачи, популярные языки программирования (python, js), маленькие базы кода.
5) Продуктивность выросла меньше или уменьшилась на следующих типах задач: сложные задачи, редкие языки программирования или большие базы кода.
👍20🔥54👎1💊1
Ранее я уже писал, что Yann LeCun уходит из Meta до конца этого года, чтобы начать свой стартап.
Сейчас стало известно, что он ведет переговоры и близок к получению инвестиций в $0.5B с оценкой компании в $3B.
Последние 12 лет Ян работал на позиции Chief AI Scientist в Meta. Он лауреат премии Тьюринга(аналог нобелевки в Computer Science) за 2018 год за создание Deep Learning.

Ян скептически высказывался о LLM как способе достижения AGI/ASI. В Мета он не занимался LLM и не имеет отношения к разработке и провалам llama 4.
👍349
Мой первый проект в Facebook

Когда я пришёл в Facebook в 2020 году, моим первым проектом, как ни странно, стала автоматическая модификация кода. Это было ещё до эпохи AI-хайпа и взлёта LLM.

В чем была задача
Автоматическая аннотация всего кода в Facebook Privacy аннотациями. Эти аннотации описывали семантические типы данных, источник данных, кого эти данные описывали и т.д.
Например, у вас есть поле в базе, которое имеет тип varchar. Для работы с этим полем в таблице у вас есть классы в коде, которые описывают маппинг (ORM). Далее это поле читает какой-то другой код и т.д. Задача была на уровне кода пометить все эти места соответствующими лейблами, которые бы описывали, что это за данные. Например, что это имя пользователя, его айдишник, его email, его телефонный номер и т.д.
Т.е. чтобы описать, что эта переменная или поле в классе не просто строка, а чувствительные приватные данные.
Далее эти метки можно использовать на уровне кода для проверки Privacy правил. Чтобы эти данные не утекали туда куда пользователь не давал своего согласия. Например, чтобы что-то не использовалось для таргетной рекламы.
Этот подход называется Privacy as code.

Как я ее решил
В Facebook давно были разработаны фреймворки и тулы для автоматической модификации кода. Для этого нужно написать другой код, который описывает как этот код менять. Весь код представляет собой семантическое дерево: Abstract syntax tree. Это дерево можно обходить при помощи DFS или BFS (пригодились алгоритмы). На каждой итерации обхода можно делать проверки на тип вершины (это функция, выражение, объявление переменной и т.д.), вытаскивать данные (имя функции, переменной, список аргументов функции и т.д.) и проверять, что мы нашли то место, которые мы хотим изменить. И далее описать изменение - удаление, модификация, добавление кода. Далее этот код натравливается на код базу, сканирует код, делает изменения и автоматически создает code review (pull requests). Далее это code review асайнится на владельцев кода и после ревью оно деплоится.
За несколько лет работы мой код создал более 30 тысяч автоматических code review еще до эпохи LLM. В итоге я разметил весь код в Facebook семантическими типами данных (email, phone number, user name, user id, user generated content и т.д.).

В итоге это стало частью более масштабного проекта по пониманию всех данных в Facebook/Meta, о чем был написан пост в официальном engineering блоге Мета: https://engineering.fb.com/2025/04/28/security/how-meta-understands-data-at-scale/
🔥37👍256🤯2🏆1
Новый год, новые лейофы

Среди FAANG-компаний в январе были два мега лейофа:

1) Amazon. ~16k человек. Озвученные причины: уплощение иерархии, уменьшение бюрократии и т.д.
2) Meta. ~1.5k человек. Затронуло отделы, которые работали над Metaverse. Это, в основном, RL (reality labs). В Лондоне вчера сократили большинство тех, кто работал в RL. Причины: смещение приоритетов с Metaverse на AI. При этом работа над wearables продолжится (умные очки Meta Ray-Ban).

Общий тренд на лейофы в Bigtech/FAANG сохраняется. Не так много, как в 2023, но на том же уровне, что и в 2024 и 2022.
😢20🙈4
Шаблон решения задач на бинарные деревья. Tree Traversal

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

Если в условии у вас бинарное дерево, то в подавляющем числе случаев вам нужно применить алгоритм обхода дерева: DFS или BFS. Наиболее часто нужно применять DFS. Для бинарного дерева он упрощается до:

void traverse(TreeNode node) {
if (node == null) {
return;
}
traverse(node.left);
visit(node);
traverse(node.right);
}

visit - это ваша кастомная логика, которая будет специфична для конкретной задачи. Ее можно поместить до рекурсивных вызовов для левого и правого ребенка. В таком случае такой обход дерева называется pre-order tree traversal:
void traverse(TreeNode node) {
if (node == null) {
return;
}
visit(node);
traverse(node.left);
traverse(node.right);
}

Между рекурсивными вызовами, в таком случае такой обход называется in-order tree traversal:
void traverse(TreeNode node) {
if (node == null) {
return;
}
traverse(node.left);
visit(node);
traverse(node.right);
}

и после рекурсивных вызовов, такой обход называется post-order tree traversal:
void traverse(TreeNode node) {
if (node == null) {
return;
}
traverse(node.left);
traverse(node.right);
visit(node);
}

Особенностью in-order tree traversal является то, что для BST (бинарного дерева поиска), метод visit будет вызываться для вершин дерева в порядке возрастания значений.

Во многих задачах, вам нужно будет что-то вычислять во время обхода дерева. Обычно, это min/max от различных значений. Для этого вам нужно будет расширить метод обхода и дополнить его параметрами и возвращаемыми значениями:


int traverse(TreeNode node) {
if (node == null) {
return {base_value};
}
int leftResult = traverse(node.left);
int rightResult = traverse(node.right);
return {f(leftResult, rightResult, node.value)};
}

{base_value} - значение для базового случая (для листа дерева). Обычно, это 0 или 1.
{f(leftResult, rightResult, node.value)} - какая-то функция от результатов для левого, правого поддерева и значения в текущей вершине. Обычно это min/max от суммы, разницы и т.д.

Иногда нужно передавать какие-то параметры:

int traverse(TreeNode node, int value) {
if (node == null) {
return {base_value};
}
int leftResult = traverse(node.left, {foo(value)});
int rightResult = traverse(node.right, {bar(value)});
return {f(leftResult, rightResult, node.value)};
}

{foo(value)}, {bar(value)} - какие-то функции от value. Часто это value + 1 или value -1. Но зависит от задачи. Иногда это какие-то более сложные функции, которые могут зависеть от текущего значения в вершине: node.value.

Иногда вам нужно сокращать область поиска (особенно для BST(бинарного дерева поиска)) или делать дополнительные проверки перед рекурсивным вызовом:

int traverse(TreeNode node, int value) {
if (node == null) {
return {base_value};
}
int leftResult = 0;
if ({left_condition}) {
leftResult = traverse(node.left, {foo(value)});
}
int rightResult = 0;
if ({right_condition}) {
traverse(node.right, {bar(value)});
}
return {f(leftResult, rightResult, node.value)};
}

{left_condition}, {right_condition} - обычно зависят от node.value. Условия вроде node.value > value, node.value < value.
🔥2410👍8
Иногда, возвращаемое значение и ответ задачи - это разные величины. В таком случае нужно возвращать пару величин или обновлять глобальную переменную, которая и будет ответом.
int globalResult = 0;

int solve(TreeNode root) {
traverse(root);
return globalResult;
}

int traverse(TreeNode node, int value) {
if (node == null) {
return {base_value};
}
int leftResult = 0;
if ({left_condition}) {
leftResult = traverse(node.left, {foo(value)});
}
int rightResult = 0;
if ({right_condition}) {
traverse(node.right, {bar(value)});
}
globalResult = {g(leftResult, rightResult, node.value)};
return {f(leftResult, rightResult, node.value)};
}


Смотри также:
1) Шпаргалка по основным алгоритмам для алгоритмического собеседования
2) Шпаргалка по Java для алгоритмического собеседования
3) Разобрал все основные алгоритмы и 47 задач с собеседований на алгоритмы в FAANG
🔥226👍6
Шаблон решения задач на Two Pointers.

Существенная часть задач на собеседованиях в FAANG-компании по алгоритмам - задачи на массивы, строки и связные списки.
Множество из них решается при помощи подхода, который называется Two Pointers.

Какие признаки того, что задача на Two Pointers?
1) В условии есть массив, строка или связный список (или данные задачи можно к ним свести).
2) Массив, строка или список в задаче отсортированны или их можно отсортировать (тогда сложность с линейной повысится до O(n*log(n)).
3) В условии не один массив/строка/список, а два.
4) По логике задачи вам надо суммировать/умножать или сравнивать разные элементы из одного и того же массива/строки/списка
5) Аналогично предыдущему, для случая если у вас два массива/строки/списка - по логике задачи вам нужно суммировать/умножать или сравнивать элементы из двух/нескольких массивов/строк/списков.
6) В условии сказано, что нужно найти пару, тройку, четверку чисел из заданного массива
7) В условии описываются интервалы времени, с которыми нужно что-то сделать (смержить по какому-то критерию, найти окно в расписании и т.д.)
8) В условии идет речь про палиндромы.
9) Нужно изменить массив/строку in-place (без дополнительных структур данных и доп. памяти).
10) Нужно смержить несколько массивов в один.

Метод Two Pointers сводится к тому, что вы идете циклом по вашему массиву/строке/списку при помощи не одного указателя/индекса, а при помощи двух указателей/индексов.

Типичный код, который циклом идет по массиву при помощи одного указателя i:
for (int i = 0; i < arr.length; i++) {
....
}

В методе Two Pointers, вам одновременно нужно использовать два указателя.

Тут может быть несколько вариантов в зависимости от задачи:

1) Массив один. Первый указатель вначале указывает на начало массива, а второй на конец массива. Указатели двигаются навстречу друг другу:
int left = 0;
int right = arr.length - 1;
while (left < right) {
{calculate_something}
{return_break_condition}
if ({left_move_condition}) {
{when_move_left_logic}
left++;
} else if ({right_move_condition}) {
{when_move_right_logic}
right--;
}
}

{calculate_something} - какие-то вычисления или логика, специфичная для задачи.
{return_break_condition} - условие окончания работы алгоритма, если его можно прервать раньше, чем left станет равным или большим, чем right.
{left_move_condition} - условие, когда двигать левый указатель.
{right_move_condition} - условие, когда двигать правый указатель.
{when_move_left_logic} - какая-то доп. логика, если нужно ее выполнить, когда двигаем левый указатель.
{when_move_right_logic} - какая-то доп. логика, если нужно ее выполнить, когда двигаем правый указатель.
2) Массив один. Оба указателя вначале указывают на середину массива. Далее двигаются в противоположные стороны:
int left = (arr.length - 1)/2;
int right = (arr.length - 1)/2;
while (left >= 0 && right < arr.length) {
{calculate_something}
{return_break_condition}
if ({left_move_condition}) {
{when_move_left_logic}
left--;
} else if ({right_move_condition}) {
{when_move_right_logic}
right++;
}
}

3) Массива два. Оба указателя начинают с начала первого и второго массива соответственно. В одном цикле идем по двум массивам одновременно:
int i = 0;
int j = 0;
while (i < arr1.length {&&/||} j < arr2.length) {
{calculate_something}
{return_break_condition}
if ({i_move_condition}) {
{when_move_i_logic}
i++;
} else if ({j_move_condition}) {
{when_move_j_logic}
j++;
}
}

4) Список/Массив/Строка одна. Идем двумя указателями, которые стартуют с начала, но с разной скоростью. Fast and Slow Pointers.
Например, вначале подвинем первый указатель сразу на k-позиций. Далее будем двигать оба указателя с одной скоростью. Тогда вконце, один указатель будет сдвинут на k-позиций относительно первого.
17🔥14👍6👎1
5) Массив один. Нужно поменять его in-place. Первый указатель начинает с начала. Второй где-то внутри массива. Оба идут в одном направлении к концу массива. Или как в самом первом варианте - первый указывает на начало массива, второй на конец. Указатели двигаются на встречу друг другу.

Есть еще большая связанная тема - интервалы. Ее я разберу отдельным постом.
👍25👎1
Сколько нужно решить задач по алгосам в 2026, чтобы пройти в FAANG?

Тут завит от вашего изначального уровня:

1) Топ олимпиадник. У вас бэкграунд топового олимпиадника. Вы побеждали/были призером крупных соревнований на уровне страны или международном уровне. В таком случае 50-100 будет достаточно. Просто отфильтруйте задачи на leetcode по компании, в которую вы хотите, и решите топ 30-100 по частоте встречаемости. Если не готовиться вообще, то есть риск реджекта, т.к. собесы и олимпиады это разные жанры. Нередко собеседовал крутых олимпиадников и они получали реджект по одной или нескольким осям(problem solving, coding, verification, communication).
2) Уже в FAANG. Например, вы работаете в Amazon или Microsoft, но хотите в Google или Meta. Возможно, вам придется прокачать дополнительно некоторые темы. Вроде динамического программирования, деревьев, графов. Это в дополнение к решению задач под конкретную компанию. Поэтому, это может быть 100-300 задач. 300 скорее всего потребуется, если хотите в Google, т.к. туда самое сложное кодинг собеседование.
3) Средний программист. Вы не побеждали в олимпиадах, кодить умеете хорошо, но алгосы не особо решали. Я бы ориентировался на 300-600 задач. 600 - это, если вы сразу хотите в Google. Для большинства FAANG или около FAANG хватит 300, из которых 150+ это medium задачи на leetcode.

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

Это может быть:
1) https://leetcode.com/
2) https://www.algoexpert.io
3) https://neetcode.io/
4) Cracking the coding interview

И другие ресурсы, которые я рекомендовал ранее: https://t.me/faangmaster/696
🔥31👍95🗿3👎1🥱1
Нужно ли ботать алгосы, если вы ML Engineer и хотите в FAANG?

Если вы хотите в Meta, Amazon, Apple, Google, Microsoft, Uber и т.д. на позицию ML Engineer, то на собесе у вас будет столько же кодинг раундов на алгосы, сколько и у обычных программистов. У вас будет ML дизайн раунд вместо System/Product design. Но алгосы точно такие же.
😭28👍22👎1
Сегодня будет второй стрим, снова порешаем ~5 задач.

Первые 0-15 минут выделю на ваши вопросы, если такие будут.

https://youtube.com/live/dsRkFge7Z9U?feature=share
👍36🔥11