Чем дальше прохожу «Computer Science во Frontend», тем чаще оказывается, что привычные вещи устроены совсем не так просто, как кажутся сверху. Массив уже оказался не совсем массивом, теперь добрался до RxJS и устройства памяти процесса. В обоих случаях примерно одна история: пока работаешь через удобную абстракцию — всё понятно, а стоит заглянуть внутрь, начинается самое интересное.
Начал проходить миникурс по RxJS https://rxjs-course-avy.web.app/. В React основной подход довольно понятный: изменилось состояние → компонент перерендерился, а асинхронность обычно закрывается через
Многие данные во frontend — это вообще не одно значение, а поток значений во времени: ввод пользователя, HTTP-запросы, события роутера, WebSocket, таймеры.
По собственному опыту особенно хорошо смысл потоков становится понятен, когда появляется два-три зависимых асинхронных запроса, а предыдущие ещё надо уметь отменять. Можно собрать это на
Параллельно в курсе «Computer Science во Frontend» дошёл до сегментов памяти программы. Со школы помню классическую картинку: есть код программы, данные, куча растёт вверх, стек растёт вниз — всё просто и понятно. И это даже не то чтобы неправильно. Просто реальная память процесса, как обычно, решила не ограничиваться школьной схемой и добавить немного подробностей.
Память процесса представляет собой набор областей виртуального адресного пространства. Есть сегмент кода
Ещё выше в классической схеме находится
Ещё со школы помню страшилку: «Не кладите, дети, много данных в стек — переполнится и всё сломается». И здесь тоже всё немного интереснее: в стеке лежат далеко не только восьмибайтовые указатели, а целые стековые кадры функций, локальные значения и служебные данные. Поэтому условные 8 МБ стека выглядят огромными ровно до момента, пока не появляется глубокая рекурсия или большой локальный массив.
В общем, очередная тема из серии «вроде всё знал, пока не начал разбираться». С RxJS оказывается, что асинхронность удобнее воспринимать не как набор отдельных операций, а как поток событий. С памятью — что привычные стек и куча являются только частью гораздо более сложной картины. Похоже, весь Computer Science примерно так и устроен: сначала тебе дают простую модель, а потом постепенно объясняют, сколько всего она от тебя скрывала.
Начал проходить миникурс по RxJS https://rxjs-course-avy.web.app/. В React основной подход довольно понятный: изменилось состояние → компонент перерендерился, а асинхронность обычно закрывается через
Promise, async/await, useEffect, TanStack Query или внешний state-менеджер. В Angular потоки встроены в экосистему гораздо глубже, поэтому здесь приходится немного перестраивать привычный способ мышления.Многие данные во frontend — это вообще не одно значение, а поток значений во времени: ввод пользователя, HTTP-запросы, события роутера, WebSocket, таймеры.
Observable позволяет такие потоки объединять, фильтровать и преобразовывать через map, switchMap, combineLatest, debounceTime и другие операторы. Современный Angular при этом разделяет задачи: Signals удобны для состояния UI, а RxJS остаётся сильным инструментом для сложной асинхронности.По собственному опыту особенно хорошо смысл потоков становится понятен, когда появляется два-три зависимых асинхронных запроса, а предыдущие ещё надо уметь отменять. Можно собрать это на
Promise и async/await, но довольно быстро начинается ручное управление состояниями, отменами и гонками. С потоками такая логика иногда получается заметно чище, хотя первое время на RxJS смотришь примерно как на отдельный язык программирования внутри TypeScript.Параллельно в курсе «Computer Science во Frontend» дошёл до сегментов памяти программы. Со школы помню классическую картинку: есть код программы, данные, куча растёт вверх, стек растёт вниз — всё просто и понятно. И это даже не то чтобы неправильно. Просто реальная память процесса, как обычно, решила не ограничиваться школьной схемой и добавить немного подробностей.
Память процесса представляет собой набор областей виртуального адресного пространства. Есть сегмент кода
text с машинными инструкциями, .data для инициализированных глобальных и статических переменных, .bss для неинициализированных, а дальше располагается heap для динамической памяти. Отдельно существует область mmap, куда могут отображаться файлы, анонимная память и динамические библиотеки вроде libc.so.Ещё выше в классической схеме находится
stack: там живут данные вызовов функций, локальные значения, адреса возврата и служебная информация. Стек обычно растёт в сторону уменьшения адресов, а расположение самих областей может меняться при каждом запуске из-за ASLR (Address Space Layout Randomization — рандомизации размещения адресного пространства). Поэтому память процесса — это не один большой непрерывный кусок RAM, а организованное виртуальное пространство, которое операционная система отображает на реальную память по мере необходимости.Ещё со школы помню страшилку: «Не кладите, дети, много данных в стек — переполнится и всё сломается». И здесь тоже всё немного интереснее: в стеке лежат далеко не только восьмибайтовые указатели, а целые стековые кадры функций, локальные значения и служебные данные. Поэтому условные 8 МБ стека выглядят огромными ровно до момента, пока не появляется глубокая рекурсия или большой локальный массив.
В общем, очередная тема из серии «вроде всё знал, пока не начал разбираться». С RxJS оказывается, что асинхронность удобнее воспринимать не как набор отдельных операций, а как поток событий. С памятью — что привычные стек и куча являются только частью гораздо более сложной картины. Похоже, весь Computer Science примерно так и устроен: сначала тебе дают простую модель, а потом постепенно объясняют, сколько всего она от тебя скрывала.
RxJS Ninja
RxJS Ninja — интерактивный курс RxJS: уроки, практика, справочник операторов
Бесплатный интерактивный курс RxJS на русском: уроки, практика, справочник операторов (of, from, map, switchMap, mergeMap, catchError) и real-world use cases.…
👍4
Продолжаю смотреть курс «Computer Science во Frontend». Дошёл до многопоточности. Ну какая многопоточность в JavaScript? Это не про нас. JavaScript однопоточный. Многопоточность — это где-то там, в больших и мощных Java и Go. Но, как обычно, есть нюансы. Причём сразу два: есть Web Workers, которые предоставляет окружение, и есть асинхронность, которой тоже нужно как-то грамотно управлять.
Посмотрел на пример с Web Worker, где автор создаёт два потока, — без слёз на этот код не посмотреть. Worker выполняет отдельный JS-файл, а если хочется собрать всё динамически, начинаются развлечения: функцию превращаем в строку, оборачиваем в
А вот управление асинхронностью оказалось намного интереснее. Мне понравилась структура со страшным названием «асинхронный семафор (барьер)». Идея очень простая: есть несколько независимых операций, и продолжить работу можно только после завершения всех. Например, при запуске проекта нужно подключиться к базе данных, прочитать YAML-конфиг и поднять Redis. Только когда готовы все три компонента, выполняем callback. (см. рисунок)
В примере есть три флага.
У меня когда-то была аналогичная задача на фронте: выполнить код только после того, как всё загрузилось и инициализировалось. Проект был древний и страшный, а я помню, как извращался с Redux. Решение в итоге собрал из говна и палок. Сейчас смотрю на барьер и думаю: вот же оно. Иногда полезно изучить название конструкции, которую ты когда-то самостоятельно изобрёл в гораздо более страшном виде.
Заодно посмотрел блок по функциональному программированию. Раньше все эти функторы, монады и каррирование выглядели как тайное знание бородатых программистов на Haskell. А потом выясняется, что половиной этих идей мы спокойно пользуемся в обычном JavaScript. Функции высшего порядка принимают и возвращают функции, замыкания сохраняют окружение, каррирование разбивает функцию на цепочку вызовов, а композиция позволяет собирать сложное поведение из простых функций.
Даже привычные
И вот тут я наконец понял основную идею функционального программирования. Значение помещается в некоторый контекст, а функции последовательно преобразуют его, стараясь не вытаскивать наружу и не мутировать состояние вручную. Звучит просто ровно до того момента, пока не узнаешь, что называется страшным словом «монада». Но без десятка нормальных примеров понять это почти невозможно. Но когда начинаешь видеть знакомые
Так что вывод получился забавный. В JavaScript вроде бы нет привычной многопоточности, а функциональное программирование кажется чем-то академическим и далёким. Но начинаешь копать — и выясняется, что асинхронные барьеры, функторы и монады уже давно находятся рядом. Просто раньше я пользовался частью этих идей, не зная, как они называются.
Посмотрел на пример с Web Worker, где автор создаёт два потока, — без слёз на этот код не посмотреть. Worker выполняет отдельный JS-файл, а если хочется собрать всё динамически, начинаются развлечения: функцию превращаем в строку, оборачиваем в
Blob, создаём URL и только потом отдаём Worker. Извращение ещё то. Поэтому если мне действительно понадобится удобная многопоточность, я лучше возьму Go. В JavaScript это инструмент скорее для отдельных специфических задач, чем повседневная модель программирования.А вот управление асинхронностью оказалось намного интереснее. Мне понравилась структура со страшным названием «асинхронный семафор (барьер)». Идея очень простая: есть несколько независимых операций, и продолжить работу можно только после завершения всех. Например, при запуске проекта нужно подключиться к базе данных, прочитать YAML-конфиг и поднять Redis. Только когда готовы все три компонента, выполняем callback. (см. рисунок)
В примере есть три флага.
expectedFlags хранит полный набор условий, а readyFlags — уже выполненные. Каждый участник после завершения работы «поднимает» свой флаг, а барьер проверяет, собрались ли все. Set здесь особенно удобен: повторный barrier.set('database') ничего не сломает и не увеличит счётчик, потому что одинаковые значения в Set не дублируются. Просто и достаточно элегантно.У меня когда-то была аналогичная задача на фронте: выполнить код только после того, как всё загрузилось и инициализировалось. Проект был древний и страшный, а я помню, как извращался с Redux. Решение в итоге собрал из говна и палок. Сейчас смотрю на барьер и думаю: вот же оно. Иногда полезно изучить название конструкции, которую ты когда-то самостоятельно изобрёл в гораздо более страшном виде.
Заодно посмотрел блок по функциональному программированию. Раньше все эти функторы, монады и каррирование выглядели как тайное знание бородатых программистов на Haskell. А потом выясняется, что половиной этих идей мы спокойно пользуемся в обычном JavaScript. Функции высшего порядка принимают и возвращают функции, замыкания сохраняют окружение, каррирование разбивает функцию на цепочку вызовов, а композиция позволяет собирать сложное поведение из простых функций.
Даже привычные
Array и Promise можно рассматривать с этой точки зрения. Array через map ведёт себя как функтор, а через flatMap — как монадическая структура: значение находится в контексте «много значений». Promise — это контекст «значение появится позже», а then позволяет преобразовывать его, не вытаскивая из этого контекста вручную. Maybe/Optional описывает другой контекст — «значение может быть, а может и не быть»; в обычном JS отдалённо похожие задачи решают ?. и ??.И вот тут я наконец понял основную идею функционального программирования. Значение помещается в некоторый контекст, а функции последовательно преобразуют его, стараясь не вытаскивать наружу и не мутировать состояние вручную. Звучит просто ровно до того момента, пока не узнаешь, что называется страшным словом «монада». Но без десятка нормальных примеров понять это почти невозможно. Но когда начинаешь видеть знакомые
Array, map, flatMap и Promise, вся эта страшная теория внезапно становится намного ближе к обычному JavaScript.Так что вывод получился забавный. В JavaScript вроде бы нет привычной многопоточности, а функциональное программирование кажется чем-то академическим и далёким. Но начинаешь копать — и выясняется, что асинхронные барьеры, функторы и монады уже давно находятся рядом. Просто раньше я пользовался частью этих идей, не зная, как они называются.
👍3
Функциональное программирование меня неожиданно увлекло. Особенно рекурсия, которую я считал довольно простой конструкцией: функция вызывает саму себя, и всё. Оказалось, что существует как минимум пять её разновидностей, некоторые весьма замысловатые. А началось всё с бумажной книги, которую я купил давным-давно. Заодно вспомнил интересную методику чтения, позволяющую не тратить десятки часов на книги.
В чистом функциональном программировании нет привычных циклов
Линейная — один рекурсивный вызов, например факториал:
Хвостовая — рекурсивный вызов выполняется последним:
Множественная — несколько вызовов, например Фибоначчи:
Взаимная — функции вызывают друг друга:
Вложенная — результат одного вызова передаётся другому:
Все типы рекурсии я привёл на картинке. Особенно понравился алгоритм Маккарти 91. Выглядит как математическая магия: функция вызывает саму себя внутри собственного вызова, но результат вполне предсказуемый. Казалось бы, знакомая конструкция, а сколько интересного обнаруживается, если копнуть глубже.
Но вернёмся к книге. Она бумажная, а читать техническую литературу от корки до корки — удовольствие сомнительное, особенно когда половина материала уже знакома. Вспомнил методику Андрея Парабеллума из книги «Быстрые результаты. 10-дневная программа повышения личной эффективности». Идея простая: в большинстве книг Non-fiction информация повторяется, а основные мысли зачастую можно уместить в одну статью.
Методика основана на трёх проходах:
Первый (1–3 минуты) — просматриваем оглавление, заголовки и выводы. Решаем, стоит ли читать книгу.
Второй (15 минут) — выборочно читаем интересные главы, ищем ключевые идеи.
Третий (без ограничения времени) — углублённо изучаем самое ценное, делаем заметки и пропускаем второстепенное.
По собственному опыту до третьего прохода доживает ну очень небольшое количество книг. И это нормально. Зачем тратить десять часов, если полезные мысли можно извлечь за двадцать минут? Конечно, сложная техническая литература — исключение, там без практики не обойтись. Ещё полезно оценивать прочитанное по десятибалльной шкале и выносить из книги 1–3 идеи для применения.
В итоге с книгами получается примерно то же самое, что и с программированием: 20% теории и 80% практики. Можно прочитать десять книг по рекурсии, но пока сам не напишешь несколько алгоритмов, толку будет немного. Главное не сколько книг прочитал, а что научился делать после их прочтения.
В чистом функциональном программировании нет привычных циклов
for и while. Вместо них используют рекурсию и функции высшего порядка вроде map, filter и reduce. Вспомнил, что давно купил книгу Мануэля Рубио-Санчеса «Введение в рекурсивное программирование». Решил наконец до неё добраться и выяснил, что существует пять основных типов рекурсии:Линейная — один рекурсивный вызов, например факториал:
n * factorial(n - 1).Хвостовая — рекурсивный вызов выполняется последним:
return factorial(n - 1, n * acc). Допускает оптимизацию стека, но в JavaScript она не гарантирована.Множественная — несколько вызовов, например Фибоначчи:
fibonacci(n - 1) + fibonacci(n - 2).Взаимная — функции вызывают друг друга:
isEven() и isOdd().Вложенная — результат одного вызова передаётся другому:
f(f(n - 1)). Классический пример — алгоритм Маккарти 91, который для чисел ≤ 100 возвращает 91, а для чисел > 100 — число минус 10.Все типы рекурсии я привёл на картинке. Особенно понравился алгоритм Маккарти 91. Выглядит как математическая магия: функция вызывает саму себя внутри собственного вызова, но результат вполне предсказуемый. Казалось бы, знакомая конструкция, а сколько интересного обнаруживается, если копнуть глубже.
Но вернёмся к книге. Она бумажная, а читать техническую литературу от корки до корки — удовольствие сомнительное, особенно когда половина материала уже знакома. Вспомнил методику Андрея Парабеллума из книги «Быстрые результаты. 10-дневная программа повышения личной эффективности». Идея простая: в большинстве книг Non-fiction информация повторяется, а основные мысли зачастую можно уместить в одну статью.
Методика основана на трёх проходах:
Первый (1–3 минуты) — просматриваем оглавление, заголовки и выводы. Решаем, стоит ли читать книгу.
Второй (15 минут) — выборочно читаем интересные главы, ищем ключевые идеи.
Третий (без ограничения времени) — углублённо изучаем самое ценное, делаем заметки и пропускаем второстепенное.
По собственному опыту до третьего прохода доживает ну очень небольшое количество книг. И это нормально. Зачем тратить десять часов, если полезные мысли можно извлечь за двадцать минут? Конечно, сложная техническая литература — исключение, там без практики не обойтись. Ещё полезно оценивать прочитанное по десятибалльной шкале и выносить из книги 1–3 идеи для применения.
В итоге с книгами получается примерно то же самое, что и с программированием: 20% теории и 80% практики. Можно прочитать десять книг по рекурсии, но пока сам не напишешь несколько алгоритмов, толку будет немного. Главное не сколько книг прочитал, а что научился делать после их прочтения.
👍1
Недавно ко мне обратился знакомый программист и рассказал, что есть ненулевой шанс попасть под сокращение. Я вспомнил, что меня самого увольняли раза три-четыре, так что определённый опыт накопился. Сразу оговорюсь: это мой личный опыт, а не универсальная инструкция для всего IT.
Как только в компании начинаются разговоры про оптимизацию, повышение эффективности бизнеса и сложную экономическую ситуацию, я бы задумался. Насколько проект, над которым я работаю, критичен для бизнеса? Некритичный проект могут просто закрыть, а на критичном оставить двух-трёх человек для поддержки. Причём уволить могут довольно быстро, иногда за пару недель.
Первое — финансовая подушка. Я бы начал откладывать деньги, чтобы накопить хотя бы 3–6 месячных окладов. Меня несколько раз увольняли в самые «удачные» периоды: декабрь-январь или летом. В первом случае все на праздниках, во втором — в отпусках. Деньги нужны не только для оплаты коммуналки и питания, но и чтобы не бросаться на первый попавшийся оффер.
Второе — алгоритмы. Причём не видео «Все алгоритмы за два часа», а полноценный курс по решению задач с LeetCode. На собеседовании могут дать две-три задачи по двадцать минут, и это скорее математические головоломки, чем реальное программирование. Я бы не советовал часами биться над каждой задачей самостоятельно. Лучше разобрать существующее решение, воспроизвести его без подсказок и закрепить на похожих задачах. В идеале — 200–300 задач и около полугода подготовки. Рекомендую курс «Подготовка к алгоритмическому собеседованию в BigTech». Самое обидное, что в реальной работе большинство этих трюков практически не используется.
Третье — резюме и собеседования. Сейчас HR активно используют ИИ, поэтому резюме стоит оптимизировать под ключевые слова вакансий, но главное — показать результаты своей работы, а не просто перечислить технологии. Ещё рекомендую посмотреть записи технических собеседований на YouTube и пройти хотя бы одно пробное. На повторение теории вроде асинхронности JS, сборки мусора и работы браузера я бы выделил одну-две недели. Алгоритмы потребуют гораздо больше времени.
Четвёртое — поиск работы. Это отдельная работа, которой я уделял по 4–6 часов в день. Адаптировать резюме, написать сопроводительное письмо, пообщаться с HR, пройти собеседование, подтянуть обнаруженные пробелы в знаниях. Больше всего выматывает ощущение чёрной дыры: отправляешь резюме, выполняешь задания, тратишь время, а в ответ — ни привета, ни ответа. И ещё одно наблюдение: чем меньше контора, тем больше она иногда мнит себя Google. В условном ООО «Ромашка» легко встретить пять-семь этапов отбора с топологической сортировкой и обходом графов.
Пятое — запасной вариант. Сейчас, по моим наблюдениям, рынок работодателя: кандидатов много, хороших вакансий мало. Если после трёх-четырёх месяцев активного поиска по-прежнему глухо как в танке, я бы посмотрел в сторону смежной специальности. Пусть зарплата ниже, зато устроиться проще. У меня такой запасной вариант — системное администрирование. Не предел мечтаний, но когда заканчиваются деньги, романтика быстро испаряется.
В общем, поиск работы — это отдельный навык, который практически не связан с умением писать хороший код. Одно дело — выйти на рынок подготовленным, с финансовой подушкой, обновлённым резюме и прорешанными алгоритмами. И совсем другое — после увольнения судорожно бегать, тушить пожары и соглашаться на первый попавшийся оффер.
Поэтому готовиться к увольнению лучше, пока тебя ещё не уволили.
Как только в компании начинаются разговоры про оптимизацию, повышение эффективности бизнеса и сложную экономическую ситуацию, я бы задумался. Насколько проект, над которым я работаю, критичен для бизнеса? Некритичный проект могут просто закрыть, а на критичном оставить двух-трёх человек для поддержки. Причём уволить могут довольно быстро, иногда за пару недель.
Первое — финансовая подушка. Я бы начал откладывать деньги, чтобы накопить хотя бы 3–6 месячных окладов. Меня несколько раз увольняли в самые «удачные» периоды: декабрь-январь или летом. В первом случае все на праздниках, во втором — в отпусках. Деньги нужны не только для оплаты коммуналки и питания, но и чтобы не бросаться на первый попавшийся оффер.
Второе — алгоритмы. Причём не видео «Все алгоритмы за два часа», а полноценный курс по решению задач с LeetCode. На собеседовании могут дать две-три задачи по двадцать минут, и это скорее математические головоломки, чем реальное программирование. Я бы не советовал часами биться над каждой задачей самостоятельно. Лучше разобрать существующее решение, воспроизвести его без подсказок и закрепить на похожих задачах. В идеале — 200–300 задач и около полугода подготовки. Рекомендую курс «Подготовка к алгоритмическому собеседованию в BigTech». Самое обидное, что в реальной работе большинство этих трюков практически не используется.
Третье — резюме и собеседования. Сейчас HR активно используют ИИ, поэтому резюме стоит оптимизировать под ключевые слова вакансий, но главное — показать результаты своей работы, а не просто перечислить технологии. Ещё рекомендую посмотреть записи технических собеседований на YouTube и пройти хотя бы одно пробное. На повторение теории вроде асинхронности JS, сборки мусора и работы браузера я бы выделил одну-две недели. Алгоритмы потребуют гораздо больше времени.
Четвёртое — поиск работы. Это отдельная работа, которой я уделял по 4–6 часов в день. Адаптировать резюме, написать сопроводительное письмо, пообщаться с HR, пройти собеседование, подтянуть обнаруженные пробелы в знаниях. Больше всего выматывает ощущение чёрной дыры: отправляешь резюме, выполняешь задания, тратишь время, а в ответ — ни привета, ни ответа. И ещё одно наблюдение: чем меньше контора, тем больше она иногда мнит себя Google. В условном ООО «Ромашка» легко встретить пять-семь этапов отбора с топологической сортировкой и обходом графов.
Пятое — запасной вариант. Сейчас, по моим наблюдениям, рынок работодателя: кандидатов много, хороших вакансий мало. Если после трёх-четырёх месяцев активного поиска по-прежнему глухо как в танке, я бы посмотрел в сторону смежной специальности. Пусть зарплата ниже, зато устроиться проще. У меня такой запасной вариант — системное администрирование. Не предел мечтаний, но когда заканчиваются деньги, романтика быстро испаряется.
В общем, поиск работы — это отдельный навык, который практически не связан с умением писать хороший код. Одно дело — выйти на рынок подготовленным, с финансовой подушкой, обновлённым резюме и прорешанными алгоритмами. И совсем другое — после увольнения судорожно бегать, тушить пожары и соглашаться на первый попавшийся оффер.
Поэтому готовиться к увольнению лучше, пока тебя ещё не уволили.
👍1
Решил на этой неделе сделать небольшую подборку новостей. Весёленькая выдалась неделя: критическая уязвимость PHP, эксперименты с ИИ-презентациями и конференция о будущем разработки. Причём некоторые новости заставляют задуматься, куда вообще движется наша профессия.
1. PHP2Shell — старый PHP не сдаётся
Начну с самой эпичной уязвимости PHP, про которую вы, скорее всего, уже слышали, — PHP2Shell. Пересказывать технические подробности не буду, по ссылке всё подробно и по-русски. На поддерживаемых версиях PHP ничего особенно страшного: обновился и живёшь дальше. Во все основные дистрибутивы экстренно привезли исправления. Казалось бы, проблема решена.
Но PHP — такая вещь, на которой работает куча старья, давно не обновляющегося и уже никогда не обновляемого. К сожалению, у меня такие серверы тоже есть. Обновить их невозможно, а тратить деньги на модернизацию никто не собирается. Например, на серверах с FreeBSD 13 пришлось собирать PHP из исходников. Вот такая современная информационная безопасность.
Заодно посмотрел, сколько у нас в компании сайтов на PHP. Оказалось, примерно 90%, а оставшиеся 10% — всякая экзотика вроде Java, Ruby и NodeJS. Так что PHP живее всех живых, сколько бы его ни хоронили. И, судя по количеству старых корпоративных систем, хоронить его будут ещё очень долго.
2. Как я делал презентацию при помощи ИИ
На этой неделе выступил с докладом «Нальчик и магия Кавказских гор» в Клубе путешественников Тюменского отделения Русского географического общества. Рассказывал о своём путешествии на Кавказ в мае этого года. Если кто пропустил, вот моя статья о поездке: https://vk.ru/@grebenyov-puteshestvie-v-kabardino-balkariu-stranu-chudes.
Но интересно даже не само выступление, а подготовка презентации. Я решил сделать её при помощи ИИ. Мой наивный подход «сделай красиво» быстро упёрся в проблему: ИИ действительно делает красиво, только каждый слайд в совершенно разном стиле. Один получился минималистичным, другой — с кучей декоративных элементов. А мне нужна была единая презентация, а не выставка художественных фантазий нейросети.
Нашёл хорошее видео «Как делать презентации уровня топовых агентств с помощью AI» https://www.youtube.com/watch?v=U2NpS_80mrw. Подход у автора классический — «зыринг и тыринг». Сначала находишь понравившийся дизайн, на его основе создаёшь дизайн-систему, а уже по ней генерируешь отдельные слайды. В результате все слайды получаются в одном стиле. Никакой магии, просто нормальная организация работы.
Кстати, если заметили, обложки для своих постов я теперь генерирую по тому же принципу. Сначала задаю единый визуальный стиль, а потом уже создаю конкретные картинки. Оказалось, что с ИИ всё работает примерно как с обычным дизайнером: если не объяснить, чего именно хочешь, получишь красиво, но совсем не то.
3. Как ИИ меняет разработку ПО
Третья новость. Побывал на офлайн-конференции «Как ИИ меняет разработку ПО». Вот запись конференции. Особенно понравились два доклада, причём совершенно разных: один про рынок труда, другой про автономных ИИ-агентов. Но оба, как оказалось, об одном — о том, как меняется сама профессия программиста.
Первый доклад — «Реальность рынка найма осенью 2026 года». Про трудоустройство в IT прямо сейчас. Скажем так, всё довольно грустно. По приведённым на докладе данным, полноценный поиск работы занимает около полугода, а на одну вакансию может приходиться 2000–3000 резюме. Конкуренция какая-то совершенно нездоровая. Особенно если вспомнить времена, когда программист мог выбирать между несколькими предложениями.
Меняется и сам спрос на специалистов. По словам докладчика, компаниям всё чаще нужны не отдельные фронтендеры или C#-разработчики, а ИИ-инженеры — по сути, фулстеки со знанием AI, способные самостоятельно решить задачу от начала до конца. Пока отдельно держатся бизнес-аналитики и дизайнеры. А вот узкая специализация, похоже, постепенно становится менее привлекательной для работодателей.
1. PHP2Shell — старый PHP не сдаётся
Начну с самой эпичной уязвимости PHP, про которую вы, скорее всего, уже слышали, — PHP2Shell. Пересказывать технические подробности не буду, по ссылке всё подробно и по-русски. На поддерживаемых версиях PHP ничего особенно страшного: обновился и живёшь дальше. Во все основные дистрибутивы экстренно привезли исправления. Казалось бы, проблема решена.
Но PHP — такая вещь, на которой работает куча старья, давно не обновляющегося и уже никогда не обновляемого. К сожалению, у меня такие серверы тоже есть. Обновить их невозможно, а тратить деньги на модернизацию никто не собирается. Например, на серверах с FreeBSD 13 пришлось собирать PHP из исходников. Вот такая современная информационная безопасность.
Заодно посмотрел, сколько у нас в компании сайтов на PHP. Оказалось, примерно 90%, а оставшиеся 10% — всякая экзотика вроде Java, Ruby и NodeJS. Так что PHP живее всех живых, сколько бы его ни хоронили. И, судя по количеству старых корпоративных систем, хоронить его будут ещё очень долго.
2. Как я делал презентацию при помощи ИИ
На этой неделе выступил с докладом «Нальчик и магия Кавказских гор» в Клубе путешественников Тюменского отделения Русского географического общества. Рассказывал о своём путешествии на Кавказ в мае этого года. Если кто пропустил, вот моя статья о поездке: https://vk.ru/@grebenyov-puteshestvie-v-kabardino-balkariu-stranu-chudes.
Но интересно даже не само выступление, а подготовка презентации. Я решил сделать её при помощи ИИ. Мой наивный подход «сделай красиво» быстро упёрся в проблему: ИИ действительно делает красиво, только каждый слайд в совершенно разном стиле. Один получился минималистичным, другой — с кучей декоративных элементов. А мне нужна была единая презентация, а не выставка художественных фантазий нейросети.
Нашёл хорошее видео «Как делать презентации уровня топовых агентств с помощью AI» https://www.youtube.com/watch?v=U2NpS_80mrw. Подход у автора классический — «зыринг и тыринг». Сначала находишь понравившийся дизайн, на его основе создаёшь дизайн-систему, а уже по ней генерируешь отдельные слайды. В результате все слайды получаются в одном стиле. Никакой магии, просто нормальная организация работы.
Кстати, если заметили, обложки для своих постов я теперь генерирую по тому же принципу. Сначала задаю единый визуальный стиль, а потом уже создаю конкретные картинки. Оказалось, что с ИИ всё работает примерно как с обычным дизайнером: если не объяснить, чего именно хочешь, получишь красиво, но совсем не то.
3. Как ИИ меняет разработку ПО
Третья новость. Побывал на офлайн-конференции «Как ИИ меняет разработку ПО». Вот запись конференции. Особенно понравились два доклада, причём совершенно разных: один про рынок труда, другой про автономных ИИ-агентов. Но оба, как оказалось, об одном — о том, как меняется сама профессия программиста.
Первый доклад — «Реальность рынка найма осенью 2026 года». Про трудоустройство в IT прямо сейчас. Скажем так, всё довольно грустно. По приведённым на докладе данным, полноценный поиск работы занимает около полугода, а на одну вакансию может приходиться 2000–3000 резюме. Конкуренция какая-то совершенно нездоровая. Особенно если вспомнить времена, когда программист мог выбирать между несколькими предложениями.
Меняется и сам спрос на специалистов. По словам докладчика, компаниям всё чаще нужны не отдельные фронтендеры или C#-разработчики, а ИИ-инженеры — по сути, фулстеки со знанием AI, способные самостоятельно решить задачу от начала до конца. Пока отдельно держатся бизнес-аналитики и дизайнеры. А вот узкая специализация, похоже, постепенно становится менее привлекательной для работодателей.
PHP2Shell.ru
PHP2Shell: критическая уязвимость PHP — как защититься до патча
CVE-2026-109618 и CVE-2026-109619, CVSS 9.2. Ручные меры защиты и где брать патчи PHP.
❤1👍1
Как я понял, заметно лучше ситуация у Data Scientist и MLOps-инженеров. Это уже специалисты, которые умеют не просто отправлять текст в нейросеть и получать ответ, а работать с моделями, данными, развёртыванием и эксплуатацией ИИ внутри закрытой корпоративной инфраструктуры. Но есть нюанс: таких специалистов рынку требуется относительно немного. Так что массовым спасением для программистов это направление тоже не назовёшь.
Второй доклад — «Human In The Loop — или как жить с нейрослопом». Автор рассказывал про автономных ИИ-агентов на примере DeepSeek Harness. Настроил систему, раздал задачи по своим домашним pet-проектам, оставил работать, а утром получил 700 новых Pull Request (PR). Вроде бы красота: пока ты спишь, ИИ программирует. Только вот теперь попробуй разобраться в этих 700 PR и понять, что он там вообще напрограммировал. Автоматизировали написание кода, а вот что делать с результатом — отдельный вопрос.
В ходе дискуссии пришли к интересному выводу: главное не количество новых коммитов или PR, а Time to Market — время от появления идеи новой фичи до её выхода в production. Можно генерировать сотни PR в день, но если они неделями висят на проверке, никакого ускорения разработки не получится. Просто бутылочное горлышко переедет в другое место.
Поэтому ускорять нужно весь процесс: от бизнес-аналитика и постановки задачи до тестирования, ревью и DevOps. Иначе получится забавная ситуация: программисты при помощи ИИ клепают уйму новых фич, а до прода они добираются с прежней скоростью. Только теперь ещё и приходится разгребать горы автоматически сгенерированного кода.
И вот что интересно. Все три новости, несмотря на совершенно разные темы, об одном и том же. Технологии меняются, ИИ ускоряет работу, появляются новые инструменты, а старые системы никуда не исчезают. И в итоге самое сложное по-прежнему не написать код или сгенерировать красивую картинку, а довести всё это до рабочего результата.
Можно сгенерировать 700 PR за ночь. Но кто-то всё равно должен разобраться, что из этого действительно нужно, как оно работает и кто потом будет это поддерживать.
Второй доклад — «Human In The Loop — или как жить с нейрослопом». Автор рассказывал про автономных ИИ-агентов на примере DeepSeek Harness. Настроил систему, раздал задачи по своим домашним pet-проектам, оставил работать, а утром получил 700 новых Pull Request (PR). Вроде бы красота: пока ты спишь, ИИ программирует. Только вот теперь попробуй разобраться в этих 700 PR и понять, что он там вообще напрограммировал. Автоматизировали написание кода, а вот что делать с результатом — отдельный вопрос.
В ходе дискуссии пришли к интересному выводу: главное не количество новых коммитов или PR, а Time to Market — время от появления идеи новой фичи до её выхода в production. Можно генерировать сотни PR в день, но если они неделями висят на проверке, никакого ускорения разработки не получится. Просто бутылочное горлышко переедет в другое место.
Поэтому ускорять нужно весь процесс: от бизнес-аналитика и постановки задачи до тестирования, ревью и DevOps. Иначе получится забавная ситуация: программисты при помощи ИИ клепают уйму новых фич, а до прода они добираются с прежней скоростью. Только теперь ещё и приходится разгребать горы автоматически сгенерированного кода.
И вот что интересно. Все три новости, несмотря на совершенно разные темы, об одном и том же. Технологии меняются, ИИ ускоряет работу, появляются новые инструменты, а старые системы никуда не исчезают. И в итоге самое сложное по-прежнему не написать код или сгенерировать красивую картинку, а довести всё это до рабочего результата.
Можно сгенерировать 700 PR за ночь. Но кто-то всё равно должен разобраться, что из этого действительно нужно, как оно работает и кто потом будет это поддерживать.
👍1
На работе очередной аврал. Нашли критические уязвимости в Node.js, и обычное обновление превратилось в небольшой технический цирк. А параллельно выяснилось, что исправить неправильную дату в тысячах телефонных разговоров сложнее, чем собрать Node.js из исходников на старой FreeBSD. Причём каждая следующая проблема вылезала ровно после того, как я разбирался с предыдущей. Но обо всём по порядку.
Вот статья про уязвимости: https://habr.com/ru/companies/otus/news/1097666/ Если кратко, нужно переходить на Node.js 22.23.4 или 24.22.1. В нашей компании из сисадминов на Node.js пишу только я. И тут неожиданно выяснилось, что почти за два года я написал очень приличное количество скриптов и сервисов. Теперь всё это хозяйство пришлось собирать в кучку и обновлять.
С Docker-приложениями всё оказалось просто: поправил Dockerfile, пересобрал образ, запустил на сервере — красота. На некоторых серверах с Debian 13 нужной версии Node.js в репозиториях нет, но и это решаемо: скачал готовый бинарник, настроил симлинки. А вот FreeBSD 13 — совсем другая история. Новые пакеты уже не выходят, поэтому полез в исходники и начал собирать Node.js вручную.
Исходники пришлось брать из репозитория FreeBSD 14, а потом молиться, чтобы всё собралось. Одна компиляция Node.js 22 занимает около часа. Часть проектов после перехода с Node.js 20 на 22 собираться отказалась, особенно пришлось повозиться с TypeScript. Версия теперь фактически «прибита гвоздями»: выйдет 22.23.5 — повторяй весь цирк заново.
Параллельно воевал с Яндексом. У нас есть ИИ-система, которая распознаёт телефонные разговоры и оценивает, как менеджеры отрабатывают скрипты продаж. Звонки из АТС загружает моя программа. Всё работало, пока я не заметил две ошибки: один и тот же оператор записан как «Иванов» и «Ivanov», а дата начала звонка уехала в другую тайм-зону. Программу исправил, новые записи стали нормальными. Но старых-то тысячи!
Самое очевидное решение — удалить всё и загрузить заново. Только распознавание у Яндекса платное, и сумма за повторную обработку получается ну очень интересная. Полез в API: метаданные менять вроде бы можно. Фамилия оператора обновляется без вопросов, а дата — никак. Пробовал разные форматы, переписывал запросы. Яндекс бодро отвечает, что всё хорошо, но сама дата остаётся прежней. Техподдержка подтвердила: без повторной загрузки записи её не изменить.
Ладно, хотя бы фамилии исправлю. Написал свою мегапрограмму, запустил в 10 потоков — и тут прилетел
За неделю получил два урока. Первый: Docker сильно облегчает жизнь, когда поддерживаешь много сервисов на разных системах. Второй: ошибка в данных может обойтись дороже, чем ошибка в коде. Код исправил, перезапустил — готово. А тысячи уже распознанных разговоров так просто не поправишь. Ошибку совершить легко. А вот последствия иногда исправлять технически можно, но экономически совершенно бессмысленно.
Вот статья про уязвимости: https://habr.com/ru/companies/otus/news/1097666/ Если кратко, нужно переходить на Node.js 22.23.4 или 24.22.1. В нашей компании из сисадминов на Node.js пишу только я. И тут неожиданно выяснилось, что почти за два года я написал очень приличное количество скриптов и сервисов. Теперь всё это хозяйство пришлось собирать в кучку и обновлять.
С Docker-приложениями всё оказалось просто: поправил Dockerfile, пересобрал образ, запустил на сервере — красота. На некоторых серверах с Debian 13 нужной версии Node.js в репозиториях нет, но и это решаемо: скачал готовый бинарник, настроил симлинки. А вот FreeBSD 13 — совсем другая история. Новые пакеты уже не выходят, поэтому полез в исходники и начал собирать Node.js вручную.
Исходники пришлось брать из репозитория FreeBSD 14, а потом молиться, чтобы всё собралось. Одна компиляция Node.js 22 занимает около часа. Часть проектов после перехода с Node.js 20 на 22 собираться отказалась, особенно пришлось повозиться с TypeScript. Версия теперь фактически «прибита гвоздями»: выйдет 22.23.5 — повторяй весь цирк заново.
apt update && apt upgrade -y тут не спасёт. После такого я стал фанатом Docker. Жаль, на FreeBSD его нет.Параллельно воевал с Яндексом. У нас есть ИИ-система, которая распознаёт телефонные разговоры и оценивает, как менеджеры отрабатывают скрипты продаж. Звонки из АТС загружает моя программа. Всё работало, пока я не заметил две ошибки: один и тот же оператор записан как «Иванов» и «Ivanov», а дата начала звонка уехала в другую тайм-зону. Программу исправил, новые записи стали нормальными. Но старых-то тысячи!
Самое очевидное решение — удалить всё и загрузить заново. Только распознавание у Яндекса платное, и сумма за повторную обработку получается ну очень интересная. Полез в API: метаданные менять вроде бы можно. Фамилия оператора обновляется без вопросов, а дата — никак. Пробовал разные форматы, переписывал запросы. Яндекс бодро отвечает, что всё хорошо, но сама дата остаётся прежней. Техподдержка подтвердила: без повторной загрузки записи её не изменить.
Ладно, хотя бы фамилии исправлю. Написал свою мегапрограмму, запустил в 10 потоков — и тут прилетел
rate limit. Яндекс не любит слишком много запросов подряд. Пришлось снова править код, ограничивать интенсивность и запускать обработку заново. В итоге фамилии исправил, а старые даты остались как есть: при аналитике за сентябрь и октябрь теперь нужно учитывать разницу во времени.За неделю получил два урока. Первый: Docker сильно облегчает жизнь, когда поддерживаешь много сервисов на разных системах. Второй: ошибка в данных может обойтись дороже, чем ошибка в коде. Код исправил, перезапустил — готово. А тысячи уже распознанных разговоров так просто не поправишь. Ошибку совершить легко. А вот последствия иногда исправлять технически можно, но экономически совершенно бессмысленно.
Хабр
В Node.js исправили 10 уязвимостей — включая возможное RCE в Brotli
21 октября команда Node.js выпустила обновления безопасности для веток 22.x, 24.x и 26.x. Разработчики закрыли десять уязвимостей, четыре из которых получили высокий уровень опасности. Среди наиболее...
❤1👍1