и посмотреть медиа
S0ER - arquitectura y codificación
и посмотреть медиа
Materiales sobre arquitectura de software, programación y crecimiento profesional en TI.
Materiales sobre arquitectura de software, programación y crecimiento profesional en TI.
S0ER se centra en la arquitectura de software, programación y desarrollo profesional. El canal ofrece análisis en profundidad, ejemplos de código y estrategias para el avance en el campo de la TI.
TurboFan: анализ оптимизаций в V8 с помощью ассемблера (часть 1) Чем глубже мы узнаем языки программирования, тем больше начинаем любить и ценить ассемблер. Сегодня покажу, как знание ассемблера помогает в изучении возможностей движка V8. V8 — это движок для работы с языком JavaScript, он используется в NodeJS и браузере Chrome. Одна из особенностей этого движка — представление «горячего» кода в виде оптимизированных машинных инструкций. Для этого в движок интегрирован оптимизирующий JIT-компилятор TurboFan. Основные задачи, которые решает TurboFan: 💡 Анализ и оптимизация «горячих» функций (которые вызываются часто); 💡 Специализация кода под конкретные типы данных; 💡 Удаление избыточных операций; 💡 Векторизация вычислений; 💡 Инлайнинг функций. Для работы с машинным кодом традиционно используется ассемблер, поэтому давайте разберем небольшой пример, который позволит лучше понять, как работает TurboFan. В этой статье будет общее описание блоков кода, а в будущих статьях разберем детали каждого из них. Основные моменты, которые нужны для старта: 1️⃣ Мы будем использовать nodejs для получения машинного кода функции, для этого нужно запомнить следующий шаблон команды: node --print-opt-code --code-comments -allow-natives-syntax your_script.js 2️⃣Мы будем использовать специальную инструкцию %OptimizeFunctionOnNextCall, без нее ничего не получится. Давайте сделаем простой скрипт: // sum.js function sum(a, b) { return a + b; } // Прогреваем функцию (вызываем много раз, чтобы V8 её оптимизировал) for (let i = 0; i < 10000; i++) { sum(i, i + 1); // используем целые числа, чтобы TurboFan сделал оптимизацию именно под них } // Явно просим V8 оптимизировать функцию (требует --allow-natives-syntax) иначе в выводе не будет описане функции %OptimizeFunctionOnNextCall(sum); // Вызываем ещё раз (теперь с оптимизацией) sum(1, 2); Теперь запустим скрипт node --print-opt-code --code-comments -allow-natives-syntax sum.js, если мы сделали всё правильно, то получим огромный вывод на экран, из которого интересна вот эта часть: --- Raw source --- (a, b) { return a + b; } --- Optimized code --- optimization_id = 1 source_position = 22 kind = TURBOFAN name = sum stack_slots = 6 compiler = turbofan address = 0x2edae09247a1 Instructions (size = 184) ; загрузка hidden класса объекта (проверка структуры) 0x1097064c0 0 488b59f8 REX.W movq rbx, [rcx-0x8] ; проверка контекста 0x1097064c4 4 f6433501 testb [rbx+0x35],0x1 0x1097064c8 8 0f85f2e03dfb jnz 0x104ae45c0 (CompileLazyDeoptimizedCode) ;; деоптимизация ; пролог 0x1097064ce e 55 push rbp 0x1097064cf f 4889e5 REX.W movq rbp, rsp 0x1097064d2 12 56 push rsi 0x1097064d3 13 57 push rdi 0x1097064d4 14 50 push rax ; выравнивание стека и проверка лимитов 0x1097064d5 15 4883ec08 REX.W subq rsp,0x8 0x1097064d9 19 488975e0 REX.W movq [rbp-0x20],rsi 0x1097064dd 1d 493b65a0 REX.W cmpq rsp, [r13-0x60] (external value (StackGuard::address_of_jslimit())) 0x1097064e1 21 0f8653000000 jna 0x10970653a ; если стек переполнен, переходим ; ====== Основная функция ====== ; Загрузка аргумента "a" 0x1097064e7 27 488b5518 REX.W movq rdx, [rbp+0x18] 0x1097064eb 2b f6c201 testb rdx,0x1 0x1097064ee 2e 0f8572000000 jnz 0x109706566 ; Загрузка аргумента "b" 0x1097064f4 34 488b4d20 REX.W movq rcx, [rbp+0x20] 0x1097064f8 38 48c1f920 REX.W sarq rcx, 32 ; сразу распаковка SMI для "b" ; Подготовка аргументов к сложению 0x1097064fc 3c 488bfa REX.W movq rdi,rdx 0x1097064ff 3f 48c1ff20 REX.W sarq rdi, 32 ; распаковка для "a"
Открыть канал и посмотреть медиаЛюбую проблему можно решить введением дополнительного уровня абстракции, кроме одной — слишком большого количества уровней абстракции. Иногда слушаешь человека, вроде и говорит хорошо, вроде и по делу, а потом он брякнет что-то типа «идентификатору присвоили значение 10», и хочется плакать, ведь даже чат-бот знает, что с идентификатором значение можно только ассоциировать (или слинковать, кому как нравится), а присвоить значение можно только переменной. Хуже становится, только если особо гениальный ум скажет: «Так переменная — это и есть идентификатор», сразу становится понятно, что человек не понимает разницы между семантикой языка программирования и его синтаксисом. Для многих открытие, что переменная и идентификатор — это термины, которые существуют на разных уровнях абстракции. Да чего там, сам факт, что в программировании - всё есть абстракции, выглядит для человека как непосильная для осмысления и анализа мысль. 💡 Поэтому просто запомните, что переменная принимает и хранит значения, можете спросить у ИИ, почему это так, а идентификатор — это имя, которое обозначает переменные, функции, объекты, по сути, это просто ссылка. Идентификатор существует на уровне синтаксиса языка программирования, немного на уровне семантики (например, при определении области видимости). Когда уместно говорить «идентификатор», когда «переменная»? В случаях, когда речь идет о синтаксисе языка, можно говорить «идентификатор», а можно «имя переменной», что есть одно и то же, но когда речь идет об алгоритме, то правильно говорить «переменная». Надеюсь, мое объяснение поможет лучше разобраться и не использовать термины не по назначению.
Открыть канал и посмотреть медиаЕсть известная фраза «Преждевременная оптимизация — корень всех зол». Современные программисты используют эту фразу в качестве индульгенции своего невежества. Многие знают, что фраза принадлежит Дональду Кнуту — известному компьютерному учёному, автору монументального труда «Искусство программирования» (The Art of Computer Programming). Но мало кто знает контекст и изначальный посыл этой фразы, на самом деле в 1974 году Кнут написал статью «Structured Programming with go to Statements», где сказал: «Программисты тратят колоссальное время на размышления и беспокойство о скорости некритичных частей своих программ, и эти попытки повысить эффективность на самом деле оказывают сильное негативное влияние при отладке и поддержке. Мы должны забыть о мелких оптимизациях, скажем, в 97% случаев, потому что преждевременная оптимизация — корень всех зол. И всё же наше внимание к этим критичным 3% не должно ослабевать.»
Открыть канал и посмотреть медиаВсегда ли короткие имена переменных - зло? Никто не будет спорить с тем, что имена переменных в коде должны быть понятными и выразительными. Но с тем, что выразительное имя - это всегда полное длинное описание из которого можно сделать вывод для чего существует та или иная переменная - это тема для спора. Я люблю короткие имена переменных, люблю аббревиатуры, часто их использую и мне не нравится писать длинные имена по типу "encodedDataBasePasswordStr", даже с автокомплитом. Поэтому давайте сформулирую свои правила в отношении коротких имен переменных. 👑 Когда короткие имена приемлемы ✅В небольших методах с очевидным контекстом ✅В математических вычислениях, где традиционно используются короткие обозначения ✅Для итераторов в небольших циклах ✅В лямбда-функциях, где контекст ясен Пример оправданного короткого имени. function calculateDistance(x1: number, y1: number, x2: number, y2: number): number { const dx = x2 - x1; const dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); } В этом случае: x1, y1, x2, y2 - стандартные математические обозначения координат dx, dy - общепринятые сокращения для "delta x" и "delta y" А типы параметров (number) делают назначение переменных ещё понятнее 👑 Когда короткие имена недопустимы Однако есть ситуации, когда короткие имена действительно становятся проблемой: ✅ В больших методах, где контекст теряется ✅ Для переменных с широкой областью видимости ✅Когда назначение переменной неочевидно ✅Для булевых флагов, где важно понимать критерий Пример плохого использования: function processUserData(u: User, d: DataProcessor, c: Config) { // ... 50 строк кода ... if (u.s) { // Что такое 's'? Статус? Субscription? Счёт? d.p(u); // Что делает 'p'? process? print? persist? } } При этом вместо 'u' вполне можно было использовать сокращения usr, а вместо 'c' использовать cfg, это устоявшиеся сокращения, поэтому использовать их можно. Когда есть возможность аннатировать переменную ее типом, с учетом небольшого размера функции, нормальным становится и вариант с u: interface User { id: string; name: string; age: number; } // Хорошо - тип ясен из контекста function greet(u: User) { console.log(`Hello, ${u.name}!`); } Для итераторов в небольших циклах короткие имена допустимы: const numbers = [1, 2, 3]; // i - общепринятое имя для индекса for (let i = 0; i < numbers.length; i++) { console.log(numbers[i]); } В функциональном программировании для простых операций: const users = [{name: 'Alice'}, {name: 'Bob'}]; // n - понятно в контексте map const names = users.map(u => u.name); 👑 Надеюсь, приведенные пример убедили вас, что в зависимости от ситуации короткие имена переменных не только допустимы, но и помогают писать выразительный код.
Открыть канал и посмотреть медиаЗаметил за собой странное искажение, которое возникает при работе с LLM. Когда что-то не получается, я злюсь на себя, думая что не могу правильно сформулировать задачу, так чтобы ИИ меня понял. Ищу другие промпты, пытаюсь играть с версиями моделей, менять русский на английский и т.д. Мысль, что я пытаюсь заставить решать GPT что-то выходящие за рамки его возможностей в голову почему-то не приходит.
Открыть канал и посмотреть медиаУ нас изменился способ авторизации на soer.pro, теперь основной вход через логин и пароль, если у вас есть подписка, чтобы ее не потерять, нужно на странице логина пройти регистрацию. Спасибо за понимание.
Открыть канал и посмотреть медиаУстраивайтесь поудобнее: будем разворачивать ВМ 🚬 Делимся новым видео на канале S0ER. Женя рассказал, как выбрать и настроить ВМ, как установить Docker, Node.js и другие инструменты для разработки, а также как настроить терминал и плагин Tix для совместной работы. Посмотреть можно по ссылкам: 😶🌫️ YouTube 😶🌫️ VK видео 😶🌫️ RuTube Еще больше сценариев использования платформы Cloud․ru Evolution ищите по ссылке 👈
Открыть канал и посмотреть медиаCode of Leadership #31 - Hooked: how to build habit-forming products (Рубрика #Management) Новый эпизод подкаста посвящён обсуждению книги Нира Эяля «На крючке» и её модели создания продуктов, формирующих привычки. Для обсуждения книги пришел Евгений Сергеев (S0ER), который поделился опытом применения модели в разработке ПО, обсуждения её этических аспектов и влияния на пользователей. В общении мы затронули темы поведенческих триггеров, адаптации продуктов к привычкам пользователей, а также эволюции технологий, программирования и роли разработчиков. Особое внимание уделили важности обратной связи, доверия пользователей и интеграции продуктов в экосистемы. Евгений уже много лет публикует хорошие видео на Youtube на канале S0ER, а также у него есть каналы в tg (@softwareengineervlog и @soer_live). Он много рассказывает про хард скиллы в обще, а также про проектирование и архитектуру в частности. Выпуск подкаста доступен в Youtube, VK Video, Podster.fm, Ya Music. #Architecture #Software #Engineering #ProductManagement #Management #Economics
Открыть канал и посмотреть медиаСегодня начал дарить подарки 🎁 за развитие айти блогинга, думаю, что это отличный способ мотивировать авторов развиваться и делать ещё более крутой контент. Сегодня я раздал подарков на 10.000 рублей, предпочтение отдавал молодым техническим каналам, авторы которых продвигают хардскилы, поэтому проверьте, если у вас появилась 🤵 в подарках канала, то это от меня. В следующий раз раздам подарков ещё больше. Поэтому накидайте в комментарии хороших технических телеграм пабликов 💡 И главное помните хардскилы - это сила. 💡
Открыть канал и посмотреть медиаSolo los usuarios registrados pueden compartir su opinión.
¡Sé el primero en compartir tu experiencia con este recurso!