<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Kirill Valitskii</title><generator>teletype.in</generator><description><![CDATA[SWE, 22 yrs old.]]></description><link>https://teletype.in/@cybeaster?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/cybeaster?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/cybeaster?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Tue, 21 Apr 2026 01:59:05 GMT</pubDate><lastBuildDate>Tue, 21 Apr 2026 01:59:05 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@cybeaster/ue_roadmap_p1</guid><link>https://teletype.in/@cybeaster/ue_roadmap_p1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster</link><comments>https://teletype.in/@cybeaster/ue_roadmap_p1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster#comments</comments><dc:creator>cybeaster</dc:creator><title>Roadmap Unreal Engine / C++ developer</title><pubDate>Sun, 28 Jan 2024 07:17:21 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/bd/7d/bd7d504a-e07c-4c5e-a04b-f4cfc3cb87d1.png"></media:content><category>GameDev</category><description><![CDATA[<img src="https://img4.teletype.in/files/f2/b7/f2b733f8-e350-478c-a3b1-62c662230fb7.jpeg"></img>Unreal Engine для начинающих.]]></description><content:encoded><![CDATA[
  <p id="jPWR"><br />Прежде чем начать перечислять технологии, давайте для начала определим, кто решил подойти к этому моменту:</p>
  <ul id="r2KN">
    <li id="B1Aq">Программист из геймдева, Godot, Unity и т.д.</li>
    <li id="qn00">Программист, меняющий стэк из другой области, не геймдев.</li>
    <li id="yrbJ">Начинающий программист без какого либо опыта, в том числе с языками программирования.</li>
  </ul>
  <p id="cOoC">Во всех трех случаях подход будет разный, однако, основные моменты будут такими же. </p>
  <p id="VSGH">Важно понимать, что внутри позиции Unreal Engine / C++ Developer скрыто множество под-областей. </p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="9odp">Вы можете:</p>
    <ul id="trdN">
      <li id="3HfW">Заниматься UI&#x27;ем, изредка касаясь написанием кода. </li>
      <li id="lsgH">Писать/дописывать инструментарий для других разработчиков.</li>
      <li id="4GnI">Программировать мультиплеерную логику или клиентскую для общения с сервером.</li>
    </ul>
  </section>
  <p id="nujs">И это далеко не полный список. Можно включить физику, звуки, и даже рендер. </p>
  <p id="uW9D">В разных командах вы можете встретить разные подходы к делению обязанностей среди программистов.</p>
  <p id="Pl4c">В моей компании часто приходиться заниматься всеми перечисленными пунктами.</p>
  <hr />
  <p id="Tu0t">Ниже я сначала опишу, как каждому типу людей стоит подходить к изучению топика, и далее уже укажу конкретные вещи, которые спрашивают на собеседованиях и полезные ресурсы.</p>
  <p id="90tO">Помимо прочего, я крайней рекомендую всем уделять внимание общедоступным проектам, из которых вы можете подчерпнуть best-practice&#x27;ы. </p>
  <p id="KoJv">Их можно найти или на гитхабе, или на маркетплейсе Epic Games. </p>
  <hr />
  <h2 id="3GUf">Неопытный</h2>
  <p id="QzNw">Вы не знакомы с языками программирования и не знаете, что представляет собой Unreal Engine.</p>
  <p id="LN5j">Вам я исключительно советую прибегнуть к курсам и/или видео на ютубе, где с нуля пишут какой-то микро проект.</p>
  <p id="cEhB">В вашем случае желательно подойти в первую очередь со стороны Blueprints, т.е скриптовым визуальным языком программирования. Он даст вам базовое понимание работы Actor&#x27;ов, Component&#x27;ов, сцены и т.д.</p>
  <p id="EV78">После освоения базы, можно пытаться переносить код на C++, параллельно вникая в устройство этого языка программирования.</p>
  <p id="CYl3">Важно отметить, что в контексте скриптовки игровой логики для движка вам потребуется лишь небольшая часть этого языка. Поэтому так же советую смотреть гайды по нему в контексте Unreal Engine, чтобы не обнаружить себя на  cppreference.com, вникающим в какой нибудь локальный <a href="https://en.cppreference.com/w/cpp/string/basic_string" target="_blank">ужас</a>, который вас вероятнее всего отпугнет.</p>
  <p id="NEUA">Лично я начинал с <a href="https://www.udemy.com/course/unrealcourse/" target="_blank">курса на Udemy</a> и <a href="https://youtu.be/DywBqQtTHMo?si=iZ1irDQGsiIOt9FB" target="_blank">небольшого шутера на ютубе</a>.</p>
  <p id="f3h2">В процессе создания пет-проекта стоит вносить некоторые правки в предлагаемый код. Придумывать и изменять логику игры, чтобы лучше разобраться в механике работы движка и его сущностей.</p>
  <p id="kEN3">Также, важно избегать типичных ошибок новичков: <strong>пытаться понять все и сразу</strong>. Если вам совсем не очевидно как работают Line Trace&#x27;ы или Behaviour Tree, и вы несколько часов копаетесь в исходниках или гайдах, стопаря процесс создания игры, то так не долго и выгореть.</p>
  <p id="BCm3">Крайне советую оборачивать слишком непонятные вещи в абстрактные <em><strong>Кидает луч</strong></em>, или <em><strong>Выполняет действия по порядку с условиями</strong></em>, чтобы потом к ним вернуться и уже на базе написанного проекта с ними экспериментировать.</p>
  <p id="KueZ">Как только освоите базовые понятия, указанные, например, в курсе на Udemy и напишете свой проект, можете начинать искать работу для собора фидбека, или устроиться в стартап на бесплатную основу, чтобы получать хоть какой-нибудь опыт.</p>
  <hr />
  <h2 id="ol4h">Бывалый, не геймдев.</h2>
  <p id="JYFa">Для вас главной проблемой станет иерархия типов и структур в движке, и сама механика работы real-time движков. </p>
  <p id="5Kng">Вы можете приступать сразу к языку и его основам. После - писать свой проект на базе того же <a href="https://www.udemy.com/course/unrealcourse/" target="_blank">курса на Udemy.</a></p>
  <p id="D72n">Поскольку для вас главной проблемой будут абстракции, которые предоставляет движок, и архитектура, я так же рекомендую почаще читать исходники движка, хотя бы на самом высоком уровне, и <strong>чужие проекты, </strong>чтобы схватывать паттерны работы и лучшие практики, которые использовали сами создатели движка и другие программисты.</p>
  <p id="VZBN">В остальном все так же как и у начинающего: пишете свой первый проект на C++, и с ним можете идти на собеседования.</p>
  <hr />
  <h2 id="RMdZ">Бывалый, геймдев.</h2>
  <p id="6wsR">Советы тут будут похожи на предыдущий пункт, за тем исключением, что поскольку вы знакомы с общей абстракцией в виде Actor&#x27;ов, миров, уровней и компонентов, вам стоит в первую очередь ознакомиться с разницей в функциональностях движка, и тем, как с ними работать.</p>
  <p id="m9r1">Советую все так же начать писать свой проект, но уже сильно больше внимания обращать на другие проекты, т.к вы найдете много пересечений с другими движками. Возможно даже вам не понадобится курс. Можете сразу скачать готовый проект и разбираться в нем.</p>
  <hr />
  <h2 id="xDtl">Цели</h2>
  <p id="PDbD">Ниже приведен список компонентов и ключевых сущностей движка, порядочное изучение которых и составит своеобразную Road map&#x27;у.</p>
  <p id="BdZV">Тип деления на абстракции я выбрал произвольно, так, как посчитал нужным на основании своего опыта.</p>
  <hr />
  <h3 id="7sxV">Акторы</h3>
  <p id="RYnu">Самый простой компонент движка, который можно поставить на сцену: <code>AActor</code> и его производные: <code>APawn</code> и <code>ACharacter</code>. Нужно понять их схожести и различия. Как они работают с компонентами и репликацией. </p>
  <p id="k8cl">Плюс, уяснить разницу с <code>UObject</code>, помимо того, что его можно поставить на сцену и напрямую уничтожить.</p>
  <hr />
  <h3 id="dJti">Компоненты</h3>
  <p id="u7Zn">Компоненты являются строительными блоками для всех актеров. Нужно уяснить как они инициализируются, как уничтожаются и реплицируются. Так же у него есть свои наследники, каждый из которых реализует конкретную функциональность: <code>USceneComponent</code> и <strong><code>UPrimitiveComponent</code>. </strong>Они являются базовыми классами для большинства компонентов. Их необходимо разобрать.</p>
  <p id="UhSq">Важно во время изучения испробовать разных их наследников, вроде <code>USkeletalMeshComponent</code> или <code>UWidgetComponent</code>, чтобы изучить область применения.</p>
  <h3 id="390S">Управляющие сущности</h3>
  <p id="P8dv"><code>APlayerController</code>, <code>APlayerState</code>, <code>AGameMode</code>, <code>AGameState UGameInstance</code>. Все это базовые игровые сущности, которые необходимо понимать. Их время жизни, работа с репликацией, область применения и смысл существования.</p>
  <hr />
  <h3 id="UBK8">События</h3>
  <p id="jcrI">Следующим по важности следуют <code>FDelegate</code> и <code>FEvent</code>.</p>
  <p id="Pa0I">Они, по сути, представляют из себя сущность, на которую вы подписываетесь и ждете когда что-то произойдет (<code>Execute</code> или <code>Broadcast</code>). Кроме того есть <code>Multicast Delegate</code>&#x27;ы, <code>Dynamic Delegate</code>&#x27;ы и т.д с разными переменными параметрами.</p>
  <p id="ZMBH">Необходимо поэксперементировать с разными их вариациям для фиксации разных событий при входе в Collision Box&#x27;ы, нажатие на мышь/клавиатуру и т.д.</p>
  <p id="gblH">Они создаются через <code>DECLARE_EVENT</code>и <code>DECLARE_DELEGATE</code>.</p>
  <hr />
  <h3 id="44D5">Мир</h3>
  <p id="4f5t">Советую вам уделить отдельное внимание таким вещам как <code>ULevel</code>и <code>UWorld</code>. Как они вместе составляют игровое поле, как работать с их Blueprint&#x27;ом, классом, и что происходит когда вы переходите с уровня на уровень <code>(UGameplayStatics::OpenLevel).</code></p>
  <hr />
  <h3 id="zA4o">Базовые классы</h3>
  <p id="j9NX">Вам необходимо усвоить, что из себя представляет основной класс для всех сущностей движка <code>UObject</code> и <code>UObjectBase</code>. Как при помощи него работает сборщик мусора и, немало важно, как этот класс может работать с репликацией, т.е мультиплеером.</p>
  <hr />
  <h3 id="yAKy">Коллизии</h3>
  <p id="nAEe">Поскольку вам часто понадобится фиксировать коллизии, то нужно поработать с разными их проявляениям.</p>
  <ol id="gGLx">
    <li id="Z2vV">На уровне компонентов и Actor&#x27;ов: каждый <code>UPrimitiveComponent </code>может работать с коллизиями и детектить их, например <code>OnComponentHit</code><strong>, </strong><code>OnComponentBeginOverlap </code><strong>и </strong><code>OnComponentEndOverlap.</code></li>
    <li id="qBNZ">На уровне кастов: вы можете создавать разные геометрически объекты (Лучи, Сферы и т.д) для фиксации тех или иных сущностей (геометрии). <code>LineTraceSingleByChannel</code>, <code>OverlapMultiByChannel </code>и т.д</li>
  </ol>
  <p id="8uHK">Они используются постоянно и являются частью физического движка.</p>
  <hr />
  <h3 id="p42D">Контейнеры</h3>
  <p id="VAUJ"><code>TMap</code>, <code>TSet</code>, <code>TArray</code>, <code>TList</code> и т.д. Чем отличаются, чем схожи, в том числе с <code>std::unordered_map</code>, <code>std::map</code> и прочими. </p>
  <p id="1ofW">На более глубоком уровне советую почитать про <code>TSparseArray.</code></p>
  <hr />
  <h3 id="P0fS">Рефлексия</h3>
  <p id="UUo6"><s>Стоит подумать о жизни и смысле существования.</s></p>
  <p id="r902">До этого момента вы вероятнее всего уже сталкивались с <code>UCLASS</code>, <code>USTRUCT</code>, <code>UENUM </code>и т.д.</p>
  <p id="cm32">Часто интервьеру, может быть интересно как вы понимаете рефлексию, т.е инструмент, который позволяет анализировать ваш код и генерировать еще больше инструкция для движка.</p>
  <p id="h5If">Те же свойства, прописываемые в <code>UPROPERTY</code> и <code>UCLASS</code>, вроде <code>BlueprintReadOnly</code> являются теми самыми ключевыми словами, по которым создаются дополнительные инструкции для движка.</p>
  <hr />
  <h3 id="KRxA">Сборщик мусора и smart pointer&#x27;ы</h3>
  <p id="dimN">Концепция эта не нова, однако часто интервьеру может быть интересно в чем вы видите различия <code>std::weak_ptr</code> и <code>TWeakPtr</code> из движка и как они работают со сборщиком мусора. Как последний ведет учет объектов, которые надо уничтожить, можно ли создать <code>TSharedPtr</code> на <code>UObject</code> и т.д.</p>
  <p id="JvaZ">Тут придется окунуться в стандарт C++ и часть изучить. </p>
  <hr />
  <h3 id="QBRr">Репликация</h3>
  <p id="Wh3A">Не все проекты включают мультиплеерную часть, но на собеседовании часто спрашивают.</p>
  <p id="lnbu">Концепция сервера и клиента, RPC вызовы (Server, Client, Multicast), условия репликации переменных и т.д. </p>
  <p id="F61A">Все это <strong>важно</strong> осмыслить хотя бы на поверхностном уровне.</p>
  <p id="FWcf">У меня уже есть <a href="https://habr.com/ru/articles/647521/" target="_blank">статья</a>, с которой очень советую ознакомиться.</p>
  <h3 id="OUMi">Сессии</h3>
  <p id="OMdb">Этот топик - часть мультиплеера, но все же стоит отдельно из-за своей специфики: создание <a href="https://habr.com/ru/articles/647521/" target="_blank">сессии</a>. Является скорее приятным дополнением, нежели необходимостью.</p>
  <hr />
  <h3 id="6AIt">Build Tool и модули</h3>
  <p id="dVq4">Весь движок состоит из модулей, конфигурации которых прописываются в корневых директориях ваших исходников в файлах <code>.build.cs.</code></p>
  <p id="krPk">Важно знать, как их прописывать, чем приватный модуль отличается от публичного и так далее. </p>
  <p id="4C2k">Этот топик более узкий и спрашивают его не часто.</p>
  <hr />
  <h3 id="mKMt">Софт и хард ссылки. <code>TSoftObjectPtr</code>, <code>TStrongObjectPtr</code></h3>
  <p id="TW1O">Уже более специфическая вещь, связанная с загрузкой и сохранением объектов в памяти. </p>
  <p id="Z98b">Нередко интервьюеру интересно, как вы понимаете возможности движка для менеджмента ресурсов, особенно если память устройства сильно ограничена. </p>
  <hr />
  <h2 id="mMD4">Заключение</h2>
  <p id="QPEJ">Список выше далеко не самый полный и весьма абстрактный. Каждый из пунктов можно поделить на несколько частей и добавить деталей, однако тогда и статья вылилась бы в учебник.</p>
  <p id="OVQa">С большинством пунктов вы столкнетесь пока будете писать pet-проект, какие-то из них будете нагонять после, т.к не в каждом проекте задеваются все перечисленные концепции.</p>
  <p id="mePR">Только то, что указано, является необходимой базой (кроме <em>Сессий</em>), в которой важно глубоко разобраться.</p>
  <hr />
  <h2 id="L3OU">Полезные ресурсы</h2>
  <ul id="xFU3">
    <li id="liuh"><a href="https://docs.unrealengine.com/5.3/en-US/" target="_blank">Официальная документация</a></li>
    <li id="ydPP">Документация сообщества:</li>
    <ul id="A7B0">
      <li id="yBOw"><a href="https://benui.ca/unreal/" target="_blank">https://benui.ca/unreal/</a></li>
      <li id="VyPm"><a href="https://ikrima.dev/ue4guide/" target="_blank">https://ikrima.dev/ue4guide/</a></li>
      <li id="kS7h"><a href="https://vorixo.github.io/devtricks/" target="_blank">https://vorixo.github.io/devtricks/</a></li>
      <li id="jPtc"><a href="https://unrealcommunity.wiki/" target="_blank">https://unrealcommunity.wiki/</a></li>
    </ul>
    <li id="1etU"><a href="https://habr.com/ru/users/Cybeaster/publications/articles/" target="_blank">Мой цикл статей по Unreal Engine.</a></li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@cybeaster/nvidia_pge_fail</guid><link>https://teletype.in/@cybeaster/nvidia_pge_fail?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster</link><comments>https://teletype.in/@cybeaster/nvidia_pge_fail?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster#comments</comments><dc:creator>cybeaster</dc:creator><title>Интервью в Nvidia.</title><pubDate>Fri, 12 Jan 2024 17:47:31 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/91/08/91089b30-fd32-4a56-8345-ab71955115d2.png"></media:content><category>interview</category><description><![CDATA[<img src="https://img4.teletype.in/files/f6/75/f675f77d-0035-4eb4-9ec2-f08e79b1ee60.png"></img>Как зеленый гигант делал мне больно.]]></description><content:encoded><![CDATA[
  <h2 id="PSye">Введение</h2>
  <p id="cG0I">Собеседование в Nvidia я проходил на позицию Platform Graphics Engineer в ноябре прошлого года.</p>
  <p id="h6TK">Судя из описания вакансии менеджером, мне предстояло бы заниматься оптимизацией стриминга <strong>GeforceNOW</strong>, внося правки в игровые движки, которые предоставляют вендоры.</p>
  <p id="XdIu">Подавался я на сайте <strong>Nvidia Careers</strong> без рефералки, ответ пришел в течение пары недель, что весьма быстро.</p>
  <p id="54rU">На позицию требовались знания графических <strong>API</strong>, устройства <strong>CPU/GPU</strong>. Кроме того желателен опыт с игровыми движками, в особенности <strong>Unreal Engine</strong>.</p>
  <p id="Fp35">Я на тот момент не был силен в графике, но менеджер успокоил, сказав, что будет возможность наверстать.</p>
  <p id="1bQQ">Стоит отметить, что по моим наблюдениям в крупных компаниях первый же созвон состоится с техническим менеджером, который расскажет про вакансию и проведет скрининг. Поэтому ваши заготовленные вопросы HR&#x27;ам почему вы заинтересовались компанией <em>&lt;&lt;Рога и Копыта&gt;&gt;</em> вам не понадобятся. </p>
  <p id="kZWI">В моем случае, спрашивали азы об устройстве GPU, попросили набросать кода на С++, который профайлит обычный цикл for.</p>
  <p id="uPNH">Далее мне было назначено аж 4 часовых интервью в разные дни по схеме ниже, поэтому особой нагрузки я не почувстовал. Вместе с письмом были приложены ссылки на hackerrank, посему стало понятно - <strong>будет литкод</strong>.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="rlM7" data-align="center">1 - четверг <br />2 - пятница, утро и вечер.<br />1 -  в понедельник.</p>
  </section>
  <hr />
  <h2 id="0xfa">Собеседования</h2>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="MfMk" data-align="center">Четверг.</p>
  </section>
  <p id="bWiP">После небольшого интродакшена мне сразу дали рандомную задачку из пула на сайте. Там оказалась задача на интервалы медиум уровня, которую я решал раз 100. Проблем абсолютно не возникло, а даже если я где-то что-то забывал, интервьюер любезно, почти сразу, мне на это указывал.<br />Оставшюуся часть интервью мне показывали графики производительности и просили проанализировать узкие горлышки в программе, где и почему, как я думаю, игра тормозит. Там я тоже нашел что рассказать так как был знаком с подобными процессами после курса по CUDA.</p>
  <hr />
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="zaiJ" data-align="center">Пятница, утро.</p>
  </section>
  <p id="LleO">Так же интро, и простые вопросы по графике, пайплайны, и что, например, делает шейдер тесcеляции. После последовали вопросы easy и medium уровня - связные списки и деревья. На второй задаче я споткнулся, т.к. перенервничал и долбился в одно и тоже не правильное решение. </p>
  <p id="c3mG">В принципе, ничего сложного не было. Вторую задачу я уже решал, поэтому смог выложить хотя бы часть решения интервьюеру.</p>
  <hr />
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="maBL" data-align="center">Пятница, вечер.</p>
  </section>
  <p id="TIRM">Интро, и сразу hackerrank. Там, на удивление, не было литкода, вместо него попросили распарсить CSV-файл и посчитать частоту кадров с разными условиями ссылаясь на данные. Я набросал простой парсер на питоне, и интервьюера это вполне устроило, если конечно не считать того, что я минут 10-15 распрашивал про условие задачи, и что конкретно дано в CSV-файле.</p>
  <hr />
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Bh0f" data-align="center">Понедельник, вечер.</p>
  </section>
  <p id="wJhq">Достаточно продолжительное интро, где интервьюер копал в те задачи на оптимизацию, которыми я занимался, и далее один литкод вопрос на графы medium уровня.</p>
  <hr />
  <h2 id="zixf">Результат</h2>
  <p id="1Ykn">После всех интервью я был уверен процентов на 70 что я их прошел. Вопросы были не сложные, касались они оптимизации, с которой я уже работал. Литкода я к тому моменту нарешал в районе 230 задач, поэтому размышления были как нельзя правильными (если не считать небольшой фейл на 2-ом интервью), плюс я каждый раз в конце интервью интересовался, доволен ли интервьюер моими размышлениями, и ни разу не получал отрицательного ответа.</p>
  <p id="cy35"><em>Хотя, быть может, меня обманули...</em></p>
  <hr />
  <p id="rr4y">Ответ я ждал мучительные 4 дня. Каждый день все больше и больше сомневаясь в том, что на любимую вакансию я прохожу.</p>
  <p id="icfw">Ответ пришел - <strong>отказ</strong>. </p>
  <p id="rJqS">Почему, чего не хватает, и где я накосячил, мне не объяснили, а следующее письмо с проcьбой об оном - проигнорировали, обойдясь: </p>
  <blockquote id="uaUT">We have found someone who better fits the position. </blockquote>
  <hr />
  <h2 id="0XQw">Выводы</h2>
  <p id="Vchl"><strong>Никогда не бойтесь ходить на интервью в крупные компании</strong>. Они бывают разного уровня сложности, но чаще всего это easy-medium задачи и детали из вашей конкретной области, которые вы встретите повсюду.</p>
  <p id="ckpB"><strong>Никогда не питайте ложных надежд</strong>, даже когда лично вам кажется, что все прошло идеально. </p>
  <p id="7lp3">Я был сильно разочарован из-за недостатка опыта в прохождении собеседований в такие компании. Чаще всего если легко себя чувствовал, то оффер не заставлял долго ждать.</p>
  <p id="J9yc">Вероятнее всего, мне отказали не потому, что я плохо показал себя, а потому, что пришел человек, который знает DX12 или Vulkan. И даже если он хуже меня решил литкод, он все еще остается более подходящим кандидатом.</p>
  <p id="aPBg">Удачи!<br /></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@cybeaster/algo_guide</guid><link>https://teletype.in/@cybeaster/algo_guide?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster</link><comments>https://teletype.in/@cybeaster/algo_guide?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster#comments</comments><dc:creator>cybeaster</dc:creator><title>Алгоритмы и структуры данных</title><pubDate>Thu, 28 Dec 2023 17:11:12 GMT</pubDate><category>Algorithms</category><description><![CDATA[<img src="https://img3.teletype.in/files/e5/41/e541ed56-53ac-49d6-b9b5-b41be0de0962.png"></img>К текущему моменту я решил 250+ задач на алгоритмы и прошел несколько собеседований.]]></description><content:encoded><![CDATA[
  <p id="ix1U">К текущему моменту я решил 250+ задач на алгоритмы и прошел несколько собеседований.</p>
  <p id="FV01">В этой статье я хочу раскрыть тему алгоритмов как являения и разобрать процесс решения на составляющие, плюс показать почему именно <strong>ТЫ </strong>сможешь в них преуспеть, и медленно перейти к оным на собеседованиях.</p>
  <hr />
  <h2 id="7lUP">Зачем решать задачи на алгоритмы?</h2>
  <p id="TAne">Споры о нужде алгоритмов не утихают до сих пор. </p>
  <p id="KtVR">Одни с пеной у рта доказывают, что на работе в них нет никакого смысла, другие топят за улучшение <strong>алгоритмического мышления</strong> в решении вымышленных задач.</p>
  <p id="OP0N"> В действительности, решая алгоритмы, мы делаем следующее:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <ol id="fOoj">
      <li id="HjZw">Декомпозируем / Упрощаем проблему.</li>
      <li id="fdVv">Анализируем, подбираем паттерны для чернового решения.</li>
      <li id="sDzW">Создаем решение на тестовых данных.</li>
      <li id="Ytaf">Пишем код.</li>
      <li id="RMWI">Фиксим баги.</li>
      <li id="8u7w">Оптимизируем наше решение.</li>
      <li id="lisc">Повторяем шаг 4-6 пока не уложимся в требования задачи.</li>
    </ol>
  </section>
  <p id="LLzs">И часто ли вам на работе приходилось выполнять больше двух-трех пунктов из этого списка? Часто ли вы встречались с проблемами, для которых необходим долгий, вдумчивый анализ для составления сложного алгоритмически эффективного решения?</p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="cvlt"><strong>Итог. </strong>Если вам не нужно готовиться к алгоритмическим интервью и на работе не приходится писать ПО с нетривиальными алгоритмическими задачами, то нарешивать задачки вам явно не нужно.</p>
  </section>
  <hr />
  <h2 id="pQZn">Пример из жизни</h2>
  <p id="VCs8">Однако, это не значит, что знание основ вам никогда не понадобится. Пример из моей работы:</p>
  <p id="Qfee">Язык: C++.</p>
  <p id="PcpA">Дан массив каких то структур. Необходимо вызывать определенную функцию у каждого элемента этой структуры, после чего массив почистить. Код будет выглядеть примерно так:</p>
  <pre id="lFRb" data-lang="cpp">container&lt;Type&gt; elems;
...
for (auto&amp; elem : elems)
{
	elem-&gt;Finalize();
}
elems.clear();</pre>
  <p id="jliQ"><em>Проблема заключается в том, что метод <code>Finalize()</code> может удалить элемент из <code>elems</code> при определенных условиях</em>, и мы получим краш на изменении размера массива в <code>range-based&#x60;</code> цикле.</p>
  <pre id="nMf3" data-lang="cpp">container&lt;Types&gt; elems;
...
void Type::Finalize()
{
	...
	if(...)
	{
		elems.remove(this);
	}
}</pre>
  <p id="Z8wu">Простой подход для решения проблемы - <strong>скопировать исходный массив в другой</strong>, и пройтись по элементам копии.</p>
  <p id="vijC">На мой взгляд это неэффективно и некрасиво. Без опыта решения задач я бы так и поступил.<br />В итоге, лаконичное решение пришло через некоторое время:</p>
  <pre id="gyVR" data-lang="cpp">container&lt;Type&gt; elems;
...
while (!elems.is_empty())
{
	auto elem = elems.pop();
	elem-&gt;Finalize()
}</pre>
  <p id="DXBP">Вам может показаться этот пример <strong>глупым </strong>и <strong>очень простым</strong>. По сути так и есть, однако...</p>
  <p id="csRa">Матерые, опытные синьеры на моем проекте <strong>копировали массив.</strong><br />Значит ли это, что <em>решение не так очевидно</em>...?</p>
  <p id="Pt2B">И это с учетом того, что алгоритмически сложные задачи у нас бывают очень редко.</p>
  <hr />
  <h2 id="mHOB">Почему именно ты сможешь подготовиться к интервью</h2>
  <p id="YQay">Когда я несколько месяцев назад впервые начал решать задачи, то обомлел от разнообразия и  сложности этих задач. Казалось, что для подготовки нарешивать их нужно <strong>бесконечно</strong>.</p>
  <p id="N74P">Кроме того, единственное, что я читал это <em>Грокаем Алгоритмы от Бхаргава А</em>. Поэтому никакой академической подготовки у меня нет.</p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="5vnT">Правда заключается в том, что это разнообразие и сложность конечны, и чем <strong>больше вы нарешаете задач</strong>, тем больше <strong>паттернов вы будете знать</strong>, тем больше возможных <strong>комбинаций из паттернов</strong> сможете собрать и тем меньше очередная новая задача будет вас удивлять.</p>
  </section>
  <p id="NYSb">У меня, спустя 250 задач, при открытии очередной medium - hard задачи сразу всплывают знакомые паттерны, на которых строится та или иная задача.</p>
  <hr />
  <h2 id="rt9H">Паттерны</h2>
  <p id="kEEs">Давайте на конкретных примерах.</p>
  <p id="8NBt">Возьмем две на первый взгляд никак не связанные задачи: <a href="https://leetcode.com/problems/lru-cache/description/" target="_blank">LRU Cache </a>и <a href="https://leetcode.com/problems/two-sum/description/" target="_blank">Two Sum</a>.</p>
  <p id="CHvU">Поначалу, у новичка образуется каша в голове и он не знает как к задаче подступиться. Вместо размышлений, составления каких либо тестов сразу бросается писать какой-то код, стремясь избавиться от тотального непонимания и нагнетаемого страха.</p>
  <p id="HH9a">В процессе он пробует разные варианты и еле-еле приходит к решению, которое вряд ли даже ложиться в базовые требования задачи. </p>
  <p id="rCkb">Опытный алгоритмист на основании требований задачи сразу видит в ней какие-то <strong>паттерны</strong>. </p>
  <p id="lmH6">Самый первый из них, исходя из требований в этих задачах - <strong>скорость поиска</strong>. Она должна быть константна, а значит тут подойдет только hash map в разных вариацих.</p>
  <p id="QfWO">Второе - способ хранения данных.</p>
  <p id="hB5f">В первой задаче нужна упорядоченность, которой нет в hash map. </p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Li8K" data-align="center"><em>Хорошо. Мы ее туда добавим, если будет хранить ноды связного списка, где каждая нода указывает на последующую внутри контейнера.</em></p>
  </section>
  <p id="QbuN">Во второй требуется такой способ хранения, который предполагал бы, что взяв какое либо число из массива, мы за константное время сможем понять, составляет ли оно с другим числом такую пару, сумма которых равна искомому. </p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="pkBU" data-align="center"><em>Хорошо, будем хранить <strong>разность </strong>текущего и искомого. Если следующее число равно этой разнице, это эти числа образуют пару.</em></p>
  </section>
  <p id="5jTo">Таким образом, суммарно в этих задачах есть <strong>4 </strong>паттерна - оба разделяют использование <strong>hash map</strong> для скорости поиска, только в первой требуется еще и связный список для контроля последовательности, а во второй специфический способ хранения для <em>удобства поиска</em>.</p>
  <p id="kbXH">Имеются и другие способы решения, базирующиеся на других шаблонах.</p>
  <hr />
  <p id="2FLb">Важно понимать, что взяв определенных шаблон, hash map в нашем случае, вы начинаете его <strong>развивать</strong>, собирая <strong>мозайку </strong>для решения. Проблемы возникают тогда, когда вы берете за основу <strong>изначально неверный паттерн</strong>, который в лучшем случае будет не самым оптимальным, в худшем - просто не даст пройти все тест кейсы.</p>
  <p id="qGKG">Вам нужно научиться эти паттерны <strong>отсеивать </strong>на самом раннем этапе из возможных, но об этом ниже.</p>
  <p id="saXI"><em>Тогда возникает закономерный вопрос:</em></p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="5Hyn" data-align="center"><strong>А как тогда написать конечное решение, если оно состоит из множества шаблонов? Неуж-то перебирать их все?</strong></p>
  </section>
  <p id="7Pvp"><em>И появляется не менее закономерный ответ</em>: </p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="jQKm" data-align="center"><strong>И да, и нет.</strong></p>
  </section>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <ul id="xOxw">
      <li id="3wmz"><strong>Тезис 1.</strong> В задачах <strong>Easy-Medium</strong> уровня не высокая глубина. 2-3 паттерна будет достаточно. И их придется подбирать.</li>
      <li id="Wl15"><strong>Тезис 2</strong>. <strong>Формирование идеи нужно устраивать не из всех паттернов</strong>. Если задача про тот же LRU Cache, вам может прийти в голову использовать stack или queue для формирования очередей, и это <strong>нормально</strong>, или начать с hash map и как то комбинировать с очередями. Вторая идея со временем <strong>отсеится </strong>и вы пойдете дальше.</li>
    </ul>
  </section>
  <p id="a6WC">Опытный алгоритмист эту идею <strong>быстро отсеит </strong>и не будет тратить слишком много времени. После чего возьмет следующую и после нее. Спустя некоторое время сортировки он начнет <strong>развивать </strong>ту, с hash map, в <strong>правильном направлении</strong>, прямо как ожидает интервьюер, накидывая на нее мяса в виде дополнительных возможных функциональностей и способов хранения данных.</p>
  <p id="8LLB">Из этого следует простой вывод: </p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="1vhE" data-align="center"><strong>Чтобы эти шаблоны научиться применять, их нужно сначала несколько раз использовать и запомнить.</strong></p>
  </section>
  <p id="gsZm">Тут возникает следующая ошибка: новички сидят за решением <strong>Easy-Medium</strong> задач несколько часов, <strong>пытаясь подобрать паттерн, о котором даже не знают</strong>. </p>
  <p id="Imry">Чтобы эту ошибку не допускать, я рекомендую отводить на задачу любого уровня максимум <strong>45 минут.</strong> Этого с лихвой хватает для составляения решения и написания кода. Если вы не укладываетесь, <strong>значит вы ничего не придумаете и за 2 часа</strong>. </p>
  <hr />
  <h2 id="BYDZ">Собеседование</h2>
  <p id="Pje2">Важно понимать: </p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="ydDb" data-align="center"><strong>В первую очередь, на собеседовании задачу нужно не решать, а обсуждать.</strong></p>
  </section>
  <p id="UnwB">Там редко спрашивают что то сложнее <strong>Medium</strong>, однако, случаи такие бывают.</p>
  <p id="sCxj">Чаще всего, если задача easy-medium, то предполагается, что вы<strong> должны решить ее практически без подсказок и по сути самостоятельно</strong>.</p>
  <p id="MAxU">Если вам выпадет <strong>Hard</strong>, то вероятнее всего интервьюер жаждет с вами побольше <strong>поговорить</strong>, увидеть как можно больше ваших попыток подобрать решение, <strong>и что не менее важно - это решение с интервьюером обсудить</strong>.</p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="RqxH"><strong>Резюмирую</strong>: вне зависимости от сложности задачи ваш план действий <strong>никак не меняется</strong>. Различия будут в количестве попыток для подбора шаблонов и суммарной длительности вашего с интервьюером диалога.</p>
  </section>
  <p id="BGoP">Для полноты понимания о чем я говорю<strong> очень рекомендую</strong> посмотреть лайв кодинг интервью в разные компании. </p>
  <p id="tRUZ">В грамотных сценариях на каждом ходу своего решения программист постоянно <strong>рассуждает вслух</strong> и <strong>спрашивает интервьюера</strong>, имеет ли его текущий подобранный паттерн смысл, или нет.</p>
  <p id="FnsJ">Очень часто, если интервьюер видит, что вы неплохо справляетесь, может самостоятельно помочь, указав на какую-то деталь, которую вы не заметили, или намекнуть, если застряли. И это нормально. </p>
  <p id="RbRc">Как я уже сказал, самое главное на интервью это <strong>общаться</strong>, максимально открыто показывая, что происходит в вашей голове.</p>
  <hr />
  <h2 id="LgTo">Заключение</h2>
  <p id="4Y7Q">Теперь давайте заключим, что нужно делать программисту, который решил сесть за подготовку к собеседованию.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <ol id="KxO7">
      <li id="GY42">Минимальная инструментальная единица в задаче, с которой все начинается - это <strong>структуры данных</strong>. Знакомимся с их принципами работы по туториалам.</li>
      <li id="v3NH">Нам нужно запомнить определенные <strong>шаблоны</strong>, которые составляются из структур данных. Чтобы наша ассоциативная машина грамотно работала и <strong>связывала эти паттерны с конкретными задачами</strong>, грамотно их упаковывая в нашей памяти, мы будем решать задачи <strong>группами из определенных категорий</strong>. Сначала массивы и хэш-контейнеры, потом стэк, два указателя, бинарный/быстрый поиск и так далее. Тут можно ознакомиться с <em>Road Map от NeetCode</em>, или взять курс на <em>AlgoExpert</em>. Я использовал оба ресурса.</li>
      <li id="RIvh">Взяв очередную задачу из категории, сразу ставим таймер - ~45 минут. Если за <strong>5-10 минут</strong> не выходит ничего придумать, достаем первые подсказки, чтобы хоть как-то продвинуть решение. В этом плане мне очень понравился <em>AlgoExpert</em>, который эмитирует процесс интервью, предоставляя 2-4 скрытые шпоры на случай застрявшего решения<strong>.</strong></li>
      <li id="ioLw">Прорешав 100-150 задач нам потребуется опыт реальных собеседований. С этой целью ищем интервьера, принимая во внимание описанные мною ключевые моменты.</li>
      <li id="PvyD">Как только вы можете взять любую <strong>Medium </strong>задачу и с <strong>80%-90%</strong> вероятностью ее решить, значит вы готовы для прохождения алгоритмических интевью. Поздравляю. Теперь можно подаваться на желанные вами вакансии.</li>
    </ol>
  </section>
  <p id="N0pv">Лично я на момент написания статьи решил 126 задач на Leetcode, и ровно столько же на AlgoExpert. Некоторые задачи были похожи, единицы были точной копией и большинство представляли из себя по сути уникальные кейсы.</p>
  <p id="FeQm">В процессе подготовки я перед работой я нарешивал в среднем 2-3 <strong>Medium </strong>задачи или 3-6 <strong>Easy </strong>или 1 <strong>Hard</strong>. И так на протяжении трех с небольшим месяцев каждый день по 1.5 - 2 часа.</p>
  <p id="YVU4">Надеюсь, вы что-то вынесли из этой статьи, и так же надеюсь, что вам потребуется потратить сильно меньше времени и сил для устройства на позицию мечты.</p>
  <p id="ZzNe">Спасибо за внимание!</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@cybeaster/V7hg2gYQut6</guid><link>https://teletype.in/@cybeaster/V7hg2gYQut6?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster</link><comments>https://teletype.in/@cybeaster/V7hg2gYQut6?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cybeaster#comments</comments><dc:creator>cybeaster</dc:creator><title>Как НЕ нужно писать резюме</title><pubDate>Sat, 09 Dec 2023 15:06:09 GMT</pubDate><description><![CDATA[Прежде чем прийти к текущему состоянию своего CV, я пообщался с тонной людей, обошел множество ресурсов, в том числе resume.io, поговорил с ментором ex-amazon'а, обсудив с ним резюме. Суммарно я переписывал его раз 13-14, пока не довел до идеала.]]></description><content:encoded><![CDATA[
  <p id="xFqS">Прежде чем прийти к текущему состоянию своего CV, я пообщался с тонной людей, обошел множество ресурсов, в том числе resume.io, поговорил с ментором ex-amazon&#x27;а, обсудив с ним резюме. Суммарно я переписывал его раз 13-14, пока не довел до идеала.</p>
  <p id="PvJe">Я распишу что указывать нужно, что нельзя, и на что в первую очередь обращает внимание HR.</p>
  <p id="dD00">Начнем с того, что рекрутер может проверять в день десятки и сотни резюме, посему, считайте, что на вашей анкете он <strong>будет задерживаться секунд на 15-30</strong>. Если в нем он ничего не увидит за отведенное время, то проще будет <strong>скипнуть </strong>и приступить к следующему, чем сидеть и разбираться. Из этого следует два вывода:</p>
  <p id="dbc6">1. <strong>Каждое</strong> слово, написанное в вашем резюме, должно иметь смысл.</p>
  <p id="ats6">2. Этих <strong>слов</strong> должно быть как можно меньше, а смысла в них должно быть как можно больше.</p>
  <p id="QhAa">Как правило, если у вас <strong>менее 10 лет</strong> опыта и <strong>меньше пяти</strong> компаний, то резюме <strong>должно помещаться на одну страницу A4</strong>, если этого не происходит, тогда оптимизируйте пространство и умещайте как можете.</p>
  <p id="U0r2">Описанное выше - одна из причин, почему я <strong>отказался от всех резюме билдеров:</strong> они абсолютно неэффективно расходуют пространство.</p>
  <p id="JSJF">Ниже - это <strong>лучшее </strong>к чему я смог прийти на том же resume.io:</p>
  <figure id="MStL" class="m_column">
    <img src="https://telegra.ph/file/1a25fcb4296aaf511db6d.png" width="495" />
  </figure>
  <p id="7Xfi">И то, что получилось в итоге:</p>
  <figure id="HK5o" class="m_retina">
    <img src="https://telegra.ph/file/9122f22a6d9bc9fef8ed3.png" width="828" />
  </figure>
  <p id="cO1P">Чтобы собрать пазл о сотруднике <strong>уже</strong> небходимо идти на следующую страницу. Если было бы больше компаний или пет проектов, то могло бы выйти и на 3 страницы.</p>
  <h4 id="Что-не-нужно-писать:">Что не нужно писать:</h4>
  <ul id="h3AC">
    <li id="2DOE"><strong>Дата рождения</strong> - Эйджизм никто не отменял. Никогда не светите возрастом пока никто не явно не спросит.</li>
    <li id="t1Ap"><strong>Город/страна</strong> - Бессмысленная информация. Если вы подаетесь в Москву, значит вы или готовы к релокации, или живете в Москве. Если вы подаетесь в US - on site, но не собираетесь переезжать, то просто потратите и свое, и время HR&#x27;а в пустую.</li>
    <li id="QvUg"><strong>Отдельная графа для скиллов</strong>: абсолютно бесполезна. Каждый скилл там ничем не подкреплен. Если хотите аргументировать почему вы это умеете, пишите в секции с местами работы, пет проектами или сертификатами. (У меня на первых итерациях резюме - колонка слева).</li>
    <li id="iV9J"><strong>О себе</strong> - мне рекомендовали вообще вырезать, я оставил чтобы хоть как то обрисовывать опыт. Допустимо до 200 символов, я бы рекомендовал максимум пару строк.</li>
    <li id="I82V"><strong>Локация места работы</strong> - бесполезная информация, советую не указывать.</li>
    <li id="VihD"><strong>Фотография - </strong>бесполезная информация - вырезаем<strong>.</strong></li>
    <li id="eZVg"><strong>Язык </strong>- можно указать, если считаете, что это даст вам преимущество на вакансиях и/или есть свободное место.</li>
  </ul>
  <h4 id="Что-нужно-писать:">Что нужно писать:</h4>
  <ul id="tBiS">
    <li id="33Ws"><strong>Чем занимались</strong> на каждой работе по паттерну: <strong>ЧТО СДЕЛАЛ/ЧЕМ ЗАНИМАЛСЯ - ЧТО ПОЛУЧИЛ</strong>. Это так зываемые <em>bullet point&#x27;ы</em>. Их, обычно, указывают от 3 до 5 штук. Я урезал, чтобы поместились все проеты</li>
    <li id="X5yI"><strong>Образование </strong>- указывать желательно, если есть. Я писал без лет, только бакалавриат. Так же, все ваши сертификаты, имеющие отношения к работе, курсы английского и т.д т.п есть смысл указывать, если только это не олимпиада Кенгуренок за 2 класс.</li>
    <li id="4RnB"><strong>Стэк, задействованный в работе</strong> - нужно дать понять HR&#x27;у чем вы пользовались, однако мне советовали вставлять технологии в <em>bullet point&#x27;ы</em>. Это оказалось весьма проблематично и я вынес в отдельный список ниже позиции.</li>
    <li id="Jx3V"><strong>Опционально</strong> - в конце можно добавить ваши хобби, увлечения и пр., но сомневаюсь что хоть кто-то на это посмотрит. Исключением могут выступать ваши блоги/юпуп каналы и прочее, но даже так, я бы оставил ссылку вверху и в первом блоке постарался бы это выделить.</li>
  </ul>
  <h4 id="Теперь-конкретно-по-моему-резюме:">Теперь конкретно по моему резюме:</h4>
  <ol id="DrBE">
    <li id="7zfS"><strong>О Себе</strong> - заголовок отнимает место и бесполезен - убираем, оставляем только нужный текст. Интуинтивно и так понятно что там и о чем.</li>
    <li id="0brS"><strong>Профессиональный опыт</strong>. В теории там тоже можно было бы убрать заголовок, но место было, и я решил оставить. На первых двух местах работы по 2-3 <em>bullet points</em> с конкретными цифрами и стэком. Так же вставил небольшое описание что за продукт делал и прилинковал сайты.</li>
    <li id="48gn"><strong>Пэт проекты</strong>. Там в любом случае надо писать заголовок, иначе не будет ясно о чем блок. Там по точно такой же схеме - описание проекта в одну строку и <em>3 bullet points</em> в каждой.</li>
    <li id="erFL"><strong>Образование </strong>- т.к места не хватало, я объединил в один блок и бакалавриат, и сертификаты. Для вуза так же указал стэк, но можно этого и не делать. Почти всем все равно чем ты в вузе занимался.</li>
  </ol>
  <p id="jKEr">Так же важно понимать, что ваши резюме прогоняются через <em>Applicant Tracking systems (ATS)</em> разбивая на <strong>ключевые слова</strong>. Если в вашем резюме <em>ATS </em>не найдет кейвордов на нужную позицию, то его просто <strong>выкинут</strong>.</p>
  <p id="LHf2">Результат по кейвордам, который выдала ATS после сканирования самой первой версии резюме:</p>
  <figure id="vuGs" class="m_original">
    <img src="https://telegra.ph/file/03bd4abdae068bf6fe06e.png" width="765" />
  </figure>
  <p id="H2hz">Советую так же ознакомиться с другим <a href="https://www.careercup.com/resume" target="_blank">ресурсом</a>, где очень подробно описаны правила составления резюме.</p>
  <p id="rrEI">Так же предлагаю брать мой <a href="https://docs.google.com/document/d/1uPx5wfb1mRArK7HA8n0tNq3qMNMtDSL-bpVg_BUmjXU/edit?usp=sharing" target="_blank">вариант</a>, и переписывать под себя.</p>

]]></content:encoded></item></channel></rss>