Статистика ВК сообщества "Высшая Школа Программирования Сергея Бобровского"

0+
Обучение программированию и computer science, развитие рационального мышления.

Графики роста подписчиков

Лучшие посты

Печальные последствия моды на Специалистов по Науке о Данных ))) когда Data Sience учат повсюду, навешивая тонны лапши "с ходу зп без опыта 70т" "поможем получить работу мечты в DS" бла бла бла, а потом закончившие такие курсы обламываются на иллюзорных вакансиях, и начинают так же безрезультатно ломиться на вакансии для классических программистов — но, внезапно оказывается, что это уже совсем другая профессия.

Типичный пример с собеседования, ищут питониста.

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

Интервьюер пытается помогать :)

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

=

Поразительно, как много сегодня расплодилось людей, которые знают Python на уровне импорта пандас и нескольких его заклинаний для выполнения простых запросов, но совершенно не знают элементарных основ языка и problem solving (например, "уметь использовать словарь").

Попросите их сделать что-нибудь, с чем Pandas не может справиться, и это будет полный крах.

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

Именно поэтому принципиально не обучаю никаким прикладным практическим темам, и никогда не буду. Универсальные знания вечны, и со временем становятся только ценнее. А знания технологий, фреймворков, библиотек — это временный мусор, пыль, которая через несколько месяцев сдуется чем-то более новым. Нулевая ценность на самом деле, просто google it.

=

Зарплаты классических программистов в этом году резко подорожали, знакомые разрабы бегут даже из топовых госконтор "Рос***" и "Рос*****", частные фирмы переманивают на куда большие оклады.

Но что насчёт вашего уровня профессионализма?

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

Из недавних отзывов с моих курсов по этой теме:
"Недавно заглянул на "Java. Базовый курс Stepik" и с интересом обнаружил, что решать задачи я сразу планирую циклами и условиями. А в комментариях к задачам практически все рекомендуют, тот или иной готовый метод. Для меня это было собственным открытием, уже сейчас я хоть и немного, но отличаюсь, от многих начинающих программистов. И все это благодаря вам Сергей, за это очень вас благодарю :)"

=

P.S. Ещё кстати один удивительный момент с собеседований — это когда ребята, претендующие на джуниора, не владеют даже самым элементарным представлением о сложности (O(1), O(N), O(N*N)...), хотя бы на уровне разделения константного и линейного времени. А это ведь буквально самый базовый анализ сложности, который необходимо хотя бы понимать, когда пишешь код.

124 0 ER 5.4999
В классической инженерии (не программной) есть простая, но бесценная практика, замечательно применимая к ИТ-проектам. На ранней стадии разработки ведущий специалист пишет обзор системы на достаточно высоком абстрактном уровне: что система делает, и как она это делает. Объём этого обзора не должен быть меньше 5 страниц и не более 20 страниц (в зависимости от сложности). На каждые 2-3 страницы должна приходиться одна диаграмма. Обзор должен всё время поддерживаться в актуальном состоянии.

Плюсов тут три.

1. Не вдаваясь в технические подробности, дать впоследствии любому новому человеку, подключающемуся к проекту, достойное представление о том, а что вообще происходит.

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

3. Чтобы декомпозировать систему на правильные компоненты, обеспечить наиболее разумные интерфейсы между ними, и чтобы сделать это всё простым и элегантным, требуется определённая проектная дисциплина; регулярное ведение/обновление/улучшение такого документа и организует такую дисциплину на самом высоком уровне.

=

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

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

Написание такого документа должно происходить до того, как будет написана хотя бы одна строка кода. Ну за исключением, возможно, каких-то пробных концепций, хотя и тут злоупотреблять кодингом не следует (недавно выложил на учебном сервере материал для донов "Как правильно создавать
прототип/MVP вашего продукта" — почему лучше забыть об универсальном прототипировании продукта и MVP, почему программы-прототипа в общем случае не существует, и что вообще делает один прототип прототипом, а другой нет?).

=

Если вы не можете описать систему на простом и понятном вашим коллегам языке, то вам не стоит пока за неё браться. Очень-очень часто разработчик начинает создавать проект, не имея четкого представления о том, куда вообще он идёт. Типа, почесал, такой, затылок, открыл пустой экран редактора кода, и пошёл бездумно фигачить "естественные" классы. И на втором десятке полностью запутался и потерял понимание :)

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

=

На практике, сколь бы точные абстракции мы ни придумывали, они никогда не смогут точно описать реальные ситуации, реальный мир. Та система типов, тот язык прикладной области, который мы создаём и которым затем пользуемся в процессе непосредственного программирования — это всё построения классической логики. А требуются по сути построения конструктивной (интуиционистской) логики. Поэтому, пока в повседневное программирование не придут языки, поддерживающие MLTT (Martin-Löf Type Theory) например, так и будем бесконечно заниматься производством приляпок и латанием огромных прорех между программной моделью, по определению совсем слабенько моделирующей реальный мир — и самим этим миром.

Вот как раз хороший документ — конструктивный обзор проекта, выполненный грамотным техническим языком, и способен снять немало подобных проблем. Но, для его создания надо как следует подумать, а это кстати гораздо труднее, чем писать код. Потому что кодописанина со временем просто становится навыком, выдаёшь в продакшен свои 10-20 строк кода в час буквально "не думая", но огромный минус этого подхода, что такой застывший навык кодирования (бессознательная компетентность) со временем сам становится серьёзным препятствием, ограничивая профессиональное развитие. Что с этим делать, понятно: периодически вытаскивать свой уровень мастерства в сознательную компетентность и там шлифовать и улучшать. Как это делают в топовых университетах мира, как повышать свою продуктивность и быстро, и стратегически — в следующем посте.

69 0 ER 3.5143
"Когда кажется, что в жизни всё рушится, начинайте думать о том, что построите на освободившемся месте." (с)

1. У меня всё прекрасно, и перспективы самые радужные 💥🚀💪🏻 Надёжность и живучесть моей Школы абсолютна, потому что, ну вот я её так спроектировал и организационно, и технически. Проект этот благотворительный по большому счёту; я могу, формально говоря, вообще бесплатно обучать, т.к. мне это очень нравится; а так то мой доход на 80% складывается из других источников: консультирую разные небольшие команды по проектированию, а теперь ещё и по кибербезопасности, у меня заявок и работы тут вообще до следующего десятилетия.

Но платить занимающимся в моей Школе надо обязательно: ощутимая для человека оплата за курсы — это абсолютно необходимый (из двух) фактор его успешного обучения. А с бесплатных курсов сливается 100% независимо от их важности для человека.

2. Заметил интересную вещь, что стоило одному человеку установить свою карьерную цель 500k/месяц на моём учебном сервере, как тут же несколько других ребят замотивировались этим и стали тоже думать о более внушительных планах :) В рамках результатинации думаю сделать обязательным всем без исключения декларировать своей целью конкретную сумму зарплаты/дохода. Ничего страшного, что у кого-то она 500 тыс, а у кого-то без опыта будет цель 50 тыс, это нормально. Проблема в другом: одни получают 40, а другие с практически таким же уровнем знаний — 140. Очень, очень многие себя недооценивают... У человека уже уверенный уровень второго курса университета по computer science, а он всё чего-то боится.

Ну и сегодня конечно, вообще каждому программисту без исключения надо требовать индексации зарплаты, с 1 апреля +30% для начала вот прям обязательно выбивайте. Вам будут конечно ныть про трудную ситуацию с денежками в стране и в компании, всем тяжело надо потерпеть бла бла бла, ну на курсе карьеры разбирал эту фишку: трудные финансовые времена и были и есть и будут абсолютно всегда, это совершенно не аргумент; ваши начальники на то и начальники, что должны в первую очередь оперативно решать финансовые проблемы, ну а если не могут, ну значит сами профессионально некомпетентны.
В целом же, думаю, немало сильных сеньоров реаллокируются (смотрю даже по занимающимся у меня — тренд), и уже скоро джунам будут платить по-сеньорски.

3. Немного в продолжение предыдущего пункта: надо признать, что мой нынешний курс по фрилансерству потерял актуальность. Апворк перестал работать с РФ, ну и другие площадки тоже наверняка прикроются. Какие-то обходные пути остаются, но уже сильно усложнённые, поэтому стратегически рекомендовать всем занимающимся эту схему уже не могу.

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

А вот искать и работать с нормально платящими и адекватными заказчиками смысл есть и очень большой, стратегически двигаясь в построение своего ИТ-бизнеса. Но, тут сермяга в том, что находить таких через наши популярные сайты фриланса нереально. А правильно, с самого начала по взрослому действовать — через личный бренд, искать хороших заказчиков рекламой, и т. д. Сколько лет уже пишу о важности личного блога — ну и где он? Я например эталонный пример: почти все мои заказчики консультаций вышли на меня через эту Школу (точнее, через мои посты в этом паблике), а вы чего ждёте? Ладно...

4. Отдельно хочу коснуться отечественного геймдева. Он конечно пострадал сильнее всех других отраслей, потому что во многом ориентирован на продажи по миру, через сервисы вроде Стима и т. п. Но в целом данные риски были вполне предсказуемы, и конечно надо было просто регистрировать фирму, занимающуюся продажами, на Западе, а тут держать только разработческий отдел. Конторы кто поумнее кстати, так и делают давно. Ещё в начале 1990-х, когда работали небольшой оффшорной командой, менеджер был американцем и разруливал там у себя всё лично (а платили нам сперва по 50 долларов в месяц, и это тогда была неплохая сумма :).

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

Вообще, поразительно, как простые относительно и крайне актуальные в ИТ вещи годами остаются на уровне обсуждений, едва начинается контакт с официальными структурами, где по определению никто не хочет брать на себя ответственность. Такой сервис можно ЗА НЕДЕЛЮ запилить в каком-то минимальном формате! В расчёте на миллион пользователей в первом приближении, с простым горизонтальным масштабированием. Ребята, сегодня это уровень курсовой работы старшекурсника! ну максимум дипломной! Но т.к. подрядчики обычно в этом ничего не понимают, под предлогом космической сложности их разводят на миллиарды.

5. Страва таки, как и предполагалось, тоже отключилась. Ну как отключилась: через впн как работала так и работает. "Банить по IP", а как ещё? По указанной в профиле стране? Я на всякий случай сменил на Сербию :) По геотрекам? Ну а если я просто в длительной командировке...

Понятно, что можно каждого конкретного выискивать, изучать и отдельно банить, но это нафиг никому не надо, систему придётся специально допиливать, а у подобных сервисов и так куча головняка от возврата платных подписок. Ну, вообще клон Стравы или Инстаграмма можно за ту же неделю запилить, на гитхабе например есть похожие фуллстек-проекты, чуть-чуть в плане масштабирования доделать, а UI я бы вообще сделал, из вредности :) 1:1 с оригиналом. И автоматически переадресовывать с оригинальных сайтов, пока они блочатся, на отечественные аналоги.

Да хоть бы вообще все западные сервисы ушли, ориентироваться стратегически на это лучше. Прожить без ифонов фейсбуков гуглов и гамбургеров куда проще (да и лучше), чем без нефти газа сырья металлов. Пока единственное реальное возражение, что серьёзные пацаны боятся, чтобы третьи стороны не влезли в их всяческие корпоративные документации, если хранить это всё в российских облаках. Ну, решается просто: использовать какие-то локальные механики шифрования. "Для внутренних целей" законом разрешено использовать сколь угодно сильные алгоритмы, любой студент по ИБ напишет такую криптоутилиту за 100 долларов, элементарная задачка по большому счёту. Алгоритмы шифрования с абсолютной криптографической стойкостью (вроде Вермана), собственно, существуют более сотни лет :) Глобально ими сложно пользоваться, а вот в локальных задачках в самый раз. 😎

-продолжение следует-

49 0 ER 2.3235
Как читать много и, самое важное, продуктивно? Рекомендации Алана Кэя. Его как-то попросили пояснить за случайное по сути высказывание, что он прочитал около 20,000 книг. Кэй начал читать в 3 года, а в 5 читал уже бегло и "прожорливо". Сейчас ему 82 года, и он рассуждает и пишет крайне здраво. Но если бы он читал даже по одной книге в день (что конечно невероятно), то на сегодня получилось бы 25-30 тысяч книг. Сам Кэй полагает однако, что прочитал примерно 16,000 книг (довольно точная оценка :) ну ладно бы, сказал "15,000"), однако самое уникальное, что это отнюдь не "проглатывание", а наоборот: Кэй говорит, что ещё в школе понял, что ему придется читать одни и те же книги снова и снова, если он не научиться запоминать лучшее из них на долгосрочную перспективу. И он этому специально научился.

Однако объяснить, что такое "хорошее запоминание", гораздо сложнее, нежели "беглое чтение" — и то, и другое, безусловно, навыки (как навыки в спорте или музыке). Дополню тут Кэя — уже упоминал не раз, очень в тему книга "Вспомнить всё" Питера Брауна, которая совсем не про "тупое" запоминание, а именно про качественное изучение материалов.

=

В сущности, обучение навыкам заключается в том, чтобы заставить вашу быструю систему мышления S1 (Кэй явно рекомендует книгу "Думай медленно, решай быстро" Канемана, о которой тоже не раз писал) обратить внимание на те вещи, в которых вы хотите преуспеть. Эта система почти невидима для нашего сознания, и ею трудно управлять (на самом деле она управляет нами гораздо чаще, чем это полезно для нас). По этому поводу известный американский бизнес-коуч — нет, не Тони Роббинс ))) — Тимоти Голви (к которому кстати Алан Кэй относится с уважением) заявлял: "Те части вашего сознания, которые вам нужно обучить, не понимают русского языка!" (в оригинале, понятно имеется в виду английский).

От Тимоти Голви тоже кстати рекомендую классику "Внутренняя игра в теннис" 1974 г. Недаром среди его клиентов IBM, Apple, AT&T, и даже Кока-Кола :)

Конечно, помогает и классическое повторение с хорошим фокусом внимания. Но, вообще, с управлением своим вниманием тотальная беда; давно хотел сделать хотя бы небольшой курс a-la "внимание для программистов".

И, да, раннее начало обучения S1 тоже очень полезно: вон, восьмилетний (!) Хеймдалль Тепляков в этом году сдал ЕГЭ и собирается на мехмат МГУ. Что у него "не было детства" это бред; лучше что ли в игры на телефоне годами тупить, или крапиву рубить палкой? Гораздо лучше повзрослеть раньше, нежели позже: до сих пор встречаю инфантильных занимающихся и за 40 лет, которые начинают ныть и сдаются при первых же трудностях.
Вот это действительно детский сад штаны на лямках.

=

Кэй кстати в ходе "вдумчивого чтения" десятков тысяч книг раскопал такую контринтуитивную фишку, что хотя считается, что во время чтения очень важно постоянно пытаться глубоко вникать смысл изучаемого (подключение "медленной думалки" S2), однако такой подход далеко не всегда оказывается хорошей стратегией. Наоборот, расслабление и откладывание "умеренного понимания" на несколько часов — и особенно до следующего дня — даёт подчас гораздо больше пользы. Речь о том, что вы читаете с помощью S1 и параллельно отмечаете в реальном времени, что важно, однако не грузите это сразу в S2, а позволяете своей памяти и внутреннему механизму мышления пережевать это в течение нескольких часов или ночи. То есть задействуем кратковременную память для ввода текста в ум в реальном времени, а затем "разрешаем" кратковременной памяти сохраниться и переработаться в полезную информацию.

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

=

Кроме того, ещё одно из важных следствий того, что вы много читаете: в вашем уме появляется гораздо больше вещей, с которыми можно проводить аналогии, а благодаря таким аналогиям запоминать многие вещи становится гораздо легче. И ещё другим приятным побочным преимуществом становится то, что аналогии сами по себе — один из лучших способов возникновения/генерации идей.

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

=

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

Следовательно, очень вероятно, что существуют весьма авторитетные точки зрения - в том числе и критические точки зрения - с которыми человек ещё просто не сталкивался. Это хороший намёк на то, что даже в научной деятельности и в развитии рационального мышления вы не можете прийти к той слепой уверенности, которой жаждет наш генетически обусловленный мозг, и которой потворствует наша культура. А вот принимая некую неопределенность и относительность суждений, можно начать видеть многие вещи гораздо более ясно.

Из этого, кстати, такое следствие, что сотрудничество — это лучшая и стратегия, и тактика, нежели конкуренция в науке, инженерии, политике и жизни. Именно поэтому любой спор должен иметь целью продвижение просвещения, а не "победу" над оппонентом.

=

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

P.S. От себя добавлю, что сегодня как минимум в отношении "не очень великих книг" хорошо заходят аудиоверсии. Чтение — это всё же некоторое усилие ума, которое по определению подвержено когнитивным искажениям (например, порхающее внимание), а вот слушание пассивно, оно никак не может повлиять на звуковой поток, никуда не может от него убежать, и хотя отвлечения тоже конечно случаются, но всё же и слушание аудиокниг сегодня может быть очень продуктивным.

160 0 ER 3.0432
Мой прогноз, какие ключевые проблемы ждут объявленные на прошлой неделе планы по "по вопросам обеспечения технологического суверенитета государства в сфере развития критической информационной инфраструктуры РФ", и как надо делать правильно. Ну прежде всего 80-90% подобных проектов — программно-аппаратные комплексы, встраиваемые системы, IoT, жёсткое реальное время, и вот у всех подобных проектов, от "помигать диодиками на ардуинке" до сложнейших АСУ ТП, есть одно общее: коллективы разработчиков традиционно пишут код для этого всего на Си и немного на С++.

И это полная катастрофа.

=

Сегодня на повестке дня два вопроса:
1. Как наладить производство гвоздей.
2. Полет на Марс.

=

Си, самый популярный из всех языков для подобных задач, очень много писал на нём, и потом на плюсах, ещё с конца 1980-х, лет 10 минимум, в том числе для парижского Canal+. До явления интернета во Франции между прочим была своя национальная компьютерная сеть Minitel (все стационарные телефоны с экраном, ну и платный софт всяческий).
Актуальность архитектурных принципов построения распределённых систем вечна :) Итоговый курс по ним (и соответственно трек по параллельным вычислительным моделям) закончил кстати, выкладываю на сервер.

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

Не поймите меня неправильно — мне нравилось программировать на Си. Ассемблер кстати ещё более увлекателен, я перед сишечкой активно кодил на разных ассемблерах — и для IBM/370, и для PDP/VAX... Да, это было очень интересно, хотя сейчас я этого бы не одобрил :) Потому что продуктивное создание реальных программных продуктов подразумевает всё же несколько иные технологии и подходы, чем вот эта вся чистая инженерщина ради фана.

С тех пор не встречал и близко ни одного языка программирования, который допускает такие глупые ошибки, как выход за пределы строки или массива или переполнение буфера. Я одно время сделал на учебном сервере поддержку С++, но потом отказался — в нём так и не появилось нормального try для типовых ошибок! Просто невозможно отловить элементарные баги. Может какие-нибудь хорошие коммерческие компиляторы это умеют, но не бесплатный мэйнстрим.

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

99% десктопных Windows-программ (и большинство из них, конечно, написаны на Си/C++) допускают утечки памяти, вызванные неправильным использованием malloc() и free(). Хотя в мире серьёзных АСУ ТП такое случается пореже, всё равно огромное количество микропрограмм динамически распределяют память. Язык программирования в принципе не должен допускать утечек! проверки, гарантирующие целостность памяти, необходимы. А вычислительные затраты на это минимальны.

Работа с указателями в Си совершенно ничем не ограничена. Хотите разыменовать нулевой указатель? Вперёд! Языку нет до этого никакого дела. Не стесняйтесь делать любую математику с любым указателем. Это весело!

Вот вам подсказка по языку Си, которая невероятно повысит безопасность вашего проекта: используйте двойное обращение по указателям **
Еще лучше — попробуйте тройное. Настоящие программисты используют четыре звёздочки. Единственное ограничение на количество звездочек перед именем переменной — это размер ваших мускулов или то, насколько смелым вы себя считаете.

(это был сарказм, на всякий случай)

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

Даже такая элементарная вещь, как целочисленная арифметика, дает неожиданные результаты. 20,000 + 20,000 в какой-нибудь 16-разрядной плате управления самолётом может оказаться отрицательным числом. Это ещё как круто! Ещё лучше то, что фундаментальный тип int вообще не подразумевает никакого определённого значения. Оно зависит от марки процессора, версии компилятора и направления ветра.

Ни по одному другому языку, активно используемому в ИТ, не проводятся соревнования по степени запутанности кода. Выиграйте, написав для управления АЭС код, который работает, но настолько запутан, что ни один эксперт по Си не сможет понять, что тут вообще происходит. Большинство конкурсных работ выглядят так, будто котик долго-долго прыгал по клавиатуре. И нет, я не буду указывать здесь сайты с конкурсами по запутанности; эти люди — программисты-террористы, которых следует выследить по IP и ликвидировать.

=

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

Были единичные относительно удачные исключения, например, язык Ада ))) Он был настолько синтаксически строгим, что эмпирическое правило гласило: "Если вы можете заставить эту чёртову штуку компилироваться, то она, скорее всего, будет корректно работать". Сам язык выступал своеобразной смирительной рубашкой, которая приводила к созданию действительно надёжных микропрограмм, и на котором в США было написано огромное количество военных систем, успешно работающих и сегодня. И вот именно поэтому (слишком трудоёмко) Ada и не стала мэйнстримом, и потерпела относительную неудачу на фоне тотального "тяп-ляп и в продакшен".

=

Короче говоря, говорил месяц назад, что сегодня по очевидным причинам абсолютно обязательной нормой проектирования/system design должно стать глубокое тотальное следование в проекте архитектурным нормам безопасности с самых первых шагов. Си для этого абсолютно не подходит; однако действующие профильные команды разработчиков обучены "клепать" именно на нём условные АСУ ТП, а других для развития критической информационной инфраструктуры взять, понятно, неоткуда (да те что были многие вдобавок разбежались).

Вот как надо (и как всё равно конечно не будут/не смогут делать):

1. По-хорошему, всю подобную критическую инфраструктурщину желательно пилить на Ada-подобных языках, которые неявно ведут к корректному коду.
Если честно, очень тут жалею, что канули в небытие Паскаль (Delphi) и Оберон...

2. Ещё лучше, если в таких проектах активно будет применяться формальная верификация, но это пока реально дорого и сложно. Но как минимум, можно следовать полуформальным методам, поддерживая двустороннее отображение/соответствие между моделью и кодом хотя бы на уровне документации. В Сильных Идеях выкладывал материалы на тему, как начинать правильно думать о коде и абстракциях, и дальше обязательно продолжаю.

3. Надо однако признать, что Си никогда не исчезнет :) Поэтому тут единственная стратегия — согласиться использовать ограниченный диалект этого языка, строго придерживаться промышленных стандартов, например MISRA. Софт для истребителя F-35 например создаётся в соответствии с MISRA-C:1998.
Или, 22 февраля вышла очередная версия Angband 4.2.4 (это одна из двух самых легендарных roguelikes), и вот "use C99 types instead of the angband special types" привело к "a LOT of bug-fixing" — и это после 30 (!!!) лет разработки и шлифовки кода на Си!


4. Ok, а что насчёт C++ ? На самом деле, это с оговорками тоже вполне приемлемый вариант. Тут самое ужасное может быть, когда сишники начнут механически переползать на плюсы как на "Си с классами", и получится самый настоящий карго-культ.
Тут правильно ориентироваться на нормальные стандарты начиная с C++11 хотя бы. RAII, перегрузка операторов, волшебная инициализация, константные выражения, вывод типов, лямбда-функции, темплейты (с поддержкой метапрограммирования и контроля за компиляцией, "программируем программный код")... Главный вопрос (риторический), откуда взять дорогущих специалистов, способных это всё грамотно применять? :)

5. Поэтому стратегически лучше переходить на какие-то минимально приемлемые альтернативы: Rust, Julia, Go, и хотя они пока тянут на троечку, но всё значительно лучше чем Си.

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

Вот конкретно: если решать, куда переходить с Си — на C++ или на Go, однозначно Go. Накладные расходы на сопровождение Go-систем очень сильно меньше, а главное, что Гугл создавал Go именно для реализации огромных проектов с сотнями-тысячами программистов очень среднего класса, когда благодаря принудительно "тупому" стилю кодинга и специфике языка как-то сильно поломать продакшен почти нереально, а любой разработчик при этом легко заменяем.

Строго говоря, Go — это не язык именно системного программирования, он скорее в этом плане где-то между Си/С++ и Java/C#. Если нужно что-то прямо чисто-чисто системное (ядро своей ОС :), то лучше Rust. Хотя вот докер же запилили на Go. Порекомендую книжку "Go Systems Programming: Master Linux and Unix system level programming with Go" например.

Резюме: для 90% проектов критических информационных инфраструктур Go отлично подходит; ещё 7% шлифуем Rust-ом, и 3% на С++.

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

51 0 ER 2.0342
Какую карьерную стратегию выбрать программисту? Прежде всего надо понять и принять, что всю свою жизнь вы как разработчик, будете сидеть. Весь день. Вы сидите и смотрите в монитор. Вы создаёте виртуальные вещи. Иногда это действительно интересно, иногда нет. Очень важное качество тут, соответственно — усидчивость.

В карьере вам будут встречаться два крайних полюса:

Очень большая компания: много занудных совещаний, много времени уходит впустую. Активные, энергичные, целеустремленные разработчики не очень хорошо относятся к таким организациям. А вот те, кто работает по размеренному принципу "от звонка до звонка" и не сторонник каких-то сложных вызовов, прекрасно справляются с рутинными задачками, и получают обычно хорошую зарплату. Минус: такая расслабляющая рутина быстро затягивает, и можно легко скатиться в самый последний вагон ИТ; найти новую работу со временем становится всё тяжелее.

Очень молодой стартап: Отличное развлечение — всегда есть что-то новое, но это также означает постоянную гонку и авралы, с которыми нужно постоянно справляться, в том числе и в выходные. Иногда это реально сводит с ума, и требования, предъявляемые к вам, обычно велики; но также всевозможные бонусы, опционы на акции и корпоративные вечеринки стоят того. Но не менее вероятны и разные финансовые проблемы, задержки зарплаты, и т. п.

В стартапе вы должны всё время идти в ногу со временем (и даже немножечко опережать его). То есть вам нужно отлично знать последнюю IDE, новые крутые фишки в вашем языке и фреймворке, и это меняется каждые несколько месяцев. Со временем это становится (слегка) утомительно — если только вы не очарованы всем этим пожизненно, как я например.

Но в конце концов, большую часть дня вы как программист просто будете сидеть, уставившись в монитор, и делать что-то где-то "там".

=

Однако моя рекомендация будет контринтуитивной. Много раз убеждался, что лучше всего специализироваться на чем-то непонятном или сложном, выбирать узкую нишу, не слишком уж мэйнстримовскую. Например, заниматься встраиваемыми системами и IoT; сейчас плавно взлетает AR/VR; параллельные системы... много чего происходит не слишком заметного. Зарплата кстати в таких нишах обычно тоже выше средней, потому что гораздо труднее найти специалиста. Но и войти в них понятно тяжелее (что само по себе тоже очень хорошо).

Потому что становиться фуллстек-разработчиком в целом хорошо, но их уже миллион, и десятки курсов их активно готовят, и порог входа в целом небольшой, ну за год активных занятий вполне реально, если есть базовые способности. Но вот именно поэтому, вы собираетесь конкурировать за свою работу фуллстек-девелопером с молодым энергичным парнишкой, готовым программировать за 1/2 вашей зарплаты? Добро пожаловать в ИТ :)

Так что специализируйтесь в чём-то сложном, тяжёлом, трудном. Формальная верификация, синтез программ, computer science, ищите подходящие узкие ниши. Причём вы почти всегда можете из них легко на время выйти в фуллстек (после подобных темок он вам покажется просто детским садом), если возникнут какие-то проблемы с работой, а вот из мэйнстрима к вам в принципе перейти не смогут.

50 0 ER 2.3132
Недавно приводил статистику, что сеньоры лучше миддлов по реализации схожих задачек примерно в пять раз на небольших проектах. Однако едва проект дорастёт хотя бы до сотни тысяч строк, лучшесть сеньоров падает всего до двух раз, и практически одинаковы с миддлами сеньоры становятся на проектах объёмом в миллионы строк.

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

Нет, сермяга в том, что в крупных проектах все программисты становятся примерно одинаково ужасными )))

Во-первых, ключевым становится качество проектирования, которому нигде не учат (как минимум, в десятки раз меньше, нежели programming in small), а у специалистов нету особого опыта.

И во-вторых, Фредерик Брукс печально иронизировал, что добавляя людей в запаздывающий проект, мы только делаем его ещё более запаздывающим. Потому что общение между людьми начинает пожирать всё время. Система обычно спроектирована слабовато, её сложность (связи между сущностями) не масштабируется линейно, и естественно на согласованиях стыковок пропадает уйма времени. Имея N сущностей, при кривом проектировании мы вполне можем получить N! проблем с согласованиями. Но ведь самые лучшие и умные "работают" на совещаниях ровно с той же скоростью, что и джуниоры )))

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

=

Однако такая тактика может стать ещё более проигрышной, если постановщики плохо проделали работу по выяснению и формулированию требований. В таком случае проект превратится в поток пробоин, и все ресурсы будут тратиться на борьбу с симптомами, на бесконечное латание прорех в проекте. А в мэйнстриме некачественный сбор требований, слабые ТЗ — это классика.

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

Классика тут — это книга "Разработка требований к программному обеспечению" Карла Вигерса, но поразительно, что даже в лучших университетах мира этой теме в информатике практически не уделяется внимания, хотя наверное каждый тимлид и сеньор знает, насколько важны хорошие требования и как сильно от них зависит качество и скорость реализации проекта.

=

Определённая проблема, конечно, что бесконечное вычёрпывание воды из тонущего проекта со стороны смотрится солидно: люди в мыле что-то там постоянно пишут, вкалывают круглосуточно... Начальники такую рабочую суету обычно одобряют, а вот когда сеньор тихо и в одиночку хорошо спроектировал и запилил по нормальному ТЗ крупную систему, которая сразу норм заработала, это к сожалению обычно даже и близко не оценивается так, как того заслуживает.

Я встречал например ситуации, когда одни ребята, регулярно деплоившие баги в прод, получали премии, т.к. выходили на их правки в выходные, по ночам откликались и т.п., а другие, делавшие реально сложную работу качественно и достаточно быстро в основное рабочее время, в итоге удостаивались от начальника трёх букв :) "спс"

59 0 ER 2.2819
Почему существует такой огромный дефицит инженеров-программистов, ведь программированию учат практически везде, и множество бесплатных учебников и курсов, и зарплаты в ИТ очень хорошие? Вот почему:

- Вы учитесь в школе, и уроки по информатике пробуждают ваше любопытство.

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

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

- Вы заканчиваете университет, или колледж, или хорошие курсы в конце концов, и после этого (а нередко, уже на старших курсах) устраиваетесь на работу — причем я имею в виду настоящую работу, а не стажировку, — и начинаете зарабатывать относительно приличные деньги.

- Работа начинает постепенно вас выматывать, и вы со временем выгораете и разочаровываетесь в ИТ.

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

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

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

Страсть — вот ключевое!!!11 💥💥💥💥💥

Лучшие инженеры-программисты — это те, с кем в их компании обращаются как с дерьмом (ну ок, или даже очень хорошо обращаются, :) неважно) — но они возвращаются домой и независимо ни от чего продолжают программировать и программировать и программировать и постоянно развиваться в ИТ. Будь это чтение книг, прохождение курсов, создание сайд-проектов, практика в новых языках и фреймворках.

=

Я могу кстати сказать на 90%, кто из занимающихся у меня потенциально вполне может стать мировым топом с космической зарплатой (и таким буду максимально помогать), а кто так и будет мучиться в айти в унылой конторе (это например те, кто тянет сдачу заданий до последнего дня, словно это надо мне, а не им :). В этой связи готовлю постепенно эпический патч и ряд улучшений по схеме обучения, чтобы повысить ваш КПД в разы :)

=

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

49 0 ER 2.2349
Весьма распространенный проблемный режим для джуниоров: тебе дают некоторую часть системы и вперёд — надо её реализовать. Но при этом те части, которые уже имеются и которые тебе приходится использовать, на самом деле не поддерживают то, что тебе надо. Поэтому джуниорам приходится создавать множество костылей и приляпок к кривым API миддлов и сеньоров, а их (джунов) потом ещё и обвиняют, что они какую-то фигню понаделали.

Например, API выдаёт данные в виде строк, которые потом ещё надо аккуратно парсить. И джун такой следует дурному примеру, и начинает делать всё своё тоже в формате строк. По-хорошему же, тут надо пойти к тому, кто создал этот API, и сказать ему, что это глупо, и заставить его сделать нормально.

=

То есть работа явно зашкварная, когда джуниоры вязнут в рутине и рассуждают так: "вот API, которые мне доступны, вот библиотеки, которые мне дали, и я просто буду делать вещи так, как это делают они, и буду просто реализовывать мою задачу, даже если это очень неудобно".

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

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

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

=

А что такое "чтобы код был чище"? Вообще, качество кода — это не сам код. Ясный код — это лишь следствие качественной модели, которая существует в уме разработчика, в документации, но никак не в самом коде.

И когда мы переходим на мета-уровень по отношению к коду, то оказывается, что такие популярные вещи, как принцип DRY — это очень поверхностные метрики сложности кода. И это легко заводит вас на тупиковый путь "рефакторинга", который не меняет логику программы, но, кажется, делает код короче и "яснее". Однако на практике получается почти всегда так, что мы берём много вещей, которые раньше были в коде явными, и делаем их неявными, и получается совсем ужос-ужос.

=

Я встречал такие примеры на практике, причём отнюдь не только на уровне кода, но и на уровне архитектуры. Например, у ребят в каком-то проекте автоматизации была полусамодельная база данных на основе BerkeleyDB (btree, в исходниках), где они программно генерировали схему, программно генерировали типовые запросы к ней, был свой код, управлявший доступом, и ещё много чего своего; работало это всё невероятно быстро, но требовало некоторого ручного сопровождения и развития. И вот когда стали набирать популярность NoSQL, кто-то из "молодых менеджеров-технократов" предложил перейти на "готовую СУБД", которая вроде бы хорошо подходила под их задачки. Теперь у тебя есть эта готовая штука, и ты просто кладёшь разные сущности в гигантскую хэш-таблицу через простой API, и всё, и теперь у нас куда меньше технического долга, и вот это и вот то теперь куда проще, и бла бла бла бла бла.

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

Ты просто взял всё своё знание о системе, и выбросил его.
Благодаря такому очень поверхностному подходу, код стал проще.
Но логика не изменилась.

65 0 ER 1.6841
О важности алгоритмов и структур данных (АСД) написаны гигабайты текста, и вроде бы аргументы приводятся весомые... Однако все они разбиваются о железобетонное возражение "десятки лет пишу код, и ни разу они не пригодились" — и очень часто это действительно так.
(Готовил этот пост для группы начинающих программистов, но потом решил тут выложить.)

Поэтому, когда призываю к изучению АСД, на самом деле конечно имею в виду следующее:

Вам нужно уметь очень уверено решать самые разные программистские "проблемы" (рабочие задачи, тикеты, issues...). Пресловутый универсальный problem solving.

Но надо ли запоминать именно АСД до такой степени, чтобы "от зубов отскакивало" — чтобы вы умели реализовывать многие популярные алгоритмы фломастером на доске по памяти?

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

И что ещё более важно, АСД — великолепная практика для начинающих программистов, которым надо развиваться через решение задач растущей сложности, и тут удаётся сразу трёх зайцев поймать:
— задачки достаточно сложные порешать, попрактиковаться в уровне сложности, который постоянно будет на работе,
— изучить тему АСД для будущих собеседований,
— главное, получить хотя бы минимальное представление, как совместить два предыдущих пункта в одно целое.

=

Вот что имею в виду.

Допустим, есть большое множество точек в пространстве.

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

Теперь у вас может быть несколько ответов на этот вопрос.

1. Опустить руки, не понимая, а с чего вообще начать и как к этому подступиться, и заплакать.

2. Тупо посчитать расстояния между каждой точкой множества и заданной, затем отсортировать список этих расстояний по возрастанию, и взять первые N точек.

3. Правильнее всего конечно, надо просто понять, что эта проблема на 99.9% уже была решена в computer science, с чем вы уже частично познакомились, изучая базовые АСД, и теперь просто найти её "название" (в данном случае это т.н. задача поиска ближайшего соседа/k ближайших соседей).

4. Далее вы гуглите тему более подробно, изучаете конкретные версии решений (на уровне википедии вполне достаточно), и выбираете наиболее подходящий алгоритм под ваш случай. Cкорее всего вы найдёте десятки разных алгоритмов для решения подобной проблемы.

5. Ищете стандартные библиотеки или какой-то эталонный код (можно и самому закодировать, но лучше не надо), и также, возможно, находите сравнительный анализ библиотек, реализующих алгоритмы поиска ближайших соседей.

6. Не исключено, что из материала с таким анализом вы доберётесь до HNSW (Hierarchical Navigable Small World graphs) — этот алгоритм считается сегодня самым быстрым практическим алгоритмом для множеств из нескольких тысяч точек.

Что и подводит нас к основному моменту этого поста:

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

Ещё и потому, что "лучший" алгоритм для решения некоторой популярной проблемы сегодня не обязательно тот же, что и вчера — алгоритмы постоянно развиваются, HNSW был придуман относительно недавно.

Но такой навык мета-распознавания, конечно, будет работать на хорошем базовом фундаменте, когда вы имеете какое-то практическое представление об основных АСД.

=

Вот второй пример.

Хорошее учебное задание — найти подстроку в другой строке (вроде бы совсем просто, однако и миддлы иногда допускают мелкие ошибки).

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

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

Начинающие обычно просто пишут два вложенных цикла, которые перебирают строки символ за символом.

Возможно, если вы изучали информатику в университете, то узнали, что "самым быстрым" алгоритмом поиска подстроки считается Бойер-Мур.

Штош.

Не бывает самого быстрого алгоритма.

Возможно, если бы вы поисследовали тему подетальнее, то добрались бы до Турбо-Бойер-Мура :) Или до Apostolico-Giancarlo. Оба этих алгоритма имеют превосходные показатели и О-большого и о-маленького по сравнению с классическим алгоритмом Бойера-Мура.

И никто из ваших великолепных друзей-программистов даже не знает, что эти алгоритмы существуют!

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

=

В целом, стратегически, тоже важно понимать, что 99,9% проблем даже в Programming in Large достаточно давно были изучены, и были предложены хорошие решения как минимум в академической области, и прежде чем бросаться выдумывать велосипед, всегда лучше поискать что-то похожее готовое. Только конечно надо чётко различать исследовательский подход с тупой копипастой с stackoverflow.

=

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

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

Конечно, если ваша работа — обычные задачи вроде интернет-магазина, то коробка стандартных алгоритмов, поставляемая вместе с языком программирования или веб-фреймворком, может быть совершенно адекватной для повседневной работы.

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

А научная литература, по определению — это то, что вы не можете знать "на память", и это то, что вы не можете написать фломастером во время собеседования.

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

52 0 ER 1.5333