Цифровой пролетарий
50 subscribers
20 photos
20 links
«У самурая нет цели, есть только путь» © (какой-то японец)

Пишет @Kkroosh
Download Telegram
1310. xor-queries-of-a-subarray

📍 Чтобы решить эту задачу, надо знать, что такое исключающее или (XOR).
В javascript операцию XOR между двумя числами выполняет знак ^ .
Дает единицу тогда, когда только один из двух битов равен 1.
🏷️ Небольшая шпаргалка:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

Ход решения:

1️⃣ Посчитать префиксные XOR для каждого последующего элемента. Начальный элемент будет равен 0.
2️⃣ Чтобы получить массив answers, надо проделать операцию XOR между двумя значения prefixXOR, притом второе значение берем с индексом + 1.

Пояснения 🪴
📎 arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
// 1 = 0001
// 3 = 0011
// 4 = 0100
// 8 = 1000

📎 Массив prefixXOR = [0, 1, 2, 6, 14]
// 0 : 0
// 1 : 0001 -> 1
// 2 : 0011 ^ 0001 = 0010 -> 2
// 3 : 0100 ^ 0010 = 0110 -> 6
// 4 : 1000 ^ 0110 = 1110 -> 14

📎 Массив answers = [2, 7, 14, 8]
// 0 : 00 ^ 10 = 10 -> 2
// 1 : 001 ^ 110 = 111 -> 7
// 2 : 0000 ^ 1110 = 1110 -> 14
// 3 : 0110 ^ 1110 = 1000 -> 9

💡Почему же применение XOR к заранее посчитанным prefixXOR дает нужный результат в диапазоне?
На примере [1, 2]:

prefixXOR для index 1 = 0001 ^ 0 =1
prefixXOR для Index 2 (добавляем + 1, чтобы включить текущий правый конец) = 0001 ^ 0011 ^ 0100 = 6
XOR для диапазона [1, 2] без префиксных XOR: 0011 ^ 0100 = 7.

Таким образом, можно заметить, что всё, что до нужного диапазона, самоуничтожиться. 0001 ^ 0001 = 0.
Оздоровительная физкультура

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

Превалирующий малоподвижный образ жизни оказывает негативное влияние на здоровье. Есть куча статей и видео на эту тему. Эксперты утверждают, что 2-3 интенсивные тренировки в неделю не исправят ситуацию при сидячем положении в течение 8 часов, а могут даже усугубить.

Нужна двигательная активность во время работы.
Выход — делать каждые 30-40 минут перерыв на приседания.

Почему приседания?
Если кратко, то во время выполнения задействуются самые большие группы мышц, а значит, кровь прогоняется активнее.

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

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

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

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

P.S. Оптимальная планка для меня — около 100 приседаний за день. Но, возможно, когда-нибудь дойду до рекордов Приседалыча, но это не точно
Как говорит мой закадычный друг: "Курсов много не бывает."

Под конец августа начал проходить курс по node.js и вот прошло 6 модулей длительностью 7 месяцев.

Я преследовал следующие цели:
расширение кругозора, выработку привычки ежедневно учиться, создание места для маневра (fullstack, backend), получение базовых навыков для создания серверов на node.js

Ко всему прочему на курсе ламповая атмосфера и формат мне импонирует(отсутствие видео с объяснениями); общение, задания в текстовом формате, иногда созвоны.

Изучил базово node.js, потом перешел на написание с помощью express, а затем уже на моднейший фреймворк nest.js. В качестве базы данных на протяжении всего курса использовалась Mongo. Также к середине обучения начал применять подход TDD(Test Driven Development). Было неприятно, но один из проектов получилось написать полностью следуя этому подходу. Потрогал немного микросервисы на nest.js. Также было много полезностей, отдельно их не выношу.

Обучение необходимо по двум причинам:
1) Не учишься - отстаешь
2) Отвлечение от рабочей рутины

Делаю небольшой перерыв и продолжаю дальше. Давно ждут курсы от Кобеца.
Анимации

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

Но можно возразить на этот счет: "Уже завезли свойство interpolate-size в css для height: auto".
В таком случае надо использовать caniuse и заметить, что это свойство плохо поддерживается многими браузерами. Такое не используем.

Тут я нашел два выхода:
1) Эмпирический коэффициент, который из начального состояния высоты посчитает конечную.
Получилось плохо. Зависит от многих факторов, всех учесть невозможно и всё равно получается неточно.
2) Отрисовать незаметно элемент в DOM'e в конечном состоянии, зафиксировать высоту и в дальнейшем использовать.

Получить высоту элемента в потоке html страницы можно с помощью offsetHeight. Но это свойство надо всегда применять с осторожностью, так как оно очень ресурсоемкое из-за того что вызывает reflow.

Статья про reflow
O(n)
О-нотация используется для оценки сложности выполнения программы. Это не определенное число. Это функция, которая показывает во сколько раз изменится количество операций при изменении входных данных. Ошибочно полагают, что если О(1), то операция выполняется мгновенно. Эта запись просто говорит о том, что количество операций не зависит от входных данных. Грубо говоря, когда мы берем значение из Map'ы - нет разницы в величине Map'ы. Но при этом компьютер проведет какие-то вычисления и потратит некоторое время, чтобы найти значение.

О(n) - во фронтенде.
Исходные данные: монитор, процессор, абстрактная программа, которая выполняется за О(n^2)

📺 Монитор будет иметь 100 Гц
💻 Процессор будет с тактовой частой 1ГГц (1 000 000 000 Гц)

При каком количестве входных данных мы заметим, что что-то выполняется очень медленно?

Монитор 100 Гц меняет кадр каждые 10мс. То есть, в том случае, если за 10мс компьютер не успеет посчитать новое значение, мы увидим торможение.
За 10мс процессор может сделать 1 000 000 000 / 100 = 10 000 000 операций.

О(n^2) = 10 000 000
n = √ 10 000 000 = 3 162 - число входных данных, до которых не будет заметен лаг на мониторе.

Такая занимательная арифметика на ночь 📺
Please open Telegram to view this post
VIEW IN TELEGRAM
Экстраверт или интроверт

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

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

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

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

Разработка в большинстве своём — это про общение и взаимодействие с другими людьми.
Rebase или merge

Много статей написано на эту тему. Если брать в первом приближении merge понятнее и имеет возможность просто откатиться в случае чего.

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

Для тех, у кого не так много опыта с rebase, можно перестраховаться так: создавать временную ветку перед rebase'ом или еще одну локальную копию проекта (отнимает много места).
Занимательный факт

Недавно узнал интересный факт, с которым сталкиваются все frontend-разработчики.

fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))


Код примерно в таком виде писали все. Получаем response, дальше парсим body, чтобы получить json и дальше уже остальная логика.
Но в js есть статический метод JSON.parse и он работает синхронно, а в примере выше асинхронно.

Самый первый промис резолвится тогда, когда мы можем получить заголовки, но body еще может не быть. Если бы промис резолвился относительно получения всего body, тогда метод был бы синхронным, как и привычный JSON.parse. Но это не так.

Знал про это?
🤡 - да 👍 - нет 🌚 - не пишу код
Please open Telegram to view this post
VIEW IN TELEGRAM
Почти довёл своё рабочее место до идеала: купил нормальное кресло Samurai S-3.05.

Можно работать в разных условиях, но безусловно каждая мелочь влияет на продуктивность и здоровье.
Как в истории с Брейлсфордом и британским велосипедным спортом, где искали варианты улучшений хотя бы на 1 %. Также можно улучшать и рабочее место, пока будет нечего улучшать.

P.S. Хруст в шее — один из симптомов остеохондроза.
Примитивы по значению, а объекты по ссылке

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

Сам процесс в ноде занимает около 3,5 мб.
Создаем массив на 5 млн элементов, одна ячейка занимает 8 байт. + 40 мб к занимаемой памяти.

Делаем из массива строку, латинская буква занимает 1 байт. + 5 мб к занимаемой памяти.

Итого получилось 48,5 мб занимаемой памяти. Создаем новую переменную и кладем туда строку. Следуя правилу из названия должны скопировать по значению и увидеть в heapUsed примерно 53,5 мб. Но этого не происходит.

Потому что движок V8 оптимизирует трату памяти в таких случаях.

const arr = Array(5_000_000).fill("k"); // 5 млн × 8 байт ~ 40 МБ // 43_462_864 байт
const s = arr.join(""); // 5 млн × 1 байт ~ 5 МБ, итого // 48_548_144 байт
const s2 = s;

console.log(process.memoryUsage())
Обилие технологий оставляет свой отпечаток: лента негативных новостей, сравнение себя с другими, частое переключение контекста и так далее.

Троица книг, чтобы привести мысли в порядок.
"Тонкое искусство пофигизма" Мэнсон Марк
"Антидот" Оливер Букерман
"Unfu*k Yourself" Гэри Джон Бишоп
Please open Telegram to view this post
VIEW IN TELEGRAM
Недавно попался интересный автор с хорошим слогом, у которого опыт в it около 20 лет.

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

Я решил изучать классический бэкенд в разрезе Java. ☕️

При создании javaScript'a опирались на Java, так как он был очень популярен в то время. Поэтому синтаксис javaScript очень схож c Java.
Если был опыт работы с typescript, то переход на Java до уровня написания простых программ пройдет быстро.

Читал про столпы ООП: инкапсуляция, наследование, абстракция и полиморфизм.

Если с первыми тремя всё относительно понятно, то с полиморфизмом поинтереснее.
Я до этого был знаком именно с полиморфизмом подтипов, а видов полиморфизма оказалось больше одного.

В Java есть ad hoc полиморфизм. —> Можно описывать одноименные методы с разными типами. В зависимости от передаваемых типов будет выполнен нужный метод.

Также узнал про параметрический полиморфизм. В typescript это джейнерики.
Please open Telegram to view this post
VIEW IN TELEGRAM
Пишу очередной hello world

Установил всё нужное для компиляции java программ. Скомпилировал файл. Запускаю и получаю ошибку.
Ошибка была связана с тем, что я не снёс старую версию java. Видимо Siemens NX 10 был написан на java 8.

Дело в том, что java - обратно совместимый язык, впрочем как и JavaScript. В этом есть плюсы так и минусы: всё, что попадает в язык, остается там.

Большинство операционных систем(ОС) обратно совместимы. Но так было не всегда, раньше приходилось переписывать софт под новые версии одной ОС. Теперь большинство программ, написанных под старые версии, будут работать в новых версиях одной и той же ОС.

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

Интересно еще то, что в своей первой книги из серии "You don't know js" Кайл Симпсон в самом начале как раз разбирает два этих понятия.
Coderun

Вчера стартанул новый третий сезон Coderun. Рекомендую всем, кому нравится решать задачки. В этом году изменили формат и, как я понял, сделали задачи одинаковые для всех без разделений на домен (фронтенд/бекенд/мл и тд).

Получается не будет зубодробительных задач с css, как эта.
Также вот, например, интересная задача на прототипы в js (по крайней мере я решал ее через прототипы).
В 22:30 будет ссылка на стрим.
Буду пробовать смоделировать шкатулку с ирисовым механизмом. Такое я уже предпринимал пару лет назад, но подгонял всё на лету.
Сейчас появилось желание рассчитать все элементы и сделать нормально. Потом можно написать мини-приложение для расчета разного количества лепестков и заодно поработать с canvas'ом.
Подход к обучению ⚒️

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

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

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

4️⃣ случая тестирования, которые следует учитывать:

Пустые, нулевые значения
Граничные значения(максимальное, минимальное)
Регрессионный тест
Множество рандомных тестов

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

📔 Грокаем алгоритмы | Бхаргава - великолепно подойдет для первого знакомства
📗 Структуры данных и алгоритмы в Java | Лафоре - отличное объемлющее изложение
📘 JavaScript Algorithms Book | Trekhleb - широкий обзор на алгоритмы и структуры данных через призму JS, есть на гитхабе на разных языках
Please open Telegram to view this post
VIEW IN TELEGRAM
Продолжаю прорабатывать основные структуры данных.

🔗🔗🔗 Связный список, двунаправленный связный список

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

Узнал, что такое dummy-узел. Очень удобная вещь. Вместо головы и хвоста с пустым значением вставляется фиктивный узел. Сокращает реализацию многих методов для связного списка, так как не приходится проверять какой именно это случай: начало, центр или конец.

💻 Динамический массив

В JS всегда доступна такая роскошь, как динамический массив.
В Java сделал имплементацию динамического массива, чтобы лучше понять, как всё это устроено. Изучил банковский метод анализа сложности динамических массивов. С его помощью легко проверить, что даже при дорогостоящий реаллокации массива, все операции в среднем выполняются за О(1).

Ну и сделал интереснейшую задачу на реализацию многомерного динамического массива с возможностью масштабирования внутренних измерений. Пару дней на нее потратил.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔘 Также сегодня в 21:30 стрим со шкатулкой.

📍 О чем речь - прошлый пост.
Дайджест за август 🏖️

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

При нарешивании задачек очень полезно писать тесты. В конце поста топ-3 книги по алгоритмам. Подробнее здесь.

Углубляюсь в computer-science и постигаю основы, на которых всё базируется. Начало.
Please open Telegram to view this post
VIEW IN TELEGRAM
Конференции 📺

Небольшая ремарка :
Я хожу только на бесплатные митапы, преимущественно на MoscowJS (когда выпадает билетик). На платных не вижу смысла отдавать 30к за билет.


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

1️⃣ Очевидное - это нетворкинг. Важность его несомненна. Он в себя также включает - расширение кругозора.
Интересно было узнать, что парень зарабатывает себе на жизнь написанием кросс-платформенных приложений на Electron, а посещая конференции ищет потенциальных клиентов(в основном представители малого бизнеса).

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

3️⃣Вдохновение/ Мотивация. Этот пункт я бы сделал опциональным, так как такое случается за редким исключением. Действительно, есть спикеры с хорошими темами и подачей, которые мотивирует еще больше расти как специалист.

В заключение к 3-ему пункту расскажу про конференцию "Чинители прекрасного", которую посещал пару месяцев назад.

Интересный доклад был про считывание ДНК. Понимаешь, что человек решает на несколько порядков сложнее задачи. Это не очередной фреймворк на js.
Старая статья спикера

Отдельно от сцен были еще стенды с разными изобретениями. В юношестве увлекался сборкой головоломок и больше всего внимания привлек робот, собирающий кубик Рубика за четверть секунды. Уверен и для людей, не интересующихся подобной темой, эффект будет не менее впечатляющий. Интересно, что на тот момент это был мировой рекорд и это сделал один человек, потратив 4 года.
Статья про процесс создания робота
Please open Telegram to view this post
VIEW IN TELEGRAM