Кодовая база – Telegram
Кодовая база
1.26K subscribers
16 photos
1 video
30 links
База во фронтенд разработке.

Написать в личку: https://news.1rj.ru/str/devmargooo
Download Telegram
🎯Рекурсия

Если вы понимаете, что такое рекурсия и когда её применять — можете пропускать этот пост 🙂

〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️

Рекурсия во фронтенде встречается чаще, чем кажется. Например:

🔘 вычисление коэффициентов для анимаций;
🔘 обход и рендеринг древовидных структур (комментарии с тредами, дерево директорий и файлов);
🔘 парсинг вложенных данных (например, JSON-схемы);
🔘 написание утилит (например, парсинг токенов Figma для автоматической генерации переменных дизайн системы).

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

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

〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️

🔘Пример 1. Факториал.

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

const  factorial = (x) => x *  factorial(x - 1)

Затем нужно учесть корнер кейсы. Мы вычитаем 1 из x и очевидно, что лучше не делать это до минус бесконечности. Нужно выбрать какое-то конкретное число, на котором мы остановимся. Логично выбрать число 0, потому что это наименьшее число, для которого определена функция факториала. Получаем финальное решение:

const  factorial = (x) => x ?  x *  factorial(x - 1) : 1



🟣Пример 2. Обход дерево.

Задача: есть дерево, где каждая нода содержит id и массив children. Нужно собрать все id.

Заметим, что задача сильно упрощается, если нам не нужно думать про id дочерних элементов. Предположим, что уже существует функция getChildrenIds, которая возвращает id дочерних элементов. Останется добавить id текущей ноды. Получаем решение:


const getIds(node) => […getChildrenIds(), node.id] 


Теперь реализуем getChildrenIds. Она должна вернуть все id дочерних элементов. Но у нас уже есть функция getIds, которая вернет id элементов поддерева. Если вызвать ее для каждого потомка, то она вернет все id всех поддеревьев. Итого:

const getIds = (node) => {
let result = [node.id];
node.children.forEach((child) => result = result.concat(getIds(child)))
return result;
}


Желаю вам удачного выхода из рекурсивного цикла! 🔄 Еще про рекурсию можно почитать в этом посте.

#алгосы
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8🥱5
Forwarded from fedos dot com
👆 Фредерик П. Брукс. «Мифический человеко-месяц: очерки о разработке программного обеспечения». Эссе «Нет серебряной пули».

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



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

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

Нам всегда будут нужны люди, способные заполнить брешь между задачей реального мира, которую нужно решить, и компьютером, предназначенным для решения этой задачи. Эти люди будут называться программистами независимо от того, манипулируют они машинными регистрами на ассемблере или диалоговыми окнами в Microsoft Visual Basic. Пока у нас есть компьютеры, нам будут нужны люди, которые говорят компьютерам, чтó делать, и эта деятельность будет называться программированием.

Когда вы слышите заявления о том, что «новый инструментарий устранит необходимость компьютерного программирования», бегите! Или хотя бы посмейтесь про себя над этим наивным оптимизмом.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7💯31👎1🤔1
Решила проверить, как обстоят дела с поиском работы для фронтендеров на hh. Создала максимально дефолтное резюме максимально дефолтного миддла на React, указала 3 года опыта работы в ноу нейм компания. Сделала 30 откликов (на большее не хватило времени).

Результаты:

▫️Отказов: 10 (один автоматический спустя минуту, в бигтех)
▫️Предложений от hr перейти общаться в телеграмм: 2
▫️Тестовое: 1
▫️Звонок (на hh появились звонки?...): 1

Что лично я считаю неплохим результатом.
Please open Telegram to view this post
VIEW IN TELEGRAM
1🤗14💩8👍61🤡1
🚀 Как делать задачи быстрее

Самый простой способ ускорить работу, если вы фронтенд-разработчик - это использовать жоский typenoscript. То есть не ограничиваться стандартными типами string/number/boolean и объектами из них, а реально ограничить тип только возможными значениями.

Например, email - это не любой string, а только составленный по определенному правилу, содержащий символы @ и .. Пин-код, - это тоже не любой string, а строка ровно из 4 цифр.

📌 Чем жестче ваш typenoscript, тем быстрее вы будете работать.

На первый взгляд это звучит парадоксально: почему скорость работы увеличится, если жесткая типизация добавит работы? А вот почему:

1️⃣ Меньше ручных проверок

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

2️⃣ Меньше багов и возвратов из тестирования

Основная задача typenoscript как инструмента - снизить количество ошибок в рантайме, перенеся их в compile-time. Чем жестче ваша типизация, тем меньше багов будет в результате 🔜 меньше доработок и возвратов фичи из тестирования


3️⃣ Типы выполняют роль документации и делают код более читаемым.

Для тех, кто хочет попрактиковаться в написании типов, есть классный репозиторий https://github.com/type-challenges/type-challenges - в нем собраны задачи от самого легкого до продвинутого уровня.
Please open Telegram to view this post
VIEW IN TELEGRAM
118🔥9👍4👎3❤‍🔥2🌚21💯1🤝1
Дискуссия про применимость алгоритмических задач с собеседований в реальной работе получила новый виток. Сегодня в комментариях подкинули вот такую задачу с собеседования:

*️⃣*️⃣*️⃣
Вы хотите набрать строку s, состоящую из строчных латинских букв, в вашем любимом текстовом редакторе Notepad#.
Notepad# поддерживает два типа операций:
дописать любую букву в конец строки;
скопировать непрерывную подстроку уже напечатанной строки и вставить эту подстроку в конец строки.
Можно ли набрать строку s за число операций, меньшее длины строки?
canBeTypedFaster("tbank") => false
canBeTypedFaster("mama") => true

*️⃣*️⃣*️⃣

Задача несложная, мне потребовалось примерно двадцать секунд на подумать и еще пару минут на закодить. Вот что у меня получилось:

function canBeTypedFaster(str) {
const set = new Set();
for (let i = 0; i < str.length - 1; i++) {
const substring = str.substring(i, i + 2);
if (set.has(substring)) {
return true;
}
set.add(substring);
}
return false;
}


Как я рассуждала: для того, чтобы воспользоваться опцией копипаста, нужно, чтобы в целевой строке повторялась хотя бы одна группа из двух символов. Тогда эту группу можно будет скопировать и вставить. Можно и больше, но двух символов хватит. Следовательно, задача сводится к тому, чтобы понять, есть ли в строке повторяющиеся группы из двух элементов. Дальше все просто: я прохожусь по строке и запоминаю все группы из двух подряд идущих символов, а также проверяю, встречалась ли мне такая группа раньше. Если встречалась, то значит, эту группу можно скопировать и для такой строки ответ будет true. В противном случае ответ будет false.

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

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


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

#алгоритмы
Please open Telegram to view this post
VIEW IN TELEGRAM
110👍5👎5❤‍🔥3🤮1🍌1
Скормила эту задачу чату гпт. Вот что он мне выдал:
*⃣*⃣*⃣
Думал на протяжении 16s

Короткий ответ: да — ровно тогда, когда в строке s существует фрагмент длины ≥ 2, который в какой-то момент встречается снова так, что его второе вхождение начинается в позиции, когда префикс до этой позиции уже напечатан. Формально: существует i (1 ≤ i ≤ n-1) и L ≥ 2 такие, что i + L ≤ n и s.substring(i, i+L) встречается в s.substring(0, i). В этом случае можно одну или несколько таких копий использовать и получить число операций < n.

Ниже — простая и надёжная реализация на JavaScript:
// Возвращает true, если строку s можно набрать за число операций < s.length
function canBeTypedFaster(s) {
const n = s.length;
if (n <= 1) return false; // невозможно сократить
// для каждой позиции i — попробовать найти любую длину L>=2,
// такую что s[i:i+L] содержится в префиксе s[0:i]
for (let i = 1; i < n; i++) {
// максимальная длина, которую можем попытаться скопировать отсюда
const maxL = n - i;
// интересуют только L >= 2
for (let L = 2; L <= maxL; L++) {
const chunk = s.substring(i, i + L);
if (s.substring(0, i).indexOf(chunk) !== -1) {
return true;
}
}
}
return false;
}

// Примеры
console.log(canBeTypedFaster("tbank")); // false
console.log(canBeTypedFaster("mama")); // true


Сложность приведённого кода в худшем случае O(n³) в naive JS (из-за indexOf внутри двойного цикла), но на строках обычной длины это проходит быстро. Если нужна оптимизация для больших строк — можно применять суффиксный массив/дерево, Z-функцию или KMP/rolling hash, чтобы сократить до O(n²) или O(n).
*⃣*⃣*⃣

По-моему, какая-то лажа. Чат гпт решил искать не только группы из двух элементов, но и более длинные, хотя достаточно групп из двух элементов - они входят в более длинные. Еще и сложность кубическая.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥8👎2🖕21🤮1
Друг скинул еще одну задачу с собеседования: https://leetcode.com/problems/isomorphic-strings/. На ее решение у меня ушло около 7 минут. Решение:

var isIsomorphic = function(s, t) {
const dictS = {};
const dictT = {};
for (let i = 0; i < s.length; i++) {
const sChar = s[i];
const tChar = t[i];
if (!check(sChar, tChar, dictS) || !check(tChar, sChar, dictT)) {
return false;
}

}
return true;
};

function check(origin, replacer, map) {
if (map[origin]) {
return map[origin] === replacer
}
map[origin] = replacer;
return true;
}

Меня огорчило, что я не попала в 10% самых быстрых решений (beats 89.81%). Закинула чат гпт и он решил гораздо хуже (beats 32.05%).
Вот так этим вечером внезапно выяснилось, что чат гпт решает алгозадачи так себе - по крайней мере, те две, которые мы разбирали сегодня в канале, он решил хуже меня.

Для меня это еще один повод использовать алгозадачи на собесах 😎
👎23🔥14👍6🤮31🖕1
Мне интересно, дизлайк на предыдущий пост поставил человек, который попал в 10% самых быстрых решений? 🤔
👎21💩6🐳3🦄3🤣1🖕1
🍇 Немного о сортах типизации

Раз уж я заговорила про typenoscript, считаю своим долгом погрузить вас в эту тему.

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

const x: number = 42; // ок, в number можно присвоить number
const y: number = ‘abc’; // ошибка, в number нельзя присвоить строку


Однако не все знают, что языки программирования имеют разный взгляд на то, какой же тип является “сопоставимым”. Бывают языки с номинативной и структурной типизацией.

Номинативная типизация

Языки с номинативной типизацией используют имя типа для того, чтобы считать, что тип является сопоставимым. Так типизация работает в Java: если мы объявляем значение и указываем тип, то присвоить в это значение мы можем только этот же самый тип либо потомок (логически, потомок тоже является тем же самым типом, просто с некоторыми уточнениями).

class Order { public String id; }

// PriorityOrder технически тоже является Order-ом, просто с дополнительными свойствами
class PriorityOrder extends Order { }

public class Main {
public static void main(String[] args) {
// ок, присваиваем в Order значение типа Order
Order o1 = new Order();
// PriorityOrder тоже можно присвоить в переменную типа Order, так это наследник
Order o2 = new PriorityOrder();
}
}


Если у нас есть другой класс, который совпадает по структуре, но не является наследником, присвоить его нельзя:

class CustomerRequest { public String id; }

public class Main {
public static void main(String[] args) {
// Ошибка: нельзя присвоить в Order значение типа CustomerRequest, они никак не связаны через наследование
Order o3 = new CustomerRequest();
}
}


🚀 Структурная типизация

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

type Order = { id: string };
type CustomerRequest = { id: string };

Function handleOrder(order: Order) {…};

сonst customerRequest: CustomerRequest = { id: ‘abc’ };

// ок, потому что структура двух типов совпадает
handleOrder(customerRequest);

Typenoscript-у не важно, что тип по-другому называется - ему главное, что нужные поля имеются. Это может подкинуть вам такой неприятный сюрприз:

type Phone = string;
type Email = string;

function sendSms(phone: Phone) {...}
const email: Email = 'test@mail.ru';

sendSms(email); // oк, потому что структура одна и та же, оба типа - строки


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

#typenoscript
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12💩8🤮6👍43👎2😁1🖕1
🐆Как научиться решать алгоритмические задачи, если вы совсем не умеете

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

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

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

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

#алгоритмы
Please open Telegram to view this post
VIEW IN TELEGRAM
23🤮8👍7💯5👎3💩3❤‍🔥2🔥2🥰2🖕1
💥 Как React рендерит UI. Часть 1

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

📎 Рендеринг UI в React состоит из двух фаз: render и commit.

📌 Render фаза

Во время render фазы React вызывает функции компонентов. Ваши компоненты — это же обычные javanoscript функции, верно? Вот React эти функции и вызывает с переданными аргументами. В результате получается новый VDOM. После этого React React сравнивает старый VDOM с новым (этот процесс называется reconciliation) и определяет, какие изменения нужно внести (какие узлы добавить, какие узлы удалить и т.д.)

📌 Commit фаза

React вносит изменения в реальный DOM при помощи js методов вроде appendChild, removeChild и т.п. Но это не приводит к их немедленному отображению на экране — js однопоточный и этот поток занят выполнением js кода 🙂. После внесения изменения в DOM выполняются layout эффекты (useLayoutEffect). Они уже могут использовать реальный DOM (например, для вычисления размеров элементов) и вносить в него правки. Только после этого браузер отрисовывает новый UI на экране, после чего выполняются эффекты useEffect.

Рассмотрим пример и разберемся по шагам, что здесь происходит:

function App() {
useLayoutEffect(() => console.log('useLayoutEffect'));
useEffect(() => console.log('useEffect'));
console.log('render');
return <div>hello world</div>;
}


В этом примере:

*️⃣Render фаза

1️⃣Вызывается функция App. Вычисляется VDOM и изменения, которые нужно закоммитить в реальный DOM. Мы увидим лог “render”, потому что функция App была вызвана.

*️⃣Commit фаза

2️⃣ React обновляет реальный DOM
3️⃣ Выполняется useLayoutEffect. Мы увидим лог “useLayoutEffect”
4️⃣ Изменения отобразятся на экране, и пользователь увидит Hello world.
5️⃣ Выполнится useEffect, и мы увидим лог “useEffect”

В следующих постах посмотрим, как изменится этот флоу, если эффекты вносят изменения в DOM или состояние.

#react
Please open Telegram to view this post
VIEW IN TELEGRAM
128🔥10🤮6💩3👎2💘2
💥 Как React рендерит UI. Часть 2

В прошлой серии мы поговорили с вами о том, что рендеринг в React состоит из двух фаз — render и commit. В render фазе вычисляются новые VDOM и Fiber tree, в commit фазе сначала обновляется DOM, затем выполняются useLayoutEffect, после чего следует отрисовка и, наконец, выполняются useEffect.
Сегодня мы рассмотрим useLayoutEffect подробнее.

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

// index.css

.rect { width: 300px; height: 200px; background: grey; }

// App.tsx

export default function App() {
const rect = useRef<HTMLDivElement | null>(null);
useLayoutEffect(() => {
if (!rect.current) return;
rect.current.style.backgroundColor = "pink";
}, []);

return <div className="rect" ref={rect}></div>;
}


Это происходит за счет того, что useLayoutEffect выполняется перед отрисовкой. Браузер построил DOM с серым прямоугольником, затем выполнил js код с useLayoutEffect, в котором содержится смена цвета. После этого браузер внес изменения в DOM и затем наконец отрисовал интерфейс.

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

function sleep() {
const start = Date.now();
while (Date.now() - start < 2000) {}
}

export default function App() {
const [color, setColor] = useState("gray");

useLayoutEffect(() => {
sleep(); // спим 2 секунды
setColor("pink");
console.log(color); // серый - обновление произойдет перед следующим рендером
}, []);

return (
<div
style={{
width: "300px",
height: "200px",
background: color,
}}
></div>
);
}


Ответ на этот вопрос я напишу позже, а пока вы можете делиться вашими догадками в комментариях :)

#react
🔥1511🤮6👍3👎2💩2
Какой прямоугольник пользователь увидит сначала в задаче выше?
Anonymous Poll
53%
серый
47%
❤️розовый
🔥6🤮65👍3👎3💩3
💥 Как React рендерит UI. Часть 3

Мнения разделились. Правы оказались те, кто выбрал романтичный розовый цвет 💗 (пруф). Но подождите… ведь переменная состояния обновляется только в следующем рендере, верно?

Так и есть. При вызове setState внутри useLayoutEffect React прерывает текущую commit фазу и сразу запускает новую render фазу. Таким образом, после первого рендера пользователь ничего не увидит — до стадии отрисовки React не дошел. А вот после второго увидит розовый прямоугольник 🌸

В следующей серии поговорим о том, что будет, если в дело вступит useEffect💫

#react
Please open Telegram to view this post
VIEW IN TELEGRAM
19👍10🔥7👎4🤯4🤮2🤡1
💥 Как React рендерит UI. Часть 4

В прошлый раз мы с вами убедились в том, что useLayoutEffect действительно блокирует рендер. Если в useLayoutEffect есть “тяжелый” код (в нашем примере это была задержка в две секунды), то интерфейс зависнет, а затем покажет обновленный UI — с правками, внесенными в useLayoutEffect.

Ок, а что насчет useEffect? Мы знаем, что он выполняется после отрисовки. Как думаете, код ниже зависнет на 2 секунды прежде чем отобразить прямоугольник на экране или нет?

function sleep() {
const start = Date.now();
while (Date.now() - start < 2000) {}
}

export default function App() {
const [color, setColor] = useState("gray");

useLayoutEffect(() => { setColor("pink"); }, []);

useEffect(() => { sleep(); // спим 2 секунды }, []);

return (
<div
style={{
width: "300px",
height: "200px",
background: color,
}}
></div>
);
}

#react
🤡10🔥6🥰53👎3💩3👍1
Зависнет ли UI на 2 секунды в примере выше?☝️
Anonymous Poll
27%
Зависнет☹️
73%
Не зависнет 😊
💩9👍8🤡64👎2🤮1
💥 Как React рендерит UI. Часть 5

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

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

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

Even in cases where useEffect is deferred until after the browser has painted, it’s guaranteed to fire before any new renders. React will always flush a previous render’s effects before starting a new update.


Именно поэтому в нашем примере после useLayoutEffect React вызывает useEffect. В нашем случае useEffect содержит блокирующую операцию, поэтому интерфейс подвиснет. Затем React доходит до ререндера, и только после этого UI мы наконец увидим наш UI на экране🌸


#react
🔥11👍8🤮8😱5💩432👎2🫡2🤨1💘1
💥 Как React рендерит UI. Часть 6

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

function sleep() {
const start = Date.now();
while (Date.now() - start < 2000) {}
}

function App() {
useEffect(() => {
sleep(); // спим 2 секунды
}, []);

return (
<div
style={{
width: '300px',
height: '200px',
background: 'pink',
}}
></div>
);
}


#react
🤮11👍107💩4👎3🔥3
Когда я в 2017 году стажировалась в ЦФТ, нам рассказывали про одного парня, которому нужно было сделать класс для вычисления скидок, и он назвал его Skidon. Его так и прозвали — Дима Скидон. Сейчас на рынке работодателя вы просто не найдёте работу с таким кодом.

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

Если хотите подтянуть язык, с этим помогут в онлайн-школе разговорного английского Authentic Pigeon

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

Абсолютно кайфую от подхода ребят. Занятия тут это не потогонка, а крутой дружеский разговор.

Студент школы — Иван

Узнать подробнее о занятиях и записаться на бесплатный демо-урок

Реклама. Моисеева Анастасия Андреевна, ИНН 270393875959. Erid: 2VtzqwUv25N
Please open Telegram to view this post
VIEW IN TELEGRAM
💩139👎6🥰5🤡5👍3🥱2🗿1
Forwarded from ··• Серёжа печатает (Серёжа)
Долго грел мысль про карьерные советы. И я понял, что у меня есть очень много чего сказать или помочь, если вы хотите развиваться в рамках своих компетенций и расти как специалист, а также искать смежные области. Но вот если вы хотите поменять или найти работу, то мне нечего вам сказать или предложить, кроме нескольких пунктов и напутствий.

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

Второе. Если у вас нет огромного количества накоплений и вы не можете позволить себе уйти на год на ретрит — не уходите с текущего места работы, пока у вас нет гарантированного, насколько это возможно, оффера с другого места. Потому что стратегия «быстро найду новое место», скорее всего, не сработает. При этом не соглашайтесь на офферы с выходом через 1–2 месяца. Сейчас в компаниях настолько сильно все меняется, что за 2 месяца ваш оффер просто может протухнуть или его оптимизируют.

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

Четвертое. Главный навык для поиска работы — усердие. Надо делать очень много откликов, которые будут игнорироваться, много писать, много смотреть и искать. Это требует большого внимания, фокуса. Это требует уметь не сдаваться и терпеть до конца. Но усердие также нужно и в подготовке. Помните, что получить приглашение на собеседование — это половина проблемы. У вас конкуренция на вакансию высокая, а значит, требования к вам на собеседовании выше, чтобы пройти, поэтому не брезгуйте подготовкой. В интернете кучу видео собесов, кучу материалов, есть GPT и прочее. Не брезгуйте подготовкой, даже если вы считаете, что вы суперэксперт. Усердие также важно потому, что цикл поиска сейчас может составлять 3–4 месяца, а это долго. Я искал работу месяц, и за месяц меня высушило.

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

Напомню, что в это воскресенье я буду пробовать говорить с кем-то на тему развития и отговаривать кого-то от поиска работы. Чем ещё помочь с поиском, я просто не знаю.
11👍9💩7💯3👎2🤮2🤯1