Хочу сказать пару слов про первую книгу. Я нашел ее буквально случайно, когда я первый раз стал менеджером. С тех пор я рекомендую эту книгу всем своим подчиненным - будь они менеджеры менеджеров, линейные менеджеры, тимлиды или просто инженеры которые думают о переходе на лидерские позиции.
Почему мне так нравится эта книга? По ряду причин.
Она написана очень простым и понятным, no-bullshit языком, инженером для инженеров. Многие книги по бизнесу и лидерству (особенно американских авторов) грешат тем, что первые три главы тебе рассказывают о том, как этот подход изменил жизнь многих известных людей, потом еще две о том, как автор пришел к этому подходу, и только в конце, кратенько - в чем, собственно, подход заключается.
Ее можно читать в любом порядке, в том числе - как справочник. Может показаться, что если ты TL, то глава The Big Leagues тебе пока не нужна - но это не так. Чтение поможет понять, как мыслят люди в таких позициях, что для них важно и как выстраивать разговор и аргументацию с ними.
В том числе, если ты менеджер менеджеров, читая главу про TL-ов, можно лучше понять как растить людей, как давать им stretch goals (задачи по силам, но на пределе, которые стимулируют развитие)
В книге довольно много конкретных примеров и рекомендаций, в стиле "попробуй так, а не получится, попробуй еще вот так".
Наконец, эта книга описывает не сферический менеджмент в вакууме, а менеджмент именно инженерных команд - в этом (как, пожалуй, и везде) очень много специфики, и ее нельзя не учитывать.
Короче, это отличная книга и я настоятельно рекомендую ее всем, кому интересно лидерство именно в технической сфере.
ваш рост зарплаты не связан с ростом зарплат на рынке - это хороший рост как специалиста, обусловленный низкой базой. Если бы вы были senior или tech/team lead с опытом 10+ лет, ваш рост зарплаты в процентах был бы совсем не таким впечатляющим.
Олег: Интересно. Если взять, к примеру, какое-нибудь сообщество питонистов, то у них куда меньше культ производительности. Как получилось, что именно в нашем сообществе так происходит? Может, это вы спровоцировали культ перформанса своими докладами? Ты, Шипилев, Паньгин, Иванов и так далее.
Мне кажется, это очень интересный вопрос.
Во-первых, культ производительности определенно есть не только в Джаве: посмотрите доклады на конференциях по Go, С++, JavaScript — там тоже очень много докладов про производительность, и зачастую это самые посещаемые доклады.
Думаю, культ во многом связан с эго: "если я написал код быстрее, чем коллега, значит я круче/умнее". Посмотрите на заголовки проектов на Гитхабе: многие имеют вид "Fast(est) [Thing] for [Language]". Вдобавок, производительность относительно легко сравнивать.
Было бы интересно видеть в индустрии больше проектов с заголовками типа:
"Very robust [Thing] for [Language]"
"[Thing] for [Language] with minimum configuration parameters/completely automatic tuning"
"[Thing] for [Language] with minimum resource (disk/memory/network) usage". Такое, кстати, иногда встречается, хотя реже, чем "fastest". Например, люди любят писать очень компактные реализации libc, см. musl и друзей.
Какой смысл разделять в статье объяснения механизмов работы HashSet и HasMap, если можно просто сказать что HashSet внутри себя содержит HashMap и все вызовы проксирует к нему?
Мой личный список вопросов работодателю (если не было освещено на собеседовании).
Чем я буду заниматься? Только узкими обязанностями или еще и смежными?
Какой стек на моём проекте? Есть ли легаси?
Что с тестированием
Есть ли CI/CD и девопс инженер?
Будет ли единый ПМ и четко заданный жизненный цикл таска?
Есть ли БА?
Системы мониторинга, сборщик логов?
Переработки бывают? Оплата?
Системы трекинга времени и руткиты на рабочем компе?
Отпуска: дробление отпуска, включены или нет выходные, за сколько нужно предупреждать, отказы
За что и как часто получаются премии? Кто определяет их размер?
Есть ли СБ? Какие требования у СБ?
Почему открыта вакансия? Если не новая, то куда ушел предыдущий разработчик?
Аналогично про гибкий график, карьерный рост. Что это значит и в чем выражается.
Ретроспектива.
Код ревью в компании: кто, как долго, что если пожар.
В случае с опционами обычно контракт предполагает 4 года на весь пакет акций, с возможностью забирать частями после первого года ("one year cliff"). Т.е. всегда есть возможность выйти с 3/4, если после трех лет. Рассматривали такой вариант? Ведь всех денег не заработаешь, а опцион, даже реализованый, еще не дает гарантий, что компания будет успешной и эту инвестицию можно будет реализовать.
Я работал около трех в стартапе, контрактором. Опцион на момент моего ухода из компании стоил около $27k (поскольку стартап все время своего существования был прибыльным, нет возможности ставить цену акции в опционе нулевой). В этом случае даже опцион рассматривается как инвестиция — мне необходимо вложить $27k чтобы превратить опцион в акции, затем со временем, если компания выйдет на IPO или будет куплена (событие "exit"), я смогу продать эти акции, заплатить налоги и получить прибыль. Т.е. даже в случае рабочего, прибыльного стартапа с продающимся продуктом для опционов остается много "если", прежде чем этот вид "компенсации" превращается из ваших часов на роботе и денег в прибыль.
Для тех, кому интересна тема опционов, вот пара хороших ссылок:
Для решения это проблемы, некоторые компании в США ввели два больших типа сотрудников: non-exempt и exempt
Первый тип отличается следующими вещами
— как правило это не инженеры
— у них строгий график работы
— у них может быть строгий дресскод
— их задачи и цели имеют четкое описание и как правило их можно легко контролировать
— любая переработка оплачивается как сверхурочные
Второй тип
— здесь как правило все инженеры/синьоры/менеджеры
— нет строгого графика работы, но он часто регулируется фиктивно, путем назначения регулярных митингов в определенное время, не обязательно в «нормальные» рабочие часы. Но присутствие в офисе во время митингов не является обязательным, хотя и желательно(живое общение всегда лучше)
— может не быть дресскода
— задачи ориентированы на достижение цели в определенном временном промежутке (недели или месяцы)
— переработка отсутствует как класс, из-за того что требуют решить задачу, а не просидеть на работе
Мне очень нравятся простые примеры какой-то новой фичи, когда наглядно показывается, как раньше было всё плохо, а с новым нововведением стало всё хорошо. Пример с суммой чисел — это не то, чтобы я хотел видеть для асинхронных потоков.
Исправляем ситуацию… Допустим, у вас есть следующий метод
IEnumerable<FileResult> ReadFiles(string[] fileNames)
{
foreach(var name in fileNames)
{
yield return ReadFile(name);
}
}
Видите ключевое слово yield? В нем все дело.
Теперь вы узнали о чудесной конструкции async await и хотели бы применить ее к данному методу. И у вас даже есть новый метод ReadFileAsync.
Вы хотели бы, конечно, написать что-то такое
async IAsyncEnumerable<FileResult> ReadFilesAsync(string[] fileNames)
{
foreach(var name in fileNames)
{
yield return await ReadFileAsync(name);
}
}
Так вот! Раньше так нельзя было написать. А в C# 8 можно.
Сейчас опытным путем смог найти этот «Services».
Судя по всему для того чтобы это окно было доступно и видно (в том числе при поиске команд), нужно чтобы существовал хотябы один сервис.
То есть нельзя открыть «пустое» окно сервисов.
Я в новом проекте сделал себе коннекшн к базе. После того как его создал, это окно сразу появилось (и также опция Services в поиске стала доступна).
Блин, про контекст в ответе — я лет пять учился. У нас даже был жанр писем «почему нахер», когда я сначала давал ответ, а потом объяснял длинным письмом, почему так. Так вот, правильно делать наоборот, сначала объяснять, потом давать ответ. И этому нас научил иностранный партнёр, который отказал по 10 лицензиям из 10, и по каждой сделал это так красиво, как будто подписывал с нами миллионный контракт.
Ну на пальцах основные отличия для новичка, который не знает, что «потрогать» первым.
1. Vue не требует вообще никакой инфраструктуры, его можно воткнуть в существующий сайт с вордпрессом на шаред php хостинге, особенно если вы в курсе, что ослик сдох. Для реакта и ангуляра надо где-то поднимать ноду, npm/yarn, webpack/parcel, а потом два дня разбираться, чем babel/core отличается от babel/core и почему на первом create-app не заводится. Ну то есть какой-нибудь бандлер потом, перед выпуском в прод, настроить придётся, но это будет потом, и для vue достаточно будет parcel с нулевой конфигурацией.
2. Vue не требует изучать новые языки, работая на чистом HTML и JS. Гипотетически реакт тоже так может, но по факту 99% примеров и готовых react компонентов используют JSX и ~50% — Typescript. Это всё заметно увеличивает порог входа.
3. Vue не настаивает на функциональной парадигме, его вполне устраивает ООП. Если вас пугают выражения типа
let b = f => g => h => x => f(g(x))(h(x))
в реакте будет сложновато. При этом, если вам нравятся god object-ы на 100500 полей и методов, которые отвечают за всё, включая состояния кнопок, то vuex (аналог redux/flux/...) вполне себе есть, берите и пользуйтесь.
4. Следствие п. 3 — двусторонние биндинги. Они просто работают. Вам не надо, как в 90-ых, писать handleChange/handleKeyUp/… для каждого html элемента, а потом городить UNSAFE_ComponentWillRecieveProps и делать прочие приседания в скафандре. В результате наличию этой и других мелких сладких плюшек (например, стандартного роутера из коробки) кода на vue получается стабильно раза в 2-3 меньше, чем в таком же проекте на реакте, а пишется он быстрее.
Я спустя 3-4 года возни с redux пришёл к таким выводам:
Action types не только не нужно хранить отдельно от action creators. Их вообще не нужно делать. Для чего они могут пригодится? Для того чтобы иметь в рамках одного типа несколько фабрик action-ов. На моей практике такой случай не наступил ни разу. Могу смело сказать, что в 99% это просто бойлерплейт. Мусор. Мусору нечего делать в кодовой базе. Хотите глоссарий экшнов — автоматизируйте это. Как связывать reducer-ы с action-ами? Очень просто импортировать actionCreator-ы там где у вас reducer-ы и цепляться к ранее установленным (автоматически) actionCreator.type. Эти не сильно простые шаги уменьшат боль при написании redux приложений раза в 2.
Держите в простых случаев reducer-ы там же где и actionCreator-ы. А сложных случаев избегайте (дробите). Может показаться странным, но это радикально уменьшает количество бойлерплейта и упрощает поддержку кода. При этом различные слои не путаются, просто лежат ближе. Недостатков пока не выявил. А вот разного рода селекторы бывает полезным вынести отдельно, т.к. их иногда может 3\4 от кода набраться и они не привязаны ни к каким экшн-тайпам.
Используйте proxy в reducer-ах. Это невероятным образом улучшает как кодовую базу, так и экономит ваше время. Мутабельный код с преимуществами иммутабельного. Лучшее что я видел для redux. Реализация довольно простая, да и есть готовые решения. После внедрения бизнес-логика перестаёт выглядеть как тихий ужас.
Забудте про switch-case. Ден привёл в качестве примера и понеслась. Преимуществ у них похоже никаких, но все их пишут и пишут. Куда удобнее держать привязку action-type -> handler(state, action, rootState)
1 action = 1 handler. Не прогонять каждый action через все reducer-ы. Принудительно привязывать обработку задачи к одному handler-у. Делает код куда более предсказуемым. Это одна из важнейших вещей в redux-е. Как это обеспечить? Ну например держать путь к reducer-у в action.type. Хотя тут много вариаций.
Поменяйте сигнатуру каждого редьюсера с (state, action) на (state, action, rootState). Это позволит избежать тех хаков, когда вам для изменения под-части стора не хватает данных из другой ветви стора, и вы жутко извращаясь пихали эту логику прямо в actionCreator или выше. Это бессмысленный бред. При этом разумеется из одной ветки стора на другую повлиять нельзя. Цепляться не обязательно к rootState, тут надо смотреть на ваш IoC
Используйте нормализацию. Ну тут много про это писали. Это архиважно
Используйте memo, useAutoCallback, useAutoMemo, PureComponent и прочие примитивы с shallowComparison. Это азбука производительности вашего приложения. Очень помогут weakMemoize-ы разного рода. Селекторы, линзы и прочее. Обычно в серьёзном приложении таких утилит\помощников скапливается много.
Это не опечатка.
Пример самой вакансии.
https://web3.career/senior-rust-developer-solana-rarible/15599
Комментарии разрабов, кто такую зп получает
https://www.reddit.com/r/rust/comments/rvxzcw/comment/hra5sou/?utm_source=share&utm_medium=web2x&context=3
https://www.reddit.com/r/rust/comments/rvxzcw/comment/hr8vpc8/?utm_source=share&utm_medium=web2x&context=3
Хочу сказать пару слов про первую книгу. Я нашел ее буквально случайно, когда я первый раз стал менеджером. С тех пор я рекомендую эту книгу всем своим подчиненным - будь они менеджеры менеджеров, линейные менеджеры, тимлиды или просто инженеры которые думают о переходе на лидерские позиции.
Почему мне так нравится эта книга? По ряду причин.
Она написана очень простым и понятным, no-bullshit языком, инженером для инженеров. Многие книги по бизнесу и лидерству (особенно американских авторов) грешат тем, что первые три главы тебе рассказывают о том, как этот подход изменил жизнь многих известных людей, потом еще две о том, как автор пришел к этому подходу, и только в конце, кратенько - в чем, собственно, подход заключается.
Ее можно читать в любом порядке, в том числе - как справочник. Может показаться, что если ты TL, то глава The Big Leagues тебе пока не нужна - но это не так. Чтение поможет понять, как мыслят люди в таких позициях, что для них важно и как выстраивать разговор и аргументацию с ними.
В том числе, если ты менеджер менеджеров, читая главу про TL-ов, можно лучше понять как растить людей, как давать им stretch goals (задачи по силам, но на пределе, которые стимулируют развитие)
В книге довольно много конкретных примеров и рекомендаций, в стиле "попробуй так, а не получится, попробуй еще вот так".
Наконец, эта книга описывает не сферический менеджмент в вакууме, а менеджмент именно инженерных команд - в этом (как, пожалуй, и везде) очень много специфики, и ее нельзя не учитывать.
Короче, это отличная книга и я настоятельно рекомендую ее всем, кому интересно лидерство именно в технической сфере.
ваш рост зарплаты не связан с ростом зарплат на рынке - это хороший рост как специалиста, обусловленный низкой базой. Если бы вы были senior или tech/team lead с опытом 10+ лет, ваш рост зарплаты в процентах был бы совсем не таким впечатляющим.
Shameless plug: проект code-review-checklists/java-concurrency на Гитхабе содержит много советов из JCIP упакованных в форму применимую во время ревью кода с многопоточностью.
Спасибо за отличное интервью.
Мне кажется, это очень интересный вопрос.
Во-первых, культ производительности определенно есть не только в Джаве: посмотрите доклады на конференциях по Go, С++, JavaScript — там тоже очень много докладов про производительность, и зачастую это самые посещаемые доклады.
Думаю, культ во многом связан с эго: "если я написал код быстрее, чем коллега, значит я круче/умнее". Посмотрите на заголовки проектов на Гитхабе: многие имеют вид "Fast(est) [Thing] for [Language]". Вдобавок, производительность относительно легко сравнивать.
Было бы интересно видеть в индустрии больше проектов с заголовками типа:
См. Deep Work & Digital Minimalism
https://shipilev.net/blog/2014/exceptional-performance/
Изначально был выбран неправильный тип метрики для решения задачи. Стандартный джентльменский набор для веб-сервисов:
Сочетание 3 и 4 дало бы вам совершенно четкую картину вашей аварии: рост latency и рост числа запросов in flight.
Мой личный список вопросов работодателю (если не было освещено на собеседовании).
Чем я буду заниматься? Только узкими обязанностями или еще и смежными?
Какой стек на моём проекте? Есть ли легаси?
Что с тестированием
Есть ли CI/CD и девопс инженер?
Будет ли единый ПМ и четко заданный жизненный цикл таска?
Есть ли БА?
Системы мониторинга, сборщик логов?
Переработки бывают? Оплата?
Системы трекинга времени и руткиты на рабочем компе?
Отпуска: дробление отпуска, включены или нет выходные, за сколько нужно предупреждать, отказы
За что и как часто получаются премии? Кто определяет их размер?
Есть ли СБ? Какие требования у СБ?
Почему открыта вакансия? Если не новая, то куда ушел предыдущий разработчик?
Аналогично про гибкий график, карьерный рост. Что это значит и в чем выражается.
Ретроспектива.
Код ревью в компании: кто, как долго, что если пожар.
В случае с опционами обычно контракт предполагает 4 года на весь пакет акций, с возможностью забирать частями после первого года ("one year cliff"). Т.е. всегда есть возможность выйти с 3/4, если после трех лет. Рассматривали такой вариант? Ведь всех денег не заработаешь, а опцион, даже реализованый, еще не дает гарантий, что компания будет успешной и эту инвестицию можно будет реализовать.
Я работал около трех в стартапе, контрактором. Опцион на момент моего ухода из компании стоил около $27k (поскольку стартап все время своего существования был прибыльным, нет возможности ставить цену акции в опционе нулевой). В этом случае даже опцион рассматривается как инвестиция — мне необходимо вложить $27k чтобы превратить опцион в акции, затем со временем, если компания выйдет на IPO или будет куплена (событие "exit"), я смогу продать эти акции, заплатить налоги и получить прибыль. Т.е. даже в случае рабочего, прибыльного стартапа с продающимся продуктом для опционов остается много "если", прежде чем этот вид "компенсации" превращается из ваших часов на роботе и денег в прибыль.
Для тех, кому интересна тема опционов, вот пара хороших ссылок:
Первый тип отличается следующими вещами
— как правило это не инженеры
— у них строгий график работы
— у них может быть строгий дресскод
— их задачи и цели имеют четкое описание и как правило их можно легко контролировать
— любая переработка оплачивается как сверхурочные
Второй тип
— здесь как правило все инженеры/синьоры/менеджеры
— нет строгого графика работы, но он часто регулируется фиктивно, путем назначения регулярных митингов в определенное время, не обязательно в «нормальные» рабочие часы. Но присутствие в офисе во время митингов не является обязательным, хотя и желательно(живое общение всегда лучше)
— может не быть дресскода
— задачи ориентированы на достижение цели в определенном временном промежутке (недели или месяцы)
— переработка отсутствует как класс, из-за того что требуют решить задачу, а не просидеть на работе
Исправляем ситуацию… Допустим, у вас есть следующий метод
Видите ключевое слово yield? В нем все дело.
Теперь вы узнали о чудесной конструкции async await и хотели бы применить ее к данному методу. И у вас даже есть новый метод ReadFileAsync.
Вы хотели бы, конечно, написать что-то такое
Так вот! Раньше так нельзя было написать. А в C# 8 можно.
Сейчас опытным путем смог найти этот «Services».
Судя по всему для того чтобы это окно было доступно и видно (в том числе при поиске команд), нужно чтобы существовал хотябы один сервис.
То есть нельзя открыть «пустое» окно сервисов.
Я в новом проекте сделал себе коннекшн к базе. После того как его создал, это окно сразу появилось (и также опция Services в поиске стала доступна).
git-awards.com/users/search?login=0xd34df00d
1. Vue не требует вообще никакой инфраструктуры, его можно воткнуть в существующий сайт с вордпрессом на шаред php хостинге, особенно если вы в курсе, что ослик сдох. Для реакта и ангуляра надо где-то поднимать ноду, npm/yarn, webpack/parcel, а потом два дня разбираться, чем babel/core отличается от babel/core и почему на первом create-app не заводится. Ну то есть какой-нибудь бандлер потом, перед выпуском в прод, настроить придётся, но это будет потом, и для vue достаточно будет parcel с нулевой конфигурацией.
2. Vue не требует изучать новые языки, работая на чистом HTML и JS. Гипотетически реакт тоже так может, но по факту 99% примеров и готовых react компонентов используют JSX и ~50% — Typescript. Это всё заметно увеличивает порог входа.
3. Vue не настаивает на функциональной парадигме, его вполне устраивает ООП. Если вас пугают выражения типа в реакте будет сложновато. При этом, если вам нравятся god object-ы на 100500 полей и методов, которые отвечают за всё, включая состояния кнопок, то vuex (аналог redux/flux/...) вполне себе есть, берите и пользуйтесь.
4. Следствие п. 3 — двусторонние биндинги. Они просто работают. Вам не надо, как в 90-ых, писать handleChange/handleKeyUp/… для каждого html элемента, а потом городить UNSAFE_ComponentWillRecieveProps и делать прочие приседания в скафандре. В результате наличию этой и других мелких сладких плюшек (например, стандартного роутера из коробки) кода на vue получается стабильно раза в 2-3 меньше, чем в таком же проекте на реакте, а пишется он быстрее.
При всём при этом реакт, конечно, дико распиарен.
Я спустя 3-4 года возни с redux пришёл к таким выводам:
Action types не только не нужно хранить отдельно от action creators. Их вообще не нужно делать. Для чего они могут пригодится? Для того чтобы иметь в рамках одного типа несколько фабрик action-ов. На моей практике такой случай не наступил ни разу. Могу смело сказать, что в 99% это просто бойлерплейт. Мусор. Мусору нечего делать в кодовой базе. Хотите глоссарий экшнов — автоматизируйте это. Как связывать reducer-ы с action-ами? Очень просто импортировать actionCreator-ы там где у вас reducer-ы и цепляться к ранее установленным (автоматически) actionCreator.type. Эти не сильно простые шаги уменьшат боль при написании redux приложений раза в 2.
Держите в простых случаев reducer-ы там же где и actionCreator-ы. А сложных случаев избегайте (дробите). Может показаться странным, но это радикально уменьшает количество бойлерплейта и упрощает поддержку кода. При этом различные слои не путаются, просто лежат ближе. Недостатков пока не выявил. А вот разного рода селекторы бывает полезным вынести отдельно, т.к. их иногда может 3\4 от кода набраться и они не привязаны ни к каким экшн-тайпам.
Используйте proxy в reducer-ах. Это невероятным образом улучшает как кодовую базу, так и экономит ваше время. Мутабельный код с преимуществами иммутабельного. Лучшее что я видел для redux. Реализация довольно простая, да и есть готовые решения. После внедрения бизнес-логика перестаёт выглядеть как тихий ужас.
Забудте про switch-case. Ден привёл в качестве примера и понеслась. Преимуществ у них похоже никаких, но все их пишут и пишут. Куда удобнее держать привязку action-type -> handler(state, action, rootState)
1 action = 1 handler. Не прогонять каждый action через все reducer-ы. Принудительно привязывать обработку задачи к одному handler-у. Делает код куда более предсказуемым. Это одна из важнейших вещей в redux-е. Как это обеспечить? Ну например держать путь к reducer-у в action.type. Хотя тут много вариаций.
Поменяйте сигнатуру каждого редьюсера с (state, action) на (state, action, rootState). Это позволит избежать тех хаков, когда вам для изменения под-части стора не хватает данных из другой ветви стора, и вы жутко извращаясь пихали эту логику прямо в actionCreator или выше. Это бессмысленный бред. При этом разумеется из одной ветки стора на другую повлиять нельзя. Цепляться не обязательно к rootState, тут надо смотреть на ваш IoC
Используйте нормализацию. Ну тут много про это писали. Это архиважно
Используйте memo, useAutoCallback, useAutoMemo, PureComponent и прочие примитивы с shallowComparison. Это азбука производительности вашего приложения. Очень помогут weakMemoize-ы разного рода. Селекторы, линзы и прочее. Обычно в серьёзном приложении таких утилит\помощников скапливается много.