people
July 13, 2023

Разница поколений в ИТ

Давно хотел собрать в один пост ключевые отличия между разными поколениями айтишников. Речь пойдет в основном про разработчиков и чуть-чуть про админов и DevOps.

Вводная

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

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

В ВУЗах и на курсах такой дисциплине как «программирование» не учили.

Еще в те времена не было разделения на админов и разработчиков — всех кто имел отношение к компьютерам называли «программистами».

Начнем с самого бесящего.

«Онлайн-оффлайн»

Больше характерно для пользователей, но захватило еще и существенную часть веб-разработчиков и всяких «рядом стоящих» QA/DevOps, особенно любителей продукции Apple.

Суть явления заключается в том что человек перестает различать состояние «сна», физического выключения устройства и его нормальной работы с подключением к сети.

Для таких товарищей все это техническое разнообразие свелось до двух терминов: «онлайн» — все подключено и могу работать и «оффлайн» — все остальные варианты.

Причины банальны:

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

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

Получается такой чисто прикладной подход к устройству и его начинке (вплоть до ОС), аккуратно насаждаемый Apple и плавно распространившийся и на Windows а ныне влияющий еще и на популярные Линуксы.

Сетевой стек

Что такое IP-адрес знают даже самые тупые и зеленые из айтишников, но например что такое широковещательный адрес, маска подсети и как ее рассчитать — ныне знают единицы даже из сисадминов.

Даже бл#ть среди цисководов!

Нет это не шутка юмора а печальная реальность.

Хотя эти знания жизненно необходимы любому разработчику занятому в разработке сетевого ПО.

Хозяюшке рекрутеру на заметку:

Вопросом про localhost и 127.0.0.1 можно спокойно валить на собеседованиях даже опытных специалистов

Никто из айтишной молодежи почему-то не в курсе что «loopback» это не один только 127.0.0.1, а целая подсеть:

127.0.0.0/8 - This block is assigned for use as the Internet host
loopback address. A datagram sent by a higher level protocol to an
address anywhere within this block should loop back inside the host.
This is ordinarily implemented using only 127.0.0.1/32 for loopback,
but no addresses within this block should ever appear on any network
anywhere [RFC1700, page 5].

Поэтому в любых ОС возможно использовать в качестве локального адреса например 127.6.6.6 — настроить в вашем любимом Spring Boot прослушивание сокета на одном этом адресе и только он один будет отвечать в браузере.

UDP

Вторым важным пробелом является практически полное отсутствие знаний о протоколе UDP.

Максимум — на уровне теории, что оно вообще существует, в стиле статьи из википедии:

Двумя основными протоколами транспортного уровня являются надежный протокол управления передачей данных TCP (Transmission Control Protocol) и быстрый протокол дэйтаграмм пользователя UDP (User Datagram Protocol). TCP реализует сетевое взаимодействие в режиме с установлением логического (виртуального) соединения, а UDP - без оного.

Причем чаще всего UDP на лекциях описывают как «ненадежный», а TCP — «надежный», без малейшего понимания в чем эта надежность заключается.

Отсюда же происходит смутное представление о DNS и механизме разрешения имен, помимо боязни связываться с «ненадежным» протоколом уже в разработке.

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

Например тот же Skype когда-то создавался и работал как раз на UDP. И работал он хорошо.

Все остальное

ICMP, RIP, OSPRF, VLAN — остались только во влажных мечтах рекрутеров и в моем старом резюме.

Даже аббревиатуры эти уже ничего никому не говорят, поэтому если вы знаете хотя-бы что такое ICMP — вы уже чуточку лучше типичного соискателя.

Поздравляю.

"Typical MacOS Developer", из палаты мер и весов.

Веб vs натив vs мобайл

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

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

Когда-то все было очень просто:

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

В настоящее время, разобраться в той же технологии PWA ( Progressive Web Application) многократно тяжелее чем ее использовать.

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

Именно отсюда и растут те самые «требования» в вакансиях о владении какой-то определенной технологией Х лет.

Типы данных

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

Так оно когда-то и было, примерно во времена когда тип «строка» еще не существовал и использовались массивы символов.

Ныне во всех модных языках работает автоматический boxing-unboxing, приведение типов и кокантенация.

Так что дичь вроде:

System.out.println("obj="+ obj);

давно не вызывает никаких проблем ни у компилятора ни у рантайма ни у разработчика.

Так что владение типами данных ныне отсутствует как класс, поэтому не ждите ответа про разницу между double и float, например.

Ну и конечно знания о вещах вроде побитового сдвига остались в далеком прошлом:

 int bitmask = 0x000F;
 int val = 0x2222;
 // prints "2"
 System.out.println(val & bitmask);

В новых проектах за последние 10 лет не видел ни разу.

Многопоточность и асинхронность

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

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

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

Хороший пример такому подходу — проект Node.js, выкатывающий сборки и релизы чаще чем я обедаю.

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

Еще Node.js сильно популяризовал «асинхронное программирование» и его применение везде и для всего.

Поймите правильно:

асинхронное программирование это мощный инструмент, дающий прекрасный результат в опытных руках.

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

Если кто вдруг не знает: 

в Node.js нет синхронного программирования, все вызовы, все функции, все методы — все асинхронное.

Последовательное выполнение вызовов вроде:

callFunction1();
callFunction2();
callFunction3();

в Node.js невозможно без специальных костылей ухищрений.

Поэтому три вызова выше выполнятся не последовательно, один за другим а параллельно.

И с моей скромной точки зрения такие органичения это уже перебор.

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

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

Что вообщем-то и происходит в большинстве «молодежных» проектов.

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

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

Внезапно оказываются нужны блокировки, пул потоков, контроль выполнения и watchdog.

Если у разработчика не было подобного проекта — целый раздел знаний о внутреннем устройстве ПО является для него закрытым.

Вы же хотели увидеть "облачный сервер"?

Серверы, клиенты и облака

Опять же, раньше все было куда проще и очевидней:

есть клиент — он отправляет запросы и получает данные, есть сервер — получает запросы и отдает данные

Под такое общее описание подходили и вебсерверы с браузерами и вызовы по API и сетевая работа с базами данных.

Исходя из такой простоты, были и простые правила проектирования:

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

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

Теперь вернемся в современные печальные реалии.

Во-первых у нас теперь есть SaaS, PaaS, IaaS и совсем уж запредельная дичь вроде Amazon Lambda и Servless.

Простых правил проектирования для всего этого зоопарка не существует.

Все эти замечательные вещи — экосистемы, еще и со спецификой у каждого конкретного вендора.

А значит, то что будет создавать проблемы в AWS — будет замечательно работать на каком-нибудь GAE.

Теперь представьте себя на месте молодого разработчика, только-только научившегося ваять «облачный код» под Amazon Lambda — много он сможет сделать вне этой штуки и экосистемы Amazon вообще?

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

Абсолютно все точки взаимодействия с окружающим миром происходят через API платформы:

package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;

// Handler value: example.HandlerInteger
public class HandlerIntegerJava17 implements RequestHandler<IntegerRecord, Integer>{  @Override
  /*
   * Takes in an InputRecord, which contains two integers and a String.
   * Logs the String, then returns the sum of the two Integers.
   */
  public Integer handleRequest(IntegerRecord event, Context context)
  {
    LambdaLogger logger = context.getLogger();
    logger.log("String found: " + event.message());
    return event.x() + event.y();
  }
}
record IntegerRecord(int x, int y, String message) {
}

Между прочим это официальный пример «программы» для Amazon Lambda. Сильно похоже на ваш обычный серверный код?

Современные реалии принесли современные же проблемы — путаницу в технических терминах и очевидное отсутствие глубины понимания всего.

Когда-то мне нравилось задавать спорные вопросы на собеседованиях разработчиков, вроде:

«расскажите чем облачный сервер отличается от обычного»

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

Но больше я подобные вопросы не задаю — нынешнее поколение разработчиков вообще не знает что такое «обычный сервер», они его просто никогда не видели вживую.

Зато конечно легко рассуждают о «бесконечном масштабировании» и бесперебойной работе.

Итого

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

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

Научный базис под этими технологиями — на десятилетия упорного труда.

Так что если вы планировали залететь в эту область с ходу — результат вас сильно разочарует.

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

Что касается более ширпотребных технологий вроде обычной веб-разработки — сейчас как никогда стоит тратить определенный процент времени на получение именно базовых знаний: сети, устройство ОС, SICP — вот это все.

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

«Расслабься и не парься»

Чтобы вы не выходили за границы решения и вообще не мыслили себе разработку чего-либо без этого конкретного фреймворка.

Думаю не стоит говорить, что такого в годы моей компьютерной юности не было, вернее оно было — но «там», не тут.

Тут, на окраине мира, мы росли сами, все изучали сами, без курсов и этих ваших «коучев»

И получилось вообщем-то неплохо.