<?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>Alex Compass</title><generator>teletype.in</generator><description><![CDATA[Alex Compass]]></description><image><url>https://img1.teletype.in/files/8d/f6/8df65fe2-c3d7-4954-9d14-12335ab40bfe.png</url><title>Alex Compass</title><link>https://teletype.in/@alexbrin</link></image><link>https://teletype.in/@alexbrin?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/alexbrin?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/alexbrin?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Wed, 23 Sep 2026 05:45:03 GMT</pubDate><lastBuildDate>Wed, 23 Sep 2026 05:45:03 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@alexbrin/G2ySaxv1r9q</guid><link>https://teletype.in/@alexbrin/G2ySaxv1r9q?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/G2ySaxv1r9q?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>Ум разработчика Практика дзен в мире Java - Часть I. Учись видеть</title><pubDate>Tue, 04 Aug 2026 15:46:27 GMT</pubDate><category>Ум разработчика. Практика дзен в мире Java</category><description><![CDATA[«Пока ты смотришь на свои идеи, ты не видишь программу.»]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#6tCQ">Предисловие</a></li>
      <li class="m_level_1"><a href="#5rYa">Глава 1. Компилятор никогда не ошибается</a></li>
      <li class="m_level_2"><a href="#XoVQ">Молодой разработчик и его первая ошибка компиляции</a></li>
      <li class="m_level_2"><a href="#TRs3">Почему мы не любим ошибки</a></li>
      <li class="m_level_2"><a href="#Awqr">Что такое компилятор на самом деле</a></li>
      <li class="m_level_2"><a href="#G3oM">Переводчик между двумя мирами</a></li>
      <li class="m_level_2"><a href="#tHyv">Компилятор не думает за программиста</a></li>
      <li class="m_level_2"><a href="#qOBB">Как компилятор читает программу</a></li>
      <li class="m_level_2"><a href="#YpWs">Учиться читать, а не бояться</a></li>
      <li class="m_level_2"><a href="#Xe7Q">Почему компилятор никогда не ошибается</a></li>
      <li class="m_level_2"><a href="#bEKN">Почему нам кажется, что ошибается компилятор</a></li>
      <li class="m_level_2"><a href="#A9F9">Ошибка как момент обучения</a></li>
      <li class="m_level_2"><a href="#Ngjd">Компилятор как первый учитель</a></li>
      <li class="m_level_2"><a href="#TWnY">Быстрая обратная связь ускоряет обучение</a></li>
      <li class="m_level_2"><a href="#R96m">Дзен и искусство наблюдать результат</a></li>
      <li class="m_level_2"><a href="#kIZt">Учимся читать сообщения компилятора</a></li>
      <li class="m_level_2"><a href="#lmKH">Как правильно читать ошибки</a></li>
      <li class="m_level_2"><a href="#famp">Что изменится в вашем мышлении после этой главы</a></li>
    </ul>
  </nav>
  <h2 id="6tCQ">Предисловие</h2>
  <blockquote id="qEhL"><em>«Пока ты смотришь на свои идеи, ты не видишь программу.»</em></blockquote>
  <p id="j82j">Когда человек только начинает изучать программирование, ему кажется, что главная задача разработчика состоит в том, чтобы писать код. Со временем приходит другое понимание: писать код относительно просто. Гораздо сложнее увидеть, что происходит на самом деле.</p>
  <p id="dGyx">Большинство ошибок рождается не из-за незнания синтаксиса. Они появляются в тот момент, когда мы начинаем заменять наблюдение предположениями.</p>
  <p id="Mz8n">«Наверное, переменная уже изменилась.»</p>
  <p id="Nrz3">«Скорее всего, этот метод уже выполнился.»</p>
  <p id="FJVE">«Должно работать.»</p>
  <p id="QgEB">Но компьютеру безразлично, что мы предполагаем. Он не знает наших ожиданий. Он не пытается угадать, что мы имели в виду. Он лишь последовательно исполняет инструкции, одну за другой.</p>
  <p id="kwmZ">Разработка начинается с простого, но непривычного навыка: перестать гадать.</p>
  <p id="dLUb">В дзен существует практика простого наблюдения. Во время <strong>дзадзен</strong> не требуется создавать особое состояние, искать необычные переживания или бороться с возникающими мыслями. Практикующий лишь снова и снова возвращается к тому, что происходит прямо сейчас.</p>
  <blockquote id="cl7x"><em><strong>Дзадзен</strong> (от японских слов дза — «сидеть» и дзен — «медитация») — это базовая практика «сидячей медитации» в дзен-буддизме.<br /><strong>Краткая суть:</strong> Практикующий принимает устойчивую сидячую позу (обычно со скрещенными ногами и прямой спиной), концентрируется на дыхании и беспристрастно наблюдает за потоком мыслей, не цепляясь за них и не оценивая их. В дзен это называют принципом «просто сидения».<br /><strong>Главная цель:</strong> Остановить бесконечный внутренний диалог, отбросить эго и напрямую осознать свою истинную природу.</em></blockquote>
  <p id="B5Y5">В разработке происходит нечто похожее.</p>
  <p id="MRx4">Когда программа ведет себя не так, как мы ожидали, естественная реакция состоит в том, чтобы искать объяснение в собственной голове. Мы начинаем строить версии, вспоминать похожие ситуации, искать виноватую строку кода. Но опытный разработчик сначала делает другое. Он открывает отладчик. Смотрит значения переменных. Переходит по стеку вызовов. Проверяет, а не предполагает.</p>
  <p id="Jtmv">Это и есть практика наблюдения. Компилятор не оценивает. Он показывает несоответствие. Отладчик не спорит. Он показывает состояние программы. Стек вызовов не объясняет, почему произошла ошибка. Он честно показывает путь, которым программа пришла к этому месту.</p>
  <p id="Vhwl">Каждый из этих инструментов предлагает разработчику отказаться от фантазий и встретиться с реальностью. Именно поэтому эта часть посвящена не Java и даже не отладке. Она посвящена умению видеть. Без этого навыка невозможно глубоко понять язык программирования. Невозможно проектировать сложные системы. Невозможно уверенно исправлять ошибки. Можно лишь надеяться, что код работает.</p>
  <p id="Ug3p">Дальше мы будем говорить о компиляторе, отладчике и стеке вызовов. Но наша настоящая цель не научиться пользоваться инструментами. Наша цель намного глубже. Научиться видеть программу такой, какая она есть, а не такой, какой мы ее представляем.</p>
  <h2 id="5rYa"><strong>Глава 1. Компилятор никогда не ошибается</strong></h2>
  <h3 id="XoVQ"><strong>Молодой разработчик и его первая ошибка компиляции</strong></h3>
  <p id="PuPF">Почти у каждого разработчика есть момент, который запоминается надолго. Не потому, что он написал красивый код. И не потому, что решил сложную задачу.</p>
  <p id="ECDM">А потому, что впервые увидел красную строку с ошибкой и подумал:</p>
  <p id="RiFJ">«Почему программа не работает? Я же всё написал правильно.»</p>
  <p id="zeaC">Представьте молодого разработчика. Он только начал изучать Java. Позади несколько видеоуроков, несколько простых задач и чувство, что всё постепенно становится понятным.</p>
  <p id="bLWb">Сегодня он пишет свою первую небольшую программу самостоятельно.</p>
  <pre id="yHFX" data-lang="java">public class Main {
    public static void main(String[] args) {
        String name = &quot;Alex&quot;;
        System.out.println(&quot;Hello, &quot; + name)
    }
}</pre>
  <p id="lt5c">Он нажимает кнопку <strong>Run</strong>.</p>
  <p id="hevJ">Но вместо привычного окна с результатом появляется сообщение: </p>
  <pre id="1ZNr">error: &#x27;;&#x27; expected</pre>
  <p id="5k60">Недоумение.</p>
  <p id="Oec9">«Какой ещё <code>;</code>?»</p>
  <p id="6GNU">Он несколько раз перечитывает код. Всё кажется правильным. Переменная объявлена. Строка выводится. Скобки на месте. Он снова нажимает <strong>Run</strong>. Та же ошибка.</p>
  <p id="LCOb">Начинается поиск виноватого. Может быть, проблема в IntelliJ IDEA? Может быть, что-то неправильно установлено? Может быть, Java работает не так, как объясняли в видео?</p>
  <p id="O8VK">Через несколько минут он замечает, что в конце строки действительно отсутствует точка с запятой. Он добавляет её.</p>
  <pre id="uusI" data-lang="java">System.out.println(&quot;Hello, &quot; + name);</pre>
  <p id="Y6I9">Программа запускается. На экране появляется: <strong>Hello, Alex</strong></p>
  <p id="91H9">Обычно на этом история заканчивается.</p>
  <p id="9Skk">Человек улыбается, говорит себе: «Понятно, просто забыл точку с запятой», и идёт дальше. Но если остановиться и внимательно посмотреть на произошедшее, можно заметить нечто гораздо более важное. Ошибка заключалась вовсе не в отсутствии точки с запятой. Настоящая ошибка произошла раньше.</p>
  <p id="Ys6a">Разработчик был абсолютно уверен, что его программа написана правильно. Он доверял собственной памяти больше, чем тому, что происходило на экране. Вместо того чтобы внимательно прочитать сообщение компилятора, он начал искать объяснения в своей голове. Это очень человеческая реакция. Наш мозг не любит признавать, что ошибся. Ему проще предположить, что виноват редактор кода, неправильная настройка проекта или странное поведение языка программирования.</p>
  <p id="1r1S">Но компьютер не умеет делать предположений.</p>
  <p id="dxfq">Он не думает: «Наверное, разработчик просто устал.»</p>
  <p id="cvZ2">Он не говорит: «Почти правильно, попробую догадаться, что ты хотел написать.»</p>
  <p id="krIG">Он лишь сообщает факт. «Я не могу скомпилировать программу. В этом месте я ожидал увидеть точку с запятой.»</p>
  <p id="mFxM">Ни больше, и меньше.</p>
  <p id="roa8">Именно здесь начинается мышление разработчика. Не тогда, когда человек запоминает синтаксис Java. Не тогда, когда впервые использует цикл или создаёт объект. А тогда, когда перестаёт спорить с обратной связью и начинает её изучать.</p>
  <p id="idYt">В дзен существует простая практика наблюдения. Когда возникает мысль, её не объявляют правильной или неправильной. Её не пытаются прогнать и не пытаются удержать. Её просто замечают такой, какая она есть.</p>
  <p id="zBHG">Хороший разработчик постепенно учится делать то же самое с программой. Он перестаёт спрашивать: «Почему компьютер делает что-то странное?». И начинает спрашивать: «Что именно компьютер пытается мне показать?». На первый взгляд кажется, что это небольшая разница в формулировке. На самом деле именно она отделяет человека, который борется с ошибками, от человека, который понимает систему.</p>
  <p id="oYoh">В следующих разделах этой главы мы увидим, что компилятор вовсе не является строгим экзаменатором, который ищет повод отклонить программу. Наоборот, компилятор становится первым и самым честным учителем разработчика. И самое удивительное заключается в том, что за всю историю программирования он ни разу не ошибался намеренно. Ошибаемся мы. Компилятор лишь помогает нам это увидеть.</p>
  <h3 id="TRs3"><strong>Почему мы не любим ошибки</strong></h3>
  <p id="c1FG">Если попросить человека вспомнить школьные годы, то у многих вместе со знаниями всплывают и другие воспоминания:</p>
  <p id="IHJH">Красная ручка учителя. Исправления на полях. Низкая оценка. Замечание вроде: «Опять неправильно».</p>
  <p id="GkzP">С самого детства нас приучают к простой связи:</p>
  <p id="U0Hj"><strong>Ошибка = плохо.</strong></p>
  <p id="oCnP">Если ошибся, значит недостаточно старался. Если ошибся, значит плохо подготовился. Если ошибся, значит знаешь меньше других.</p>
  <p id="g1up">Со временем эта мысль становится настолько привычной, что мы перестаём её замечать. Она превращается в автоматическую реакцию. Именно поэтому, когда начинающий разработчик видит сообщение об ошибке компиляции, он редко воспринимает его спокойно. Вместо любопытства появляется раздражение. Иногда возникает и более неприятная мысль: «Наверное, программирование просто не для меня.»</p>
  <p id="EcFs">Но давайте на минуту остановимся. Что такое ошибка компиляции? Это не двойка в дневнике. Не замечание преподавателя. Не оценка ваших способностей. Компилятор вообще ничего о вас не знает. Он не знает, сколько времени вы изучаете Java. Не знает, сколько книг вы прочитали. Не знает, устали ли вы сегодня после работы. Для него существует только исходный код. Он сравнивает написанную программу с правилами языка Java. Если программа соответствует этим правилам, компиляция продолжается. Если нет, он сообщает, в каком месте обнаружил несоответствие.</p>
  <p id="SGBL">Всё.</p>
  <p id="9tD1">Никаких эмоций. Никаких оценок. Никакого осуждения.</p>
  <p id="Cd1o">Представьте, что вы собираете шкаф по инструкции. Вы пытаетесь вставить деревянную полку в паз, который для неё не подходит. Полка не встаёт. Будет ли разумно обижаться на шкаф? Конечно нет. Шкаф не говорит: «Ты плохой сборщик мебели.». Он просто устроен определённым образом.</p>
  <p id="9Zhe">Язык программирования ничем не отличается. Если после имени переменной ожидается оператор, компилятор не может сделать вид, что его отсутствие не имеет значения. Если после строки требуется точка с запятой, он не станет угадывать ваши намерения. Он действует строго по правилам языка. И именно в этой строгости скрывается его главная ценность.</p>
  <p id="bS7i">Представьте себе другой мир. Вы написали программу с ошибкой. Компилятор посмотрел на неё и решил: «Похоже, разработчик имел в виду вот это.». В одном случае он бы угадал. В другом ошибся. В третьем вообще изменил бы смысл программы. Каждый запуск превращался бы в лотерею. Надёжное программирование стало бы невозможным. Строгость компилятора иногда раздражает новичков именно потому, что она не оставляет места для догадок. Но со временем приходит неожиданное понимание. Строгость не является наказанием.</p>
  <p id="yiAi">Строгость является формой уважения.</p>
  <p id="oyin">Компилятор относится одинаково и к человеку, который открыл Java вчера, и к инженеру с двадцатилетним опытом. Для всех существуют одни и те же правила. Именно поэтому опытные разработчики редко воспринимают ошибки компиляции как проблему. Они воспринимают их как обратную связь. Не как сообщение: «Ты ошибся.». А как сообщение: «Вот место, где твоё понимание языка сейчас расходится с его правилами.». Это очень важное различие. В первом случае ошибка становится поводом защищаться. Во втором случае она становится источником информации.</p>
  <p id="ECCO">В дзен существует интересная мысль: Страдание часто возникает не из-за самой ситуации, а из-за сопротивления ей.</p>
  <p id="8d55">Мы хотим, чтобы реальность соответствовала нашим ожиданиям. Но реальность не обязана этого делать. В разработке происходит то же самое. Мы ожидаем, что программа должна компилироваться. Компилятор показывает, что это не так. Можно раздражаться. Можно спорить. Можно несколько раз нажимать кнопку <strong>Run</strong>, надеясь, что в этот раз всё получится.</p>
  <p id="BBib">А можно остановиться и задать другой вопрос: <strong>«Что именно программа пытается мне сообщить?»</strong></p>
  <p id="cIQL">С этого вопроса начинается обучение. Не только в программировании. Но и в любом деле, где человек хочет понять реальность, а не доказать собственную правоту.</p>
  <h3 id="Awqr"><strong>Что такое компилятор на самом деле</strong></h3>
  <p id="ktza">Когда человек впервые сталкивается с программированием, между ним и компьютером существует невидимый барьер.</p>
  <p id="u2Ry">Человек пишет:</p>
  <pre id="rOLK" data-lang="java">System.out.println(&quot;Hello, world!&quot;);</pre>
  <p id="r7a1">Он видит понятные слова.</p>
  <p id="M0WE"><code>System.</code></p>
  <p id="s6EP"><code>out.</code></p>
  <p id="x9TP"><code>println.</code></p>
  <p id="chpv">Кажется, что компьютер должен просто прочитать эту строку и выполнить её. Но компьютер не понимает Java. Для него эта строка не является командой. Для него это просто набор символов. Компьютер понимает только машинный код. Набор инструкций, записанных в форме, которую способен выполнить процессор. Возникает простой вопрос:</p>
  <p id="prq8"><strong>Как программа, написанная человеком на Java, превращается в команды, понятные компьютеру?</strong></p>
  <p id="AsT6">Ответом является компилятор.</p>
  <h3 id="G3oM"><strong>Переводчик между двумя мирами</strong></h3>
  <p id="qPmO">Самое простое объяснение компилятора:</p>
  <p id="Ztks"><strong>Компилятор — это программа, которая переводит код, написанный человеком, в форму, которую может выполнить компьютер.</strong></p>
  <p id="cL7i">Можно представить двух людей, которые говорят на разных языках. Один говорит по-русски. Другой понимает только японский. Между ними нужен переводчик. Но хороший переводчик делает больше, чем просто заменяет слова. Он проверяет смысл. Если человек сказал бессмысленную фразу, переводчик не сможет качественно её перевести. Компилятор делает примерно то же самое. Он не просто заменяет одни символы другими. Он пытается понять написанную программу.</p>
  <p id="rBzW"><strong>Почему компьютер не может выполнить Java напрямую</strong></p>
  <p id="K8m3">Возьмём простой пример:</p>
  <pre id="0OfX" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;Hello&quot;);
    }
}
</pre>
  <p id="yvQn">Для человека здесь всё понятно. Создается класс. Есть главный метод. На экран выводится текст. Но компьютер не видит «класс» или «метод». Он не знает, что такое <code>System.out.println</code>. Для процессора существует только набор очень низкоуровневых команд.</p>
  <p id="ofav">Например:</p>
  <ul id="Q9yF">
    <li id="Rd7v">взять значение из памяти;</li>
    <li id="JNXv">записать значение в регистр;</li>
    <li id="BBdM">выполнить операцию;</li>
    <li id="JYMK">перейти к следующей инструкции.</li>
  </ul>
  <p id="zQt4">Если бы каждый программист писал программы непосредственно в машинном коде, разработка была бы невероятно сложной. Поэтому появились языки программирования высокого уровня. Java, Python, C#, Kotlin и другие языки позволяют человеку описывать задачи понятным способом. А компилятор становится мостом между человеческой идеей и машинным исполнением.</p>
  <p id="zVUa"><strong>Что происходит, когда мы нажимаем Run</strong></p>
  <p id="rHA1">Начинающий разработчик часто думает: «Я написал код. Нажал кнопку запуска. Программа работает.» Но между этими действиями происходит несколько этапов. Когда мы пишем:</p>
  <pre id="twlD" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;Hello&quot;);
    }
}
</pre>
  <p id="1D0e">происходит примерно следующее. Сначала компилятор получает наш исходный код. Это файл <code>Main.java</code> Затем он начинает его анализировать.</p>
  <p id="zN9p">Он проверяет:</p>
  <ul id="Iie0">
    <li id="IOEq">правильно ли написаны ключевые слова;</li>
    <li id="8tX5">закрыты ли скобки;</li>
    <li id="7sU5">существуют ли используемые методы;</li>
    <li id="61Jr">соответствуют ли типы данных друг другу;</li>
    <li id="Sg8Z">соблюдаются ли правила языка Java.</li>
  </ul>
  <p id="zn5q">Если всё правильно, компилятор создает другой файл - <code>Main.class</code>. Внутри него находится байткод Java. Это уже не человеческий текст, но еще не машинный код процессора. Дальше в дело вступает JVM.</p>
  <p id="Y0tb">Здесь появляется одна из самых интересных особенностей Java.</p>
  <p id="4rFh">Java-код --&gt; Байткод --&gt; JVM --&gt; Машинный код --&gt; Процессор</p>
  <p id="9vCz">Это решение стало одной из главных причин популярности Java. Один и тот же файл .class может работать на разных системах. Неважно, какой процессор стоит внутри компьютера. Если есть подходящая JVM, программа может выполняться. Именно отсюда появился знаменитый принцип Java: «Напиши один раз, запускай где угодно.»</p>
  <h3 id="tHyv"><strong>Компилятор не думает за программиста</strong></h3>
  <p id="iNJt">Здесь важно понять одну вещь. Компилятор умный. Но не настолько, как часто думают начинающие разработчики. Он не понимает вашу цель. Он не знает, какую задачу вы решаете. Он не знает, почему вы написали именно такой код. Если программа компилируется, это не означает, что она правильная.</p>
  <p id="1l14">Например, <code>int age = -500;</code></p>
  <p id="twSB">С точки зрения Java это допустимо. Компилятор не знает, что возраст человека не может быть отрицательным. Компилятор проверяет только то, что входит в правила языка. Он не заменяет мышление разработчика. Он помогает ему.</p>
  <p id="ucpH"><strong>Компилятор как первый собеседник программы</strong></p>
  <p id="TSii">Когда разработчик пишет код, он создает определённую модель мира. Он говорит:</p>
  <p id="UBGJ">«Вот объект пользователя.»</p>
  <p id="cn0B">«Вот список товаров.»</p>
  <p id="FGMv">«Вот операция оплаты.»</p>
  <p id="9rNv">Компилятор смотрит на эту модель и задаёт первый вопрос: «Эта модель вообще соответствует правилам языка?». Если нет, он сообщает об этом. Не потому что хочет остановить разработчика. А потому что обнаружил несоответствие раньше, чем это сделает программа во время работы. Это огромная ценность. Чем раньше обнаружена проблема, тем дешевле её исправить. Ошибка в момент написания кода исправляется за минуту. Ошибка у пользователя в работающем приложении может стоить компании денег, времени и доверия.</p>
  <p id="De1j"><strong>Новый взгляд на компилятор</strong></p>
  <p id="8AEX">Начинающий разработчик часто видит компилятор как препятствие. Он написал код. Компилятор отказался. Значит, компилятор мешает. Опытный разработчик смотрит иначе. Он видит помощника, который постоянно проверяет его работу.</p>
  <p id="BhaW">Компилятор — это первая линия защиты программы. Он не пытается доказать, что разработчик неправ. Он показывает место, где возникло противоречие. И чем лучше разработчик умеет понимать этот диалог, тем быстрее он развивается. Потому что программирование — это не процесс написания правильного кода с первого раза. Это процесс постоянного получения обратной связи, анализа и улучшения. А компилятор является первым и самым честным источником этой обратной связи.</p>
  <h3 id="qOBB"><strong>Как компилятор читает программу</strong></h3>
  <p id="ZZrn">Когда человек читает книгу, он не воспринимает каждую букву отдельно. Мы видим слово. Мы понимаем предложение. Мы улавливаем смысл.</p>
  <p id="rd8m">Например: «Разработчик исправил ошибку в программе.»/ Человеку не нужно отдельно анализировать каждую букву. Мозг сразу собирает символы в слова, слова в предложения, а предложения в смысл.</p>
  <p id="i68S">Компьютер работает иначе. Для него программа начинается не с смысла. Она начинается с символов. Когда компилятор получает Java-файл, перед ним лежит просто текст:</p>
  <pre id="QKAL" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;Hello&quot;);
    }
}
</pre>
  <p id="OQK7">Для человека это программа. Для компилятора это последовательность символов, которую нужно постепенно понять. Именно поэтому компиляция похожа не на простое копирование текста, а на процесс чтения и анализа. Компилятор задает программе несколько вопросов.</p>
  <p id="oGwb">Сначала: «Эти символы вообще образуют понятные слова?»</p>
  <p id="SdNP">Потом: «Эти слова стоят в правильном порядке?»</p>
  <p id="bBBx">Потом: «Имеет ли смысл то, что написано?»</p>
  <p id="X2qo">И только после этого: «Можно ли превратить это в программу, которую сможет выполнить компьютер?»</p>
  <p id="Qnmt"><strong>Первый этап. Лексический анализ: поиск слов</strong></p>
  <p id="2nqI">Представим, что мы открыли книгу на незнакомом языке. Мы видим буквы, но пока не понимаем отдельных слов. Первое, что нужно сделать, — разделить поток символов на отдельные элементы. Компилятор делает примерно то же самое. Этот этап называется <strong>лексическим анализом</strong>. Его задача — превратить набор символов в понятные части программы.</p>
  <p id="YYBo">Например: <code>int age = 35;</code>. Для человека это одна строка.</p>
  <p id="lNDG">Для компилятора это несколько элементов:</p>
  <ul id="6n0I">
    <li id="xbLd">int</li>
    <li id="rN1C">age</li>
    <li id="5sy3">=</li>
    <li id="GbF1">35</li>
    <li id="uHzM">;</li>
  </ul>
  <p id="nem4">Каждый элемент имеет свое значение.</p>
  <ul id="3Xw9">
    <li id="tCMq">int — ключевое слово языка Java.</li>
    <li id="6TrM">age — имя переменной.</li>
    <li id="9gwQ">= — оператор присваивания.</li>
    <li id="7cMy">35 — числовое значение.</li>
    <li id="PURw">; — завершение инструкции.</li>
  </ul>
  <p id="KpCp">Компилятор еще не пытается понять всю программу. Он только говорит: «Я вижу такие элементы.»</p>
  <p id="PbGK">Теперь представим ошибку: <code>int age = ;</code>. Человек может понять, что здесь хотел написать разработчик. Возможно, <code>int age = 35;</code>. Но компилятор не работает с догадками. После знака = он ожидает значение. А значения нет. Поэтому появляется ошибка. Не потому что компилятор «не понял человека». А потому что в программе отсутствует обязательная часть конструкции языка.</p>
  <p id="ZoYt"><strong>Второй этап. Синтаксический анализ: правильное ли предложение</strong></p>
  <p id="fab4">Когда мы знаем слова, нужно проверить, можно ли из них составить предложение. Например: «Моя сегодня программа писать.». Формально все слова существуют. Но предложение звучит неправильно.</p>
  <p id="JvqN">В программировании происходит похожий процесс. Компилятор проверяет структуру программы. Например:</p>
  <pre id="6jrA" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;Hello&quot;);
    }
}
</pre>
  <p id="iyi2">Компилятор видит:</p>
  <ul id="7Usf">
    <li id="GUof">Класс.</li>
    <li id="c8KH">Внутри класса метод.</li>
    <li id="QmJz">Внутри метода команда вывода.</li>
    <li id="Han1">Все элементы расположены там, где должны находиться.</li>
  </ul>
  <p id="VejE">Теперь изменим код:</p>
  <pre id="rB6N" data-lang="java">public class Main {
    public static void main(String[] args)
        System.out.println(&quot;Hello&quot;);
}
</pre>
  <p id="JQtV">Человеку понятно, что пропущена фигурная скобка. Но для компилятора структура нарушена. Метод объявлен, но его тело не определено. Он не может продолжить анализ. Это похоже на чтение предложения: «Когда я пришел домой потому что». Мы понимаем, что мысль не закончена. Компилятор тоже видит незавершенную конструкцию.</p>
  <p id="ZSC0"><strong>Третий этап. Проверка типов: имеет ли смысл операция</strong></p>
  <p id="HBgm">После того как программа построена правильно, компилятор начинает проверять смысл отдельных действий. Один из важнейших принципов Java — строгая типизация. Каждое значение имеет свой тип. Например: <code>int age = 35;</code>, <code>String name = &quot;Alex&quot;;</code></p>
  <p id="YNuC">Переменная <code>age</code> хранит число. Переменная name хранит текст.</p>
  <p id="KaMa">Теперь:<code> int result = age + name;</code></p>
  <p id="XgI7">Что здесь происходит? Мы пытаемся сложить число и текст. Человек может сказать: «Наверное, разработчик ошибся.»</p>
  <p id="yuIA">Компилятор говорит: «Я вижу операцию сложения. Но не знаю, как сложить эти два типа.»</p>
  <p id="3ZDU">Поэтому он сообщает об ошибке. Это не наказание. Это предупреждение: «Твоя модель данных сейчас противоречит правилам языка.»</p>
  <p id="pmKE"><strong>Четвертый этап. Поиск существующих элементов</strong></p>
  <p id="mZuY">Java-программа состоит не только из правил языка. Она использует классы, методы и библиотеки. Например: System.out.println(&quot;Hello&quot;);</p>
  <p id="0MRj">Компилятор должен проверить:</p>
  <ul id="F7Og">
    <li id="lB7P">Существует ли класс System?</li>
    <li id="tnO7">Есть ли у него поле out?</li>
    <li id="0OlE">Есть ли у него метод println?</li>
    <li id="eFCf">Можно ли передать туда строку?</li>
  </ul>
  <p id="kaZf">Если написать <code>System.out.printl(&quot;Hello&quot;);</code> компилятор остановится. Для человека ошибка очевидна. Пропущена буква n. Но для программы существует только то, что определено. Метода <code>printl</code> нет. Поэтому компилятор сообщает: «Я не нашёл такой элемент.»</p>
  <p id="Gz7J"><strong>Почему ошибки иногда показываются не там, где проблема</strong></p>
  <p id="LzUA">Это один из самых сложных моментов для новичков. Компилятор может указать строку, где ошибка стала заметной, но настоящая причина может находиться выше. Например:</p>
  <pre id="YqJ5" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;Hello&quot;)
        System.out.println(&quot;World&quot;);
    }
}
</pre>
  <p id="c8pd">Ошибка будет показана возле второй строки вывода. Но проблема находится в предыдущей строке. Там отсутствует <code>;</code>.</p>
  <p id="2ITO">Почему? Потому что компилятор читает программу последовательно. Он ожидал увидеть завершение первой команды. Но получил начало следующей. Он сообщает место, где перестал понимать программу.</p>
  <p id="wDFd">Это похоже на человека, который читает предложение: «Сегодня утром я пошел в магазин купил хлеб и встретил». Он может понять, что что-то не так, только когда дошел до конца. Проблема появилась раньше, но стала очевидной позже.</p>
  <p id="BkGh"><strong>Компилятор не понимает намерения. Он понимает правила.</strong></p>
  <p id="DKwY">Это, пожалуй, самая важная мысль этого раздела. Компилятор не знает, что вы хотели написать. Он не читает ваши мысли. Он не видит вашу задачу. Он видит только код. И это его сила. Если бы компилятор пытался угадывать намерения, он иногда помогал бы нам, а иногда создавал бы незаметные ошибки. Строгие правила делают программу предсказуемой. Когда компилятор говорит: «Это невозможно выполнить» - он не утверждает: «Ты плохой разработчик.»</p>
  <p id="fpkp">Он говорит: «В твоём описании программы есть противоречие.»</p>
  <p id="sd6F">И чем быстрее разработчик учится воспринимать это сообщение именно так, тем быстрее он растёт.</p>
  <h3 id="YpWs"><strong>Учиться читать, а не бояться</strong></h3>
  <p id="wiL0">Начинающий разработчик часто пытается избавиться от ошибок. Опытный разработчик учится понимать их. Это большая разница. Ошибка компиляции — это не конец процесса написания программы. Это часть процесса. Ты написал. Компилятор проверил. Он показал несоответствие. Ты изменил код. Получил новую обратную связь. И постепенно программа становится точнее. В этом процессе нет борьбы между человеком и компьютером. Есть диалог. Компилятор задает вопросы. Разработчик отвечает изменением кода. И именно через этот диалог человек начинает по-настоящему видеть программу.</p>
  <h3 id="Xe7Q"><strong>Почему компилятор никогда не ошибается</strong></h3>
  <p id="arWZ">Название может показаться странным. Разве компиляторы никогда не содержат ошибок? Конечно, содержат.</p>
  <p id="Dbxk">Компилятор — это тоже программа. А программы пишут люди. В истории развития языков программирования находили ошибки в компиляторах, исправляли их, выпускали новые версии. Но когда мы говорим: «Компилятор никогда не ошибается» - мы говорим не о внутренних ошибках самого компилятора. Мы говорим о другом. Мы говорим о его главной функции. Если компилятор сообщает: «Этот код нарушает правила языка Java» - то в рамках этих правил он не ошибается. Он выполняет именно ту работу, для которой был создан.</p>
  <p id="r1Bl"><strong>Ошибка или несоответствие?</strong></p>
  <p id="htoZ">Есть важное различие между двумя вещами.</p>
  <p id="KcI1">Первое: «Программа работает не так, как ожидалось.»</p>
  <p id="qtp5">Второе: «Программа не соответствует правилам языка.»</p>
  <p id="y6bV">Это разные проблемы. Например: <code>int age = -10;</code></p>
  <p id="sKah">Программа может успешно скомпилироваться. Но с точки зрения бизнес-логики это может быть ошибкой. Компилятор не знает, что возраст человека не может быть отрицательным. Он проверяет язык Java, а не ваши бизнес-правила.</p>
  <p id="SgNN">Теперь другой пример: <code>int age = ;</code></p>
  <p id="lcup">Здесь программа не скомпилируется. Почему? Не потому что компилятору не понравилось значение. Не потому что он считает вашу идею плохой. А потому что конструкция нарушает правила языка. После знака присваивания должно находиться значение. Это не мнение. Это правило.</p>
  <p id="nHNs"><strong>Компилятор работает внутри определенной системы</strong></p>
  <p id="01n5">Чтобы понять, почему компилятор не ошибается, нужно понять его границы.</p>
  <p id="Eal0">Представим судью футбольного матча. Его задача — следить за соблюдением правил игры. Если игрок взял мяч руками, судья фиксирует нарушение. Но судья не может сказать: «Мне кажется, эта команда сегодня играет некрасиво.». Это уже не его задача. Он работает внутри определенной системы правил. То же самое делает компилятор.</p>
  <p id="l4dW">У Java есть правила:</p>
  <ul id="Qtdx">
    <li id="QY80">как объявляются переменные;</li>
    <li id="bdOF">как создаются классы;</li>
    <li id="Pqst">какие типы данных можно использовать;</li>
    <li id="lgm7">какие операции допустимы;</li>
    <li id="6HaN">как должны быть построены конструкции языка.</li>
  </ul>
  <p id="VdM1">Компилятор проверяет именно это.</p>
  <p id="dOUk">Он не оценивает:</p>
  <ul id="a65b">
    <li id="vFBf">хорошая ли архитектура;</li>
    <li id="XUMT">понятны ли имена переменных;</li>
    <li id="2Oiq">удобно ли будет поддерживать этот код через год;</li>
    <li id="EoGd">правильно ли вы выбрали структуру приложения.</li>
  </ul>
  <p id="0v3m">Для этого существуют другие инструменты и, главное, мышление разработчика.</p>
  <h3 id="bEKN"><strong>Почему нам кажется, что ошибается компилятор</strong></h3>
  <p id="RKW8">Интересно, что проблема чаще всего находится не в компиляторе, а в наших ожиданиях. Мы думаем: «Я хотел написать одно, а компилятор понял другое.». Но компилятор вообще не пытался понять наше намерение. Он анализировал только то, что мы написали. Рассмотрим пример:</p>
  <pre id="jAFV" data-lang="java">public class User {
    private String name;
    public void setName(String name) {
        name = name;
    }
}
</pre>
  <p id="ygMK">Начинающий разработчик может думать: «Я передал значение в поле объекта.»</p>
  <p id="Zm6B">Но на самом деле код делает другое. Локальная переменная name получает значение самой себя. Компилятор не сообщает ошибку.</p>
  <p id="x5fw">Почему? Потому что с точки зрения Java этот код абсолютно допустим. Язык не нарушен. Проблема находится между ожиданием разработчика и реальным поведением программы. И это очень важный момент. Компилятор не обязан исправлять наше мышление. Он показывает только то, что может проверить.</p>
  <p id="qbE0"><strong>Компилятор как зеркало</strong></p>
  <p id="ybEP">Есть интересная особенность зеркала. Оно не делает человека красивее или некрасивее. Оно просто показывает отражение. Если на лице грязь, зеркало не создает её. Оно только позволяет её увидеть. Компилятор работает похожим образом.</p>
  <p id="e7tH">Он не создает ошибки. Он делает видимыми несоответствия, которые уже существуют в коде. Когда он показывает: <code>cannot find symbol</code>, это означает: «Ты обращаешься к тому, чего система не знает.»</p>
  <p id="NG6E">Когда он показывает:<code> incompatible types</code>, это означает: «Ты пытаешься соединить вещи, которые не соответствуют друг другу.»</p>
  <p id="o1Rc">Когда он показывает: <code>&#x27;;&#x27; expected</code>, это означает: «Структура программы нарушена.»</p>
  <p id="9tth">Компилятор не говорит: «Ты плохой программист.»</p>
  <p id="bewz">Он говорит: «Посмотри сюда. Здесь есть противоречие.»</p>
  <h3 id="A9F9"><strong>Ошибка как момент обучения</strong></h3>
  <p id="p4gd">Одна из главных особенностей начинающих разработчиков — желание как можно быстрее избавиться от ошибки. Появилась красная строка - нужно срочно убрать её. Но если просто механически исправлять ошибки, развитие будет медленным.</p>
  <p id="x102">Гораздо полезнее задать вопрос: <strong>«Почему компилятор считает это неправильным?»</strong></p>
  <p id="c8a7">Например, ошибка: <code>String cannot be converted to int</code></p>
  <p id="m992">Можно быстро исправить.</p>
  <p id="78kW">Но можно остановиться и понять:</p>
  <ul id="NlJO">
    <li id="m2Lq">что такое типы данных;</li>
    <li id="Z6Ha">почему Java строго проверяет типы;</li>
    <li id="51Y3">почему некоторые преобразования опасны.</li>
  </ul>
  <p id="xAsD">Тогда ошибка превращается из препятствия в урок.</p>
  <p id="KRca"><strong>Доверие к обратной связи</strong></p>
  <p id="72dk">Хороший разработчик отличается не тем, что он никогда не получает ошибок. Наоборот, опытные разработчики постоянно получают ошибки. Они меняют код. Запускают тесты. Смотрят логи. Получают новые сообщения.</p>
  <p id="eW6D">Разница только в отношении. Новичок думает: «Почему система мешает мне написать код?»</p>
  <p id="UNcP">Опытный разработчик думает: «Что система пытается мне показать?»</p>
  <p id="LrSL">Это изменение мышления является одним из самых важных переходов в профессии.</p>
  <p id="2v3b"><strong>Компилятор не против разработчика</strong></p>
  <p id="bd0I">Иногда кажется, что между человеком и компьютером существует борьба. Разработчик пытается заставить программу работать. Компилятор мешает. Но это неправильный взгляд. Компилятор находится на стороне разработчика. Он первый, кто говорит: «Здесь есть проблема.»</p>
  <p id="pNKJ">Не после того, как ошибка попала к пользователю. Не после того, как приложение упало в production. А в момент, когда исправление занимает несколько секунд. Это невероятно ценный союзник.</p>
  <p id="aqto"><strong>Главный урок</strong></p>
  <p id="9I9o">Компилятор никогда не ошибается не потому, что он идеален, а потому, что он честно выполняет свою задачу. Он не пытается угадать, не пытается оправдать, не пытается сделать вид, что всё хорошо. Он показывает реальность такой, какая она есть. И именно этому разработчик должен учиться. Не бороться с обратной связью. Не защищать свои предположения, а смотреть, проверять, понимать. Потому что путь хорошего разработчика начинается не с умения писать много кода. Он начинается с умения видеть, где твое понимание мира расходится с реальностью.</p>
  <p id="vSkI"><strong>Обратная связь как главный инструмент обучения</strong></p>
  <p id="3vma">Представьте человека, который решил научиться играть на гитаре. Он смотрит несколько уроков, запоминает положение пальцев, читает о технике игры. Но никогда не берет инструмент в руки. Через месяц он может знать много теории. Он будет понимать, что такое аккорды. Он сможет объяснить, как работает перебор. Но когда он попробует сыграть первую мелодию, пальцы не попадут на нужные струны.</p>
  <p id="ML2J">Почему? Потому что между знанием и умением существует огромная разница. Чтобы научиться чему-либо, человеку нужна обратная связь. Он должен сделать действие, получить результат, понять разницу между ожидаемым и реальным, изменить действие, повторить.</p>
  <p id="z1ss">Именно этот цикл превращает новичка в специалиста. В программировании происходит то же самое.</p>
  <p id="2wQ0"><strong>Написать код — это только начало</strong></p>
  <p id="1YzM">Начинающие разработчики часто представляют процесс создания программы так:</p>
  <ol id="FBPr">
    <li id="E6mm">Подумать.</li>
    <li id="KGEv">Написать правильный код.</li>
    <li id="7gAi">Запустить программу.</li>
    <li id="nOuR">Получить результат.</li>
  </ol>
  <p id="ccOr">Как будто хороший разработчик сразу видит правильное решение. Но реальная разработка выглядит иначе:</p>
  <ol id="hHNF">
    <li id="FN8B">Предположить.</li>
    <li id="IOT7">Написать код.</li>
    <li id="xHIo">Получить обратную связь.</li>
    <li id="NYyo">Найти несоответствие.</li>
    <li id="njSI">Исправить.</li>
    <li id="Rvrz">Повторить.</li>
  </ol>
  <p id="9Vye">Программирование — это не процесс угадывания правильного ответа. Это процесс постоянного уточнения своего понимания.</p>
  <h3 id="Ngjd"><strong>Компилятор как первый учитель</strong></h3>
  <p id="HgpG">Когда начинающий разработчик видит ошибку компиляции, первая реакция часто негативная. Кажется, что программа мешает двигаться дальше. Но если посмотреть глубже, происходит обратное. Компилятор дает то, что является самым ценным ресурсом в обучении — мгновенную обратную связь.</p>
  <p id="qaTw">Представьте другой вариант. Вы написали программу. Она выглядит правильно. Вы отправили её пользователям. Через неделю кто-то сообщает: «При определённых условиях приложение падает.»</p>
  <p id="DBOr">Вы начинаете искать проблему. Оказывается, ошибка была в одной строке.</p>
  <p id="CJ7N">Но за это время:</p>
  <ul id="6CKG">
    <li id="9ki3">пользователи столкнулись с проблемой;</li>
    <li id="x9Nm">команда потратила время на поиск причины;</li>
    <li id="7vA4">возможно, были потеряны данные;</li>
    <li id="UlUv">кто-то получил негативный опыт.</li>
  </ul>
  <p id="MT1R">Теперь сравним. Та же самая ошибка, но обнаруженная компилятором: int age = ; - исправляется за несколько секунд. Одна и та же проблема может иметь совершенно разную цену в зависимости от того, когда она обнаружена. Поэтому хороший инженер стремится получать обратную связь как можно раньше.</p>
  <h3 id="TWnY"><strong>Быстрая обратная связь ускоряет обучение</strong></h3>
  <p id="E8nZ">Есть простой принцип:</p>
  <p id="v8Ao"><strong>Чем короче промежуток между действием и результатом, тем быстрее обучение.</strong></p>
  <p id="wXz6">Если человек изучает иностранный язык и сразу получает исправление произношения, он быстро меняется. Если он годами говорит неправильно, а потом узнает об ошибке, исправление становится сложнее.</p>
  <p id="Vmqt">В программировании так же.</p>
  <p id="haQW">Цикл:</p>
  <p id="ehKj">Написал код --&gt; Компилятор проверил --&gt; Получил ошибку --&gt; Исправил - может занимать несколько секунд. За день разработчик проходит этот цикл десятки и сотни раз. Каждый такой цикл немного изменяет его понимание языка.</p>
  <p id="GERc"><strong>Почему опытные разработчики любят ошибки</strong></p>
  <p id="Ou65">Это кажется странным. Почему человек с большим опытом может спокойно смотреть на ошибку, которая расстроила бы новичка? Потому что опытный разработчик видит в ней информацию. Ошибка сообщает: «Вот граница твоего текущего понимания.»</p>
  <p id="t1WY">Например:</p>
  <p id="dF0J">Новичок видит:<code> incompatible types</code> - и думает: «Java сложная.»</p>
  <p id="hV2W">Опытный разработчик видит: «Я передал значение одного типа туда, где ожидается другой. Нужно проверить модель данных.»</p>
  <p id="DUzU">Разница не в знаниях. Разница в отношении к обратной связи. Один человек воспринимает ошибку как препятствие. Другой — как подсказку.</p>
  <p id="wPoi"><strong>Ошибка показывает карту неизвестного</strong></p>
  <p id="toqk">Когда человек изучает новую область, перед ним существует большая территория неизвестного. В начале она выглядит как белое пятно.</p>
  <p id="XV3t">Он знает: «Я не понимаю, почему это работает.», «Я не знаю, почему появляется эта ошибка.», «Я не понимаю, как связаны эти классы.»</p>
  <p id="yzc5">Каждая ошибка немного уменьшает эту область. Она показывает: «Вот здесь есть место, которое тебе нужно изучить.»</p>
  <p id="doS0">В этом смысле ошибки являются не врагами обучения. Они являются указателями. Без них человек может долго двигаться в неправильном направлении.</p>
  <p id="obxo"><strong>Разница между оценкой и обратной связью</strong></p>
  <p id="ElVS">Очень важно разделять две вещи. Оценка говорит: «Ты сделал плохо.»</p>
  <p id="NOOu">Обратная связь говорит: «Вот что произошло. Вот где есть несоответствие.»</p>
  <p id="PDrH">Первая направлена на человека. Вторая направлена на действие. И именно вторая помогает развиваться. Компилятор никогда не говорит: «Ты плохой программист.»</p>
  <p id="e1JE">Он говорит: «В строке 5 ожидается выражение типа String, но получено значение другого типа.»</p>
  <p id="LdCa">Это принципиальная разница. Проблема находится не внутри человека. Проблема находится в конкретном месте системы. А значит, её можно изучить и исправить.</p>
  <h3 id="R96m"><strong>Дзен и искусство наблюдать результат</strong></h3>
  <p id="UYzV">В дзен есть практика возвращения к непосредственному опыту. Не к ожиданиям. Не к мыслям о том, каким что-то должно быть. А к тому, что происходит прямо сейчас. В разработке это означает:</p>
  <p id="mqwS">Не: «Моя программа должна работать.»</p>
  <p id="tMEH">А: «Что показывает мне программа сейчас?»</p>
  <p id="1HpW">Не: «Компилятор мешает.»</p>
  <p id="tbrU">А: «Какую информацию он мне дает?»</p>
  <p id="X1j3">Такой подход меняет отношение к разработке. Ты перестаешь защищать свой код. Ты начинаешь его исследовать.</p>
  <p id="tUXW"><strong>Разработчик растет через диалог</strong></p>
  <p id="M6IY">Хороший разработчик не тот, кто пишет код без ошибок. Таких людей не существует. Хороший разработчик — это человек, который умеет быстро получать информацию о своих ошибках и использовать её. Он вступает в постоянный диалог с системой:</p>
  <ul id="9veK">
    <li id="csRx">Разработчик пишет.</li>
    <li id="iksp">Компилятор отвечает.</li>
    <li id="HAk2">Разработчик анализирует.</li>
    <li id="b6Qj">Программа меняется.</li>
  </ul>
  <p id="69ft">И постепенно между человеком и компьютером появляется понимание.</p>
  <p id="On5M"><strong>Главный урок</strong></p>
  <p id="s4No">Компилятор — это не стена между человеком и программой. Это первый собеседник. Он первым сообщает: «Здесь что-то не совпадает.»</p>
  <p id="E2S3">Он делает это быстро, точно и без эмоций. И чем раньше разработчик научится воспринимать ошибки не как поражение, а как обратную связь, тем быстрее он будет расти. Потому что обучение начинается не тогда, когда мы получаем правильный ответ. Оно начинается тогда, когда мы видим разницу между тем, что ожидали, и тем, что произошло на самом деле.</p>
  <h3 id="kIZt"><strong>Учимся читать сообщения компилятора</strong></h3>
  <p id="gEYB">Для начинающего разработчика ошибка компилятора часто выглядит как предупреждение на неизвестном языке. На экране появляется несколько строк:</p>
  <ul id="FgL6">
    <li id="GAbB"><code>error: cannot find symbol</code></li>
    <li id="A84e"><code>symbol: variable username</code></li>
    <li id="MhBu"><code>location: class Main</code></li>
  </ul>
  <p id="xVzP">И первая мысль: «Что это вообще значит?»</p>
  <p id="mGg3">Мозг пытается воспринимать сообщение целиком. Но это неправильный подход. Ошибка компилятора — это не текст, который нужно просто понять от начала до конца. Это отчет. В нем есть конкретная информация:</p>
  <ul id="y3Ta">
    <li id="2dyP">где возникла проблема;</li>
    <li id="QIoq">что именно компилятор ожидал;</li>
    <li id="HHXX">что он получил вместо этого;</li>
    <li id="pu95">какую часть программы он не смог понять.</li>
  </ul>
  <p id="Fy0J">Задача разработчика — научиться извлекать эту информацию.</p>
  <p id="jOxx"><strong>Ошибка как сообщение, а не как приговор</strong></p>
  <p id="qJHJ">Начинающий разработчик часто смотрит на ошибку так: «Программа не работает.»</p>
  <p id="9omE">Но это слишком общее утверждение. На самом деле компилятор сообщает гораздо меньше: «Я не могу продолжить обработку программы, потому что встретил ситуацию, которая нарушает правила Java.»</p>
  <p id="u0w6">Это совсем другое. Компилятор не говорит, что вся программа плохая. Он указывает конкретное место, где возникло противоречие. Поэтому первое правило:</p>
  <p id="y5cw"><strong>Никогда не начинайте исправлять ошибку, пока не поняли, что именно сообщает компилятор.</strong></p>
  <p id="UO6n"><strong>Структура сообщения компилятора</strong></p>
  <p id="osNh">Рассмотрим простой пример. Код:</p>
  <pre id="T9h6" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(message);
    }
}
</pre>
  <p id="nNgb">Запускаем компиляцию. Получаем:</p>
  <pre id="3hEu">Main.java:5: error: cannot find symbol
        System.out.println(message);
                           ^
  symbol:   variable message
  location: class Main</pre>
  <p id="AW6o">На первый взгляд выглядит страшно. Но разберем его по частям.</p>
  <p id="Oofi"><strong>Первая часть: где произошла ошибка</strong></p>
  <p id="PQiP"><code>Main.java:5</code></p>
  <p id="WX4K">Это самое первое, на что нужно смотреть.</p>
  <p id="tXGr">Компилятор говорит:</p>
  <p id="d3Mn">Файл: Main.java. Строка: 5</p>
  <p id="ZGV3">Именно там он обнаружил проблему. Но важно помнить: Место обнаружения ошибки не всегда является местом её возникновения.</p>
  <p id="hDJA">Иногда причина находится несколькими строками выше.</p>
  <p id="5MZw"><strong>Вторая часть: описание проблемы</strong></p>
  <p id="JoKD"><code>cannot find symbol</code></p>
  <p id="npNz">Это одна из самых частых ошибок Java. Дословно: «Не могу найти символ.»</p>
  <p id="88e2">Но что такое символ? Для компилятора символ — это любой элемент программы:</p>
  <ul id="C2VP">
    <li id="MZOq">переменная;</li>
    <li id="xht1">класс;</li>
    <li id="15tH">метод;</li>
    <li id="svMW">поле.</li>
  </ul>
  <p id="oLVW">В нашем случае он не нашел переменную: <code>message</code></p>
  <p id="JLys"><strong>Третья часть: детали</strong></p>
  <p id="M1nZ"><code>symbol: variable message</code></p>
  <p id="Exzl">Компилятор уточняет: «Я искал переменную с именем message.»</p>
  <p id="rAd9">А ниже: <code>location: class Main</code> - говорит: «Я искал её внутри класса Main.»</p>
  <p id="lpTq">Теперь проблема становится очевидной. Мы написали: <code>System.out.println(message);</code>. Но нигде не создали: <code>String message = &quot;Hello&quot;;</code></p>
  <p id="tuxE">Исправленный вариант:</p>
  <pre id="8wCp" data-lang="java">public class Main {
    public static void main(String[] args) {
        String message = &quot;Hello&quot;;
        System.out.println(message);
    }
}
</pre>
  <p id="cuup">Компиляция пройдет успешно.</p>
  <p id="cgRx"><strong>Ошибка №1. Пропущена точка с запятой</strong></p>
  <p id="P7Tf">Одна из первых ошибок каждого Java-разработчика. Код:</p>
  <pre id="vvYe" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;Hello&quot;)
    }
}
</pre>
  <p id="tYR3">Сообщение: <code>error: &#x27;;&#x27; expected</code></p>
  <p id="k773">Компилятор говорит: «Я ожидал увидеть точку с запятой.»</p>
  <p id="kvAn">Новичок может подумать: «Но почему он показывает ошибку возле закрывающей скобки?»</p>
  <p id="7Bg6">Потому что компилятор читает код последовательно. Он увидел: <code>System.out.println(&quot;Hello&quot;)</code> - и ожидает: <code>;</code></p>
  <p id="nWsd">Но вместо этого получил: }</p>
  <p id="1lhq">То есть закрытие блока. Компилятор сообщает не: «Ошибка в фигурной скобке.». Он сообщает: «К этому моменту я ожидал завершение предыдущей команды.». Исправление: <code>System.out.println(&quot;Hello&quot;);</code></p>
  <p id="In9c"><strong>Ошибка №2. Неправильный тип данных</strong></p>
  <p id="DySW">Код:</p>
  <pre id="XxgV" data-lang="java">public class Main {
    public static void main(String[] args) {
        int age = &quot;35&quot;;
    }
}
</pre>
  <p id="Srzh">Ошибка: <code>incompatible types: String cannot be converted to int</code></p>
  <p id="UrMi">Разберем.</p>
  <p id="4JP1"><code>incompatible types</code> означает: «Типы не совместимы.»</p>
  <p id="rNWl">Дальше:<code> String cannot be converted to int</code> - означает: «Текст нельзя автоматически превратить в число.»</p>
  <p id="JDmS">Почему? Потому что: &quot;35&quot; и 35 для Java разные вещи.</p>
  <p id="iNSJ">Первое: String - это текст. Второе: int - это число. Для человека они похожи. Для программы это разные типы данных. Правильный вариант: <code>int age = 35;</code></p>
  <p id="2a8O"><strong>Ошибка №3. Метод не существует</strong></p>
  <p id="2dVv">Код:</p>
  <pre id="knZD" data-lang="java">public class Main {
    public static void main(String[] args) {
        System.out.printl(&quot;Hello&quot;);
    }
}
</pre>
  <p id="OV5c">Ошибка: <code>cannot find symbol symbol: method printl(String)</code></p>
  <p id="zMkT">Что произошло?</p>
  <p id="kFYc">Мы написали: <code>printl</code>. Но в классе <code>System.out</code> такого метода нет. Есть <code>println</code>. Одна маленькая буква изменила смысл. Компилятор не может сказать: «Наверное, вы имели в виду println.»</p>
  <p id="1OKm">Почему? Потому что иногда похожие имена означают разные вещи. Если бы Java постоянно угадывала, ошибки становились бы непредсказуемыми. Поэтому компилятор строго сообщает: «Такого метода я не знаю.»</p>
  <p id="yGwp"><strong>Ошибка №4. Класс не найден</strong></p>
  <p id="Z4b2">Код:</p>
  <pre id="pbck" data-lang="java">ArrayList&lt;String&gt; names = new ArrayList&lt;&gt;();</pre>
  <p id="fEX1">Ошибка: <code>cannot find symbol. symbol: class ArrayList</code></p>
  <p id="hHPw">Компилятор говорит: «Я не знаю, что такое ArrayList.»</p>
  <p id="UZB0">Почему? Потому что этот класс находится в другой части Java и требует импорта.</p>
  <p id="VZlb">Нужно добавить: </p>
  <pre id="0owu" data-lang="java">import java.util.ArrayList;</pre>
  <p id="zadz">Теперь компилятор понимает: «Хорошо, этот класс существует.»</p>
  <h3 id="lmKH"><strong>Как правильно читать ошибки</strong></h3>
  <p id="GRQI">Есть простой алгоритм. Когда появилась ошибка компиляции:</p>
  <p id="nZ9Z"><strong>1. Найди первую ошибку</strong></p>
  <p id="C67c">Если ошибок несколько, исправляй первую. Одна ошибка может создавать десятки последующих.</p>
  <p id="NMnw"><strong>2. Посмотри строку</strong></p>
  <p id="FkY1">Например: <code>Main.java:10</code>. Открой именно это место.</p>
  <p id="iOWz"><strong>3. Прочитай ключевые слова</strong></p>
  <p id="nS3d">Не пытайся понять всё сразу. Ищи главное:</p>
  <ul id="Ls1O">
    <li id="X3Ar"><code>cannot find symbol</code> - что-то не найдено.</li>
    <li id="thuR"><code>incompatible types</code> - несовместимые типы.</li>
    <li id="y3Wq"><code>&#x27;;&#x27; expected</code> - пропущен символ.</li>
    <li id="cIYX"><code>method does not exist</code> - такого метода нет.</li>
  </ul>
  <p id="Z9kp"><strong>4. Проверь ожидания</strong></p>
  <p id="V43w">Задай себе вопрос: «Что я думал, что произойдет?»</p>
  <p id="Myqr">И второй: «Что реально написано в коде?»</p>
  <p id="Uznl">Очень часто ошибка находится именно между этими двумя вещами.</p>
  <p id="KWbQ"><strong>Ошибки как разговор</strong></p>
  <p id="lwWv">Со временем сообщения компилятора перестают выглядеть как угрозы. Они превращаются в диалог. Компилятор говорит: «Я не нашел этот класс.». Разработчик отвечает: «Точно, я забыл импорт.»</p>
  <p id="aE64">Компилятор говорит: «Типы не совпадают.». Разработчик отвечает: «Я перепутал строку и число.»</p>
  <p id="ScAw">Компилятор говорит: «Ожидался символ.». Разработчик отвечает: «Я пропустил часть конструкции.»</p>
  <p id="DLhs">Это не борьба. Это совместная работа.</p>
  <p id="tpW4"><strong>Практика внимательного наблюдения</strong></p>
  <p id="EbAa">В дзен есть принцип: сначала увидеть, потом действовать.</p>
  <p id="j3KL">В разработке это означает: не бросаться сразу менять код. Сначала посмотреть, прочитать, понять.</p>
  <p id="tQgh">Ошибка уже содержит часть ответа. Она показывает место, где ваше представление о программе отличается от реального состояния. Компилятор не прячет проблему. Он подсвечивает её. Нужно только научиться смотреть.</p>
  <p id="y9tU"><strong>Главный урок</strong></p>
  <p id="r8FM">Сообщение компилятора — это не препятствие на пути разработчика. Это карта. Она показывает неизвестную территорию. Каждая ошибка говорит: «Здесь есть место, которое нужно понять.» И каждый раз, когда разработчик спокойно читает ошибку вместо того, чтобы раздражаться, происходит маленькое изменение мышления. Он перестает бороться с программой. Он начинает её исследовать. А именно с этого начинается настоящее мастерство разработки.</p>
  <p id="zRlQ">Не с умения писать код без ошибок. А с умения видеть, понимать и исправлять их.</p>
  <h3 id="famp"><strong>Что изменится в вашем мышлении после этой главы</strong></h3>
  <p id="odXN">В начале этой главы компилятор казался препятствием. Вы пишете код. Нажимаете кнопку запуска. Вместо результата появляется красный текст. Кажется, что что-то пошло не так. Кажется, что система мешает вам двигаться дальше. Но теперь мы можем посмотреть на это иначе.</p>
  <p id="eJid">Компилятор не является строгим проверяющим, который ищет ваши ошибки. Он является первым инструментом наблюдения. Он показывает разницу между тем, что вы хотели создать, и тем, что вы действительно написали. И именно в этой разнице находится развитие разработчика.</p>
  <p id="EtUW"><strong>Вы перестаете воспринимать ошибки как поражение</strong></p>
  <p id="EPXx">Самое первое изменение происходит внутри. Раньше ошибка могла вызывать раздражение: «Почему это опять не работает?»</p>
  <p id="lOeV">Теперь появляется другой вопрос: «Что именно система пытается мне показать?»</p>
  <p id="PnDQ">Это небольшое изменение формулировки меняет весь процесс обучения. В первом случае вы боретесь с ошибкой. Во втором — исследуете её. Разработчик, который боится ошибок, старается их избегать. Разработчик, который понимает ошибки, использует их.</p>
  <p id="MFiU"><strong>Вы начинаете доверять фактам больше, чем предположениям</strong></p>
  <p id="MvjK">Человек очень легко создает историю в своей голове. Мы предполагаем: «Переменная точно содержит это значение.», «Этот метод точно вызывается.», «Этот объект точно создан.»</p>
  <p id="hHjH">Но программа не работает с предположениями. Она работает с конкретным состоянием. Компилятор становится первым учителем, который возвращает вас из мира догадок в мир фактов. Он напоминает: «Не думай о том, что должно происходить. Посмотри, что происходит на самом деле.»</p>
  <p id="1HO7">Это один из важнейших навыков профессионального разработчика.</p>
  <p id="LrfJ"><strong>Вы начинаете читать программу глазами системы</strong></p>
  <p id="2vLL">Новичок смотрит на код и видит смысл, который хотел вложить автор.</p>
  <p id="ojhp">Он читает: <code>int age = &quot;35&quot;;</code> и думает: «Ну понятно, возраст равен 35.»</p>
  <p id="xroL">Но компилятор видит другое: «Переменная типа int получает значение типа String. Эти вещи несовместимы.»</p>
  <p id="3Tky">Постепенно разработчик учится переключаться между двумя взглядами.</p>
  <ul id="jEgG">
    <li id="jtWy">Первый: <strong>Что я хотел выразить?</strong></li>
    <li id="sBvh">Второй: <strong>Что реально видит система?</strong></li>
  </ul>
  <p id="kzbD">Именно между этими двумя точками рождается профессиональное мышление.</p>
  <p id="HuFe"><strong>Вы перестаете спорить с инструментами</strong></p>
  <p id="OjGX">У начинающего разработчика часто возникает желание доказать системе свою правоту.</p>
  <p id="DhCN">«Но я же имел в виду другое.»</p>
  <p id="boxz">«Но это должно работать.»</p>
  <p id="Lwlw">«Почему Java такая сложная?»</p>
  <p id="i4u6">Но компьютер не умеет читать намерения. Он работает с правилами. И в этом есть огромная ценность. Если бы система соглашалась с нами каждый раз, когда мы уверены в своей правоте, ошибки находились бы намного позже. Компилятор не спорит. Он показывает.</p>
  <p id="Vldw"><strong>Вы начинаете видеть программирование как диалог</strong></p>
  <p id="gHfF">Раньше процесс мог выглядеть так: написал код → получил результат.</p>
  <p id="evML">Теперь появляется более точная картина: создал предположение → получил обратную связь → изменил понимание → улучшил решение.</p>
  <p id="LMoW">Разработка становится разговором между человеком и системой. Вы задаете вопрос кодом. Компилятор отвечает. Вы анализируете ответ. Следующий вариант программы становится лучше.</p>
  <p id="mONk"><strong>Вы понимаете ценность маленьких ошибок</strong></p>
  <p id="QzfF">Большая ошибка редко появляется внезапно. Обычно она начинается с маленького несоответствия, которое осталось незамеченным: пропущенный символ, неверный тип, неправильное имя, ошибочное предположение. Компилятор позволяет увидеть эти моменты сразу. И это один из главных принципов инженерии:</p>
  <p id="c3lq"><strong>Чем раньше обнаружена проблема, тем меньше цена её исправления.</strong></p>
  <p id="WAkP">Хороший разработчик не тот, у кого нет ошибок. Хороший разработчик тот, кто умеет обнаруживать их быстро.</p>
  <p id="Otj6"><strong>Вы начинаете практиковать «ум разработчика»</strong></p>
  <p id="OJ80">В дзен есть понятие внимательного наблюдения. Не убегать от того, что происходит. Не пытаться заменить реальность своими ожиданиями. Просто увидеть.</p>
  <p id="GgwO">В программировании это означает: Посмотреть на ошибку. Прочитать сообщение. Понять причину. Изменить код. Проверить результат. Снова посмотреть.</p>
  <p id="FgSa">Это кажется простым. Но именно из таких маленьких действий формируется мастерство.</p>
  <p id="tTm3"><strong>Главный вывод первой главы</strong></p>
  <p id="0gXv">Компилятор никогда не ошибается не потому, что он совершенен, а потому, что он честно показывает состояние вашей программы.</p>
  <p id="89Vz">Он не враг, не препятствие. Не строгий учитель, который ставит оценки. Он зеркало.</p>
  <p id="nj6d">И если вы научитесь смотреть в это зеркало спокойно, без раздражения и защиты, вы получите один из самых важных навыков разработчика: <strong>способность видеть реальность программы такой, какая она есть.</strong></p>
  <p id="zG5S">Это первый шаг на пути разработчика. Не писать больше кода. Не знать больше команд. А научиться видеть. Потому что прежде чем изменить систему, нужно сначала увидеть её.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/B66f8eybMi0</guid><link>https://teletype.in/@alexbrin/B66f8eybMi0?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/B66f8eybMi0?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>Подготовка к собесу</title><pubDate>Fri, 29 Mar 2024 10:16:23 GMT</pubDate><description><![CDATA[Классификация по запуску кода на исполнение:]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#J6P2">ОСНОВНЫЕ ВИДЫ ТЕСТИРОВАНИЯ ПО</a></li>
      <li class="m_level_2"><a href="#pgUU">Все классификации тестирования:</a></li>
      <li class="m_level_2"><a href="#zXou">Классификация по запуску кода на исполнение:</a></li>
      <li class="m_level_2"><a href="#MChp">Классификация по доступу к коду и архитектуре:</a></li>
      <li class="m_level_2"><a href="#VZBu">Классификация по уровню детализации приложения (Пирамида тестирования):</a></li>
      <li class="m_level_2"><a href="#IP8i">Классификация по принципам работы с приложением</a></li>
      <li class="m_level_2"><a href="#JUF6">Классификация по целям тестирования</a></li>
      <li class="m_level_2"><a href="#fGFp">Функциональное тестирование</a></li>
      <li class="m_level_2"><a href="#hbBn">Нефункциональное тестирование</a></li>
      <li class="m_level_2"><a href="#8MiB">Классификация по цели тестирования</a></li>
      <li class="m_level_1"><a href="#VHsg">ТЕСТИРОВАНИЕ И QA/QC, ЖИЗНЕННЫЕ ЦИКЛЫ</a></li>
      <li class="m_level_2"><a href="#XduG">Что такое тестирование программного обеспечения?</a></li>
      <li class="m_level_2"><a href="#5w1w">Что такое контроль качества и обеспечение качества?</a></li>
      <li class="m_level_2"><a href="#qP6f">7 принципов тестирования</a></li>
      <li class="m_level_2"><a href="#tf5H">Что такое SDLC (Жизненный цикл разработки программного продукта)?</a></li>
      <li class="m_level_2"><a href="#nMGO">Что такое STLC Жизненный цикл тестирования программного продукта?</a></li>
      <li class="m_level_1"><a href="#qNuH">ВСЕ О ТЕСТ-ДИЗАЙНЕ</a></li>
      <li class="m_level_2"><a href="#1bKC">Что такое Тест-дизайн?</a></li>
      <li class="m_level_2"><a href="#zELi">Цели тест-дизайна:</a></li>
      <li class="m_level_2"><a href="#cXjz">Техники тест-дизайна:</a></li>
      <li class="m_level_1"><a href="#UdkJ">ДОКУМЕНТАЦИЯ (кейсы, листы, репорты)</a></li>
      <li class="m_level_2"><a href="#F14V">Чек-лист</a></li>
      <li class="m_level_2"><a href="#Tf4q">Тест-кейс</a></li>
      <li class="m_level_2"><a href="#ppNO">Тестовый набор</a></li>
      <li class="m_level_2"><a href="#qt2i">Баг-репорт</a></li>
      <li class="m_level_1"><a href="#pUOL">КЛИЕНТ - СЕРВЕРНАЯ АРХИТЕКТУРА</a></li>
      <li class="m_level_2"><a href="#tbDn">2 вида клиент-серверной архитектуры:</a></li>
      <li class="m_level_2"><a href="#2HJg">Что включает в себя КСА:</a></li>
      <li class="m_level_2"><a href="#uBNK">Существует 2 вида клиентов:</a></li>
      <li class="m_level_2"><a href="#yGzA">Плюсы и Минусы Монолитной Архитектуры:</a></li>
      <li class="m_level_2"><a href="#Jdm6">Плюсы и Минусы Микросервисной Архитектуры:</a></li>
      <li class="m_level_1"><a href="#rbG1">HTTP ПРОТОКОЛЫ</a></li>
      <li class="m_level_2"><a href="#7cYE">Метод HTTP</a></li>
      <li class="m_level_2"><a href="#Oe12">Коды состояния запроса</a></li>
      <li class="m_level_2"><a href="#yS55">Передача протокола осуществляется по Модели TCP/IP.</a></li>
      <li class="m_level_1"><a href="#hG9v">SOAP И REST</a></li>
      <li class="m_level_2"><a href="#pKJZ">SOAP</a></li>
      <li class="m_level_2"><a href="#wpLy">REST</a></li>
      <li class="m_level_2"><a href="#7Qnf">Что выбрать SOAP или REST?</a></li>
      <li class="m_level_1"><a href="#KQCp">POSTMAN И API</a></li>
      <li class="m_level_1"><a href="#huwB">МОБИЛЬНОЕ ТЕСТИРОВАНИЕ</a></li>
      <li class="m_level_2"><a href="#ikK4">Типы мобильных приложений:</a></li>
      <li class="m_level_2"><a href="#AsBl">Тестирование и особенности тестирования мобильных приложений</a></li>
      <li class="m_level_2"><a href="#UnHC">Зависимости мобильного тестирования:</a></li>
      <li class="m_level_1"><a href="#262c">ЛОКАЛИЗАЦИЯ БАГА</a></li>
      <li class="m_level_1"><a href="#msVl">DEVTOOLS</a></li>
      <li class="m_level_1"><a href="#NaF9">СНИФФЕРЫ</a></li>
      <li class="m_level_2"><a href="#9B2P">Charles</a></li>
      <li class="m_level_1"><a href="#7jzb">SQL</a></li>
      <li class="m_level_2"><a href="#10ok">Первичный и внешний ключи:</a></li>
      <li class="m_level_2"><a href="#aZ9O">Типы взаимосвязи таблиц SQL</a></li>
      <li class="m_level_2"><a href="#t2ca">Inner Join и Outer Join</a></li>
      <li class="m_level_2"><a href="#h0ue">Основные запросы:</a></li>
      <li class="m_level_1"><a href="#D7DO">KAFKA, СИНХРОННОЕ И АСИНХРОННОЕ ВЗАИМОДЕЙСТВИЕ</a></li>
      <li class="m_level_2"><a href="#19jn">Kafka</a></li>
      <li class="m_level_2"><a href="#p6i6">Синхронное взаимодействие:</a></li>
      <li class="m_level_2"><a href="#mXjN">Асинхронное взаимодействие:</a></li>
    </ul>
  </nav>
  <h2 id="J6P2">ОСНОВНЫЕ ВИДЫ ТЕСТИРОВАНИЯ ПО</h2>
  <h3 id="pgUU">Все классификации тестирования:</h3>
  <p id="cCRU"><strong>Классификация по запуску кода на исполнение:</strong></p>
  <ul id="ASQV">
    <li id="lh8M">Статическое тестирование</li>
    <li id="9N47">Динамическое тестирование</li>
  </ul>
  <p id="xWe6"><strong>Классификация по доступу к коду и архитектуре:</strong></p>
  <ul id="zaNz">
    <li id="Frlz">Тестирование белого ящика</li>
    <li id="FZWD">Тестирование серого ящика</li>
    <li id="KW1A">Тестирование чёрного ящика</li>
  </ul>
  <p id="Hoov"><strong>Классификация по уровню детализации приложения (Пирамида тестирования):</strong></p>
  <ul id="bcfo">
    <li id="Lqru">Модульное тестирование или юнит-тестирование (англ. unit testing)</li>
    <li id="R3R2">Интеграционное тестирование (Integration testing)</li>
    <li id="ZfXv">Системное тестирование (System testing)</li>
    <li id="qg5A">Приёмочное тестирование (acceptance test):<br />А) Пользовательское приемное тестирование<br />Б) Эксплуатационное<br />В) На соответствие контракту</li>
  </ul>
  <p id="eW1c"><strong>Классификация по принципам работы с приложением</strong></p>
  <ul id="4fht">
    <li id="UUy4">Позитивное тестирование</li>
    <li id="JosD">Негативное тестирование</li>
  </ul>
  <p id="mjHD"><strong>Классификация по целям тестирования</strong></p>
  <ul id="LeXH">
    <li id="aOHM">Функциональное тестирование</li>
    <li id="cydH">Нефункциональное тестирование</li>
  </ul>
  <p id="5jEn"><strong>Функциональное тестирование</strong></p>
  <ul id="WQy6">
    <li id="fSMq">Smoke test</li>
    <li id="3877">Тестирование критического пути</li>
    <li id="P7I1">Расширенное тестирование</li>
  </ul>
  <p id="yVSH"><strong>Нефункциональное тестирование</strong></p>
  <ul id="FoHE">
    <li id="e6Hm">Тестирование доступности</li>
    <li id="nEQN">Тестирование локализации и интернетизации</li>
    <li id="xEyo">Тестирование безопасности</li>
    <li id="VAQF">Проверка удобства</li>
    <li id="yjD3">Нагрузочное тестирование</li>
    <li id="b7CZ">Стресс-тестирование</li>
    <li id="LElr">Тестирование стабильности</li>
    <li id="lRSS">Инсталляционное тестирование</li>
  </ul>
  <p id="TuXK"><strong>Классификация по цели тестирования</strong></p>
  <ul id="VroH">
    <li id="3roT">Тестирование новой функциональности</li>
    <li id="EGGv">Re-test</li>
    <li id="QHuU">Регрессионное тестирование<br /><strong>Регрессионное тестирование проводится: <br /></strong>- после появления нового билда (новой версии нашего продукта)<br />- тестирование того функционала в котором часто обнаруживаются дефекты<br />- плановое тестирование<br />- того функционала, который часто меняется в ходе разработки</li>
  </ul>
  <hr />
  <h3 id="zXou"><strong>Классификация по запуску кода на исполнение:</strong></h3>
  <ul id="airX">
    <li id="3lut"><strong>Статическое тестирование</strong> — тестирование без запуска кода на исполнение. Это процесс обнаружения и устранения ошибок и дефектов в документации: программного кода компонент, требований, системных спецификаций, функциональных спецификаций, документов проектирования и архитектуры программных систем и их компонентов.</li>
    <li id="FU14"><strong>Динамическое тестирование</strong> — тестирование проводится на работающей системе, не может быть осуществлено без запуска программного кода приложения.<br />Запускаться на исполнение может как код всего приложения целиком (системное тестирование), так и код нескольких взаимосвязанных частей (интеграционное тестирование), отдельных частей и даже отдельные участки кода.</li>
  </ul>
  <h3 id="MChp"><strong>Классификация по доступу к коду и архитектуре:</strong></h3>
  <ul id="zaNz">
    <li id="TPkW"><strong>Тестирование белого ящика</strong> — метод тестирования ПО, который предполагает полный доступ к коду проекта.</li>
    <li id="ODW4"><strong>Тестирование серого ящика</strong> — метод тестирования ПО, который предполагает частичный доступ к коду проекта (комбинация White Box и Black Box методов).</li>
    <li id="E69B"><strong>Тестирование чёрного ящика</strong> — метод тестирования ПО, который не предполагает доступа (полного или частичного) к системе. Основывается на работе исключительно с внешним интерфейсом тестируемой системы.</li>
  </ul>
  <h3 id="VZBu"><strong>Классификация по уровню детализации приложения (Пирамида тестирования):</strong></h3>
  <ol id="ht7D">
    <li id="DQWg"><strong>Модульное тестирование или юнит-тестирование (англ. unit testing)</strong> — проводится для тестирования какого-либо одного логически выделенного и изолированного элемента (модуля) системы в коде. Проводится самими разработчиками, так как предполагает полный доступ к коду.<br /><strong>Модульное тестирование производят сами разработчики, не тестировщики.</strong></li>
    <li id="OmhB"><strong>Интеграционное тестирование (Integration testing)</strong> — тестирование, направленное на проверку корректности взаимодействия нескольких модулей, объединенных в единое целое.<br /><strong>Взаимодействие компонентов, модулей и иных систем между собой. Тестирование части системы, состоящей из 2-х и более модулей.</strong></li>
    <li id="rKlg"><strong>Системное тестирование (System testing)</strong> — тестирование взаимодействия между всеми компонентами системы или разных систем между собой или тестирование интерфейсов, между которыми взаимодействует система. Полная проверка приложения, всех модулей, можно ли пройти весь бизнес путь.</li>
    <li id="cJew"><strong>Приёмочное тестирование</strong> <strong>(acceptance test) — </strong>тестирование на сдаче приемки всего программного продукта или его части Заказчику<br />А) <strong>Пользовательское приемное тестирование (User Acceptance Testing)</strong> – перед релизом собирается группа конечных пользователей, тестируется основной функционал, при наличии дефектов-устраняются.<br />Б)<strong> Эксплуатационное (Operational acceptance testing) </strong>– производится пользователем или администратором в среде, которая имитирует реальные условия эксплуатации ПО, производится тестирование резервного копирования, аварийное восстановление системы, безопасность ПО.<br />В) <strong>На соответствие контракту</strong> – на соответствие гостов, нормативных актов и т.д</li>
  </ol>
  <h3 id="IP8i"><strong>Классификация по принципам работы с приложением</strong></h3>
  <ul id="4fht">
    <li id="sRon"><strong>Позитивное тестирование</strong> — тестирование, при котором используются только корректные данные.</li>
    <li id="tRrK"><strong>Негативное тестирование</strong> — тестирование приложения, при котором используются некорректные данные и выполняются некорректные операции.</li>
  </ul>
  <h3 id="JUF6">Классификация по целям тестирования</h3>
  <ol id="SDrt">
    <li id="irsE"><strong>Функциональное тестирование</strong> – тестирование которое направленно на проверку соответствия функциональных требований ПО к его реальным характеристикам. Подтверждение того, что наш продукт обладает всем функционалом, который требует заказчик.<br /><strong>Функциональное тестирование отвечает на вопрос – что должен делать наш продукт?</strong></li>
    <li id="HK25"><strong>Нефункциональное тестирование</strong> – направленно на проверку соответствия свойств ПО с его нефункциональными требованиями. Тестирование свойств, которые не относятся к функциональности системы – надежность, производительность и т.д.<br /><strong>Нефункциональное тестирование отвечает на вопрос – как это должен делать наш продукт?</strong></li>
  </ol>
  <h3 id="fGFp"><strong>Функциональное тестирование</strong></h3>
  <ol id="qkDU">
    <li id="Ugoy"><strong>Smoke test</strong> — тестирование, которое проводится после появления нового билда . Направлено на проверку готовности разработанного продукта к проведению расширенного тестирования и определения общего качества продукта.<br /><strong>Проверяет заявленную бизнес-логику ПО.</strong></li>
    <li id="6Ofd"><strong>Тестирование критического пути</strong> (critical path) — направлено для проверки функциональности, используемой обычными пользователями во время их повседневной деятельности.<br /><strong>Основной тип тестовых испытаний, во время которого значимые элементы и функции приложения проверяются на предмет правильности работы при их стандартном использовании.</strong></li>
    <li id="IfOq"><strong>Расширенное тестирование</strong> (extended) — направлено на исследование всей заявленной в требованиях функциональности.<br /><strong>Проверка нестандартного использования продукта (например, вводить не корректные логин и пароль в окне авторизации, работать на многих вкладках одновременно, подгрузка файлов недопустимых размеров или форматов. Максимально загружать нашу систему, проводить множество негативных тестов.</strong></li>
  </ol>
  <h3 id="hbBn"><strong>Нефункциональное тестирование</strong></h3>
  <ol id="yej0">
    <li id="BPBb"><strong>Тестирование доступности</strong> - доступно ли людям с ограниченными возможностями.<br /><em>Пример: Может ли человек, получив голосовое, прослушать его из верхнего динамика.</em></li>
    <li id="x5S0"><strong>Тестирование локализации и интернетизации</strong> - тестирование с целью проверки адаптации ПО к любой культуре или особенностям языка другой страны.<br /><em>Пример: Можно ли писать сообщения иероглифами (поддерживает ли кодировку)(локализация) или есть ли функция в мессенджере для оповещения о молитвенном времени (интернационализация).</em></li>
    <li id="mGEe"><strong>Тестирование безопасности</strong> - тестирование направленное на проверку безопасности конфиденциальных данных и защиту от хакерских атак, вирусов и тд.<br /><em>Пример: Отправить файл, зараженный вирусом и проверить, пропустит ли его мессенджер. Или встроить в картинку инъекцию.</em></li>
    <li id="bC1I"><strong>Проверка удобства</strong> - тестирование направленное на удобство пользования и дизайна.<br /><em>Пример: Проверить, удобно ли будет пользоваться одной рукой, не режет ли глаз цвета, не маленькая ли кнопка отправить и тд.</em></li>
    <li id="6hYL"><strong>Нагрузочное тестирование</strong> - проводимое тестирование использования в пределах нормы.<br /><em>Пример: Сервер мессенджера рассчитан на 10 человек, и им пользуются 10 человек, отправляя сообщения и допустимые файлы допустимых размеров.</em></li>
    <li id="uEev"><strong>Стресс-тестирование</strong> - нагрузка, превышающая норму в несколько раз.<br /><em>Пример: Сервер мессенджера рассчитан на 10 человек, а им одновременно пользуются 30 человек, активно отправляя сообщения, фото и файлы друг другу.</em></li>
    <li id="CAdC"><strong>Тестирование стабильности</strong> - тестирование, направленное на продолжительное испытание в пределах нормы.<br /><em>Пример: Сервер мессенджера рассчитан на 10 человек, им пользуются 10 человек в рамках стандартного использования в течении месяца (переписываются, отправляют картинки и тд).</em></li>
    <li id="HRG1"><strong>Инсталляционное тестирование</strong> - тестирование, направленное на проверку установки, обновления и удаления приложения.<br /><em>Пример: Скачать приложение, установить его, удалить, установить еще раз и после обновить.</em></li>
  </ol>
  <h3 id="8MiB">Классификация по цели тестирования</h3>
  <ol id="V2z7">
    <li id="35bC"><strong>Тестирование новой функциональности (new feature test) – </strong>производится, как только была разработана новая функциональность.<br />То есть, как только разработчик выполнил свою часть работы, по созданию новой функциональности, он передает ее на тестирование.</li>
    <li id="8Lwo"><strong>Re-test – </strong>проверка правильности исправления дефекта. Повторное тестирование функционала, в котором был найден дефект, то есть баг.</li>
    <li id="Z3qx"><strong>Регрессионное тестирование –</strong> повторная проверка ранее разработанного функционала, после появления нового билда, то есть новой версии нашего программного продукта, для того, чтоб убедиться, что новый функционал билда никак ему не навредил.<br /><strong>Регрессионное тестирование проводится: </strong>- после появления нового билда (новой версии нашего продукта)<br />- тестирование того функционала в котором часто обнаруживаются дефекты<br />- плановое тестирование<br />- того функционала, который часто меняется в ходе разработки</li>
  </ol>
  <hr />
  <h2 id="VHsg">ТЕСТИРОВАНИЕ И QA/QC, ЖИЗНЕННЫЕ ЦИКЛЫ</h2>
  <p id="tlf5"><strong>Баг</strong> – это дефект – это отклонение ожидаемого поведения работы программного продукта от фактического.</p>
  <h3 id="XduG">Что такое тестирование программного обеспечения?</h3>
  <p id="yNgD"><strong>Тестирование </strong>- процесс, направленный на исследование, испытание программного продукта (ПП) на соответствие ожидаемого результата поведения программного продукта и фактического.</p>
  <h3 id="5w1w">Что такое контроль качества и обеспечение качества?</h3>
  <p id="ndZU"><strong>Контроль качества</strong> <strong>QC (Quality Control)</strong> — это тщательное тестирование программы на наличие дефектов, а также проверка того, что программное обеспечение соответствует всем требованиям, выдвинутым заказчиком.</p>
  <p id="wTVi"><strong>Обеспечение качества QA (Quality assurance)</strong> – это подход, который помогает убедиться, что методы, технологии и процессы, используемые для создания качественных результатов, применяются правильно.</p>
  <h3 id="qP6f">7 принципов тестирования</h3>
  <p id="RKcV"><strong>Принцип 1 — Тестирование демонстрирует наличие дефектов</strong></p>
  <p id="rhyw"><strong>Принцип 2 — Исчерпывающее тестирование невозможно</strong></p>
  <p id="ijvp"><strong>Принцип 3 — Раннее тестирование</strong></p>
  <p id="14nR"><strong>Принцип 4 — Скопление дефектов</strong></p>
  <p id="r2Sj"><strong>Принцип 5 — Парадокс пестицида</strong></p>
  <p id="5bTL"><strong>Принцип 6 — Тестирование зависит от контекста</strong></p>
  <p id="vAdN"><strong>Принцип 7 — Заблуждение об отсутствии ошибок</strong></p>
  <h3 id="tf5H">Что такое SDLC (Жизненный цикл разработки программного продукта)?</h3>
  <p id="VGm9"><strong>Жизненный цикл разработки программного продукта </strong>- процесс, направленный на создание, поддержание работоспособности, качества и надежности ПП.</p>
  <p id="Ms65"><strong><a href="/@alexbrin/17vvQqv6Crz">Этапы SDLC:</a></strong></p>
  <ol id="x4Ie">
    <li id="Pugv">Требования</li>
    <li id="7fkI">Проектирование</li>
    <li id="B8hN">Разработка</li>
    <li id="5E29">Тестирование</li>
    <li id="JbLe">Релиз</li>
    <li id="3RHw">Поддержка</li>
  </ol>
  <h3 id="nMGO">Что такое STLC Жизненный цикл тестирования программного продукта?</h3>
  <p id="kz6d"><strong>Жизненный цикл тестирования программного продукта</strong> (STLC – Software <em>testing lifecycle) - </em>процесс, направленный на тестирование программного продукта.</p>
  <p id="Uc3Y"><strong><a href="/@alexbrin/17vvQqv6Crz#gC6n">Этапы STLC</a></strong></p>
  <ol id="iSKC">
    <li id="K3P2">Анализ требований</li>
    <li id="is0j">Тестовое планирование</li>
    <li id="wY9U">Написание тестовых сценариев</li>
    <li id="miwG">Подготовка тестовой среды</li>
    <li id="EHPf">Выполнение тестов</li>
    <li id="d1pC">Завершающая фаза</li>
  </ol>
  <hr />
  <h2 id="qNuH">ВСЕ О ТЕСТ-ДИЗАЙНЕ</h2>
  <h3 id="1bKC">Что такое Тест-дизайн?</h3>
  <p id="p8O8"><strong>Тест-дизайн</strong> — это этап тестирования ПО, на котором проектируются и создаются тестовые случаи (тест-кейсы).</p>
  <h3 id="zELi">Цели тест-дизайна:</h3>
  <ol id="ZgE0">
    <li id="vWxs">Придумать тесты которые смогли бы обнаружить наиболее серьезные ошибки для ПО</li>
    <li id="yQEL">Минимизация количества тестов</li>
  </ol>
  <h3 id="cXjz">Техники тест-дизайна:</h3>
  <p id="xZDG"><strong>Классы эквивалентности</strong> - это группировка тестовых данных, в рамках которой все элементы ведут себя одинаково. То есть, если система корректно обработает одно значение из класса, то она корректно обработает и все остальные значения этого класса</p>
  <p id="ZKmm"><strong>Граничные значения</strong> - Это метод тестирования, в котором основное внимание уделяется значениям на границах допустимого диапазона. Ошибки часто проникают именно в этих &quot;крайних&quot; точках, и проверка их помогает быстро их находить.</p>
  <p id="YY9F"><strong>Попарное тестирование</strong> - это метод тестирования, при котором из множества возможных вариантов входных данных выбираются и проверяются только уникальные пары. Это позволяет сократить общее количество тестовых примеров, при этом охватывая наиболее критичные комбинации.</p>
  <p id="JQPm"><strong>Таблица принятия решений</strong> - это инструмент для визуализации и анализа различных комбинаций условий и их ожидаемых результатов. Она представляет собой таблицу, в которой столбцы представляют условия, а строки - действия или результаты на основе этих условий.</p>
  <p id="tmQr"><strong>Сценарное тестирования</strong> - инструмент, подразумевающий прохождение пути пользователя.</p>
  <p id="Pdr4"><strong>ADHOC</strong> - тестирование без документации, больше относится к исследовательскому тестированию. Но сценарий такого тестирования должен преследовать какую то цель.</p>
  <p id="jNLc"><strong>Предугадывание ошибок</strong> - сценарий, подразумевающий предугадывание уязвимых мест в программе.</p>
  <hr />
  <h2 id="UdkJ">ДОКУМЕНТАЦИЯ (кейсы, листы, репорты)</h2>
  <p id="l0Ba"><strong>Требования </strong>— это документ, описание того, что должно быть реализовано. Требования описывают то, что необходимо реализовать, без детализации технической стороны решения.</p>
  <h3 id="F14V">Чек-лист</h3>
  <p id="yFo1"><strong>Чек-лист</strong>- список проверок, в котором мы указываем, что мы будем тестировать, результат и статус проверок.</p>
  <p id="y25l"><strong>Чек-лист включает в себя следующие атрибуты:</strong></p>
  <ol id="J0Qc">
    <li id="PgjA">Проект</li>
    <li id="sCb8">Цель проверки</li>
    <li id="ztop">Идентификатор</li>
    <li id="XGn0">Требования</li>
    <li id="u5Gv">Дата проведения</li>
    <li id="2JET">Исполнитель</li>
    <li id="XBya">Среда тестирования</li>
    <li id="MxEJ">Тип тестов</li>
    <li id="zpo7">Название проверок</li>
    <li id="d0jK">Результат проверки</li>
  </ol>
  <h3 id="Tf4q">Тест-кейс</h3>
  <p id="BCJY"><strong>Тест-кейс – </strong>пошаговый сценарий, описывающий как проводится тестирование, и включающий более детализированные проверки (шаги).</p>
  <p id="tNta">То есть если в чек-листах мы указывали название самих проверок, не детализировали их, то в тест-кейсах необходимо расписать каждый шаг, то есть переход по ссылкам, заполнение полей, нажатие кнопок и т.д.</p>
  <p id="EGbp"><strong>Обязательные атрибуты тест-кейсов</strong></p>
  <ol id="2rK2">
    <li id="aPtN">Название проекта</li>
    <li id="sSt4">ID</li>
    <li id="JO6a">Требования</li>
    <li id="QrZj">Модуль</li>
    <li id="qoxk">Название</li>
    <li id="i6Lq">Приоритет<br />P1 Высокий (High)<br />P2 Средний (Medium)<br />P3 Низкий (Low)</li>
    <li id="bott">Среда тестирования</li>
    <li id="9Yyh">Шаги-теста</li>
    <li id="UkCN">Ожидаемый результат</li>
  </ol>
  <h3 id="ppNO">Тестовый набор</h3>
  <p id="0gAf"><strong>Тестовый набор (Testsuite) – </strong>набор тест-кейсов, объединенный по одному модулю или цели проверки.</p>
  <p id="AdyO">Включает в себя те же атрибуты, которые и включает в себя тест-кейс.</p>
  <h3 id="qt2i">Баг-репорт</h3>
  <p id="MhnC"><strong>Баг-репорт</strong> – это отчет об ошибках</p>
  <p id="1uK4"><strong>Атрибуты баг-репорта</strong></p>
  <ol id="PYOH">
    <li id="x8RO">Проект</li>
    <li id="dxAP">Название документа</li>
    <li id="KI8f">Ссылка на требования</li>
    <li id="qzo6">Цель проверки</li>
    <li id="J09U">Дата проведения</li>
    <li id="pSMw">Исполнитель</li>
    <li id="a2vD">Среда тестирования</li>
    <li id="FoYP">Шаги теста</li>
    <li id="qwYC">Ожидаемый результат</li>
    <li id="8o1m">Фактический результат</li>
    <li id="42rQ">Статус бага</li>
    <li id="Tegi">Серьезность бага</li>
    <li id="MEz2">Приоритет устранения бага</li>
    <li id="ngkB">Прикрепленный файл</li>
  </ol>
  <p id="MUM4"><strong>Серьезность бага:</strong></p>
  <p id="tVWd"><strong>Серьезность (severity) – </strong>показывает степень ущерба, который наносится проекту существованием дефекта. Severity выставляется тестировщиком.</p>
  <p id="IFZK"><strong>У серьезности могут быть следующие статусы:</strong></p>
  <ul id="UCqM">
    <li id="Tlkp"><strong>Blocker – </strong>блокировка, работа ПО невозможна</li>
    <li id="Mye6"><strong>Critical –</strong>критический, приводит наш функционал в нерабочее состояние</li>
    <li id="fd9B"><strong>Major-</strong>серьезные ошибки, которые свидетельствуют об отклонении работы от БЛ или нарушающие работу программы, но не имеют критическое воздействие на ПО</li>
    <li id="R0a2"><strong>Minor – </strong>незначительный дефект не нарушающий функционал нашего приложения, который является несоответствием ожидаемого результата (ошибка дизайна, пример)</li>
    <li id="zblv"><strong>Trivial</strong> –не имеет влияния на функционал и работу нашей программы, но может быть обнаружен визуально.</li>
  </ul>
  <p id="lO7R"><strong>Приоритет бага:</strong></p>
  <p id="WBWm"><strong>Приоритет -</strong> показывает, как быстро дефект должен быть устранён. Priority выставляется менеджером, team-lead или заказчиком.</p>
  <ul id="OtUs">
    <li id="0Xb4"><strong>P1 Высокий (High</strong>)<br />Критическая для проекта ошибка. Должна быть исправлена как можно быстрее.</li>
    <li id="x2fj"><strong>P2 Средний (Medium)</strong><br />Не критичная для проекта ошибка, однако требует обязательного решения.</li>
    <li id="mokX"><strong>P3 Низкий (Low)</strong><br />Наличие данной ошибки не является критичным и не требует срочного решения.</li>
  </ul>
  <hr />
  <h2 id="pUOL">КЛИЕНТ - СЕРВЕРНАЯ АРХИТЕКТУРА</h2>
  <p id="ak69"><strong>Клиент-Серверная архитектура </strong>– это структура, в которой нагрузка распределяется между поставщиками услуг и заказчиками услуг, а также промежуточными звеньями.</p>
  <h3 id="tbDn">2 вида клиент-серверной архитектуры:</h3>
  <ol id="yH4I">
    <li id="jv2T">С базами данных</li>
    <li id="nln6">Без баз данных</li>
  </ol>
  <h3 id="2HJg">Что включает в себя КСА:</h3>
  <ol id="kUgY">
    <li id="cZ92">Клиент</li>
    <li id="SLJl">Сервер</li>
    <li id="7wwI">Базы данных</li>
    <li id="iT93">Промежуточное ПО - драйверы, набор протоколов, язык SQL</li>
    <li id="GR69">Прикладной программный интерфейс (API) - набор функций и подпрограмм, обеспечивающих взаимодействие клиентов и серверов, набор методов, которые можно использовать для доступа функциональности к другой программе</li>
  </ol>
  <h3 id="uBNK">Существует 2 вида клиентов:</h3>
  <ol id="2xrS">
    <li id="aTsG">Толстый клиент - приложение, которое обеспечивает расширенную функциональность независимо от центрального сервера. Сервер выступает в качестве хранилища данных</li>
    <li id="UpXp">Тонкий клиент - большую часть нагрузки берет на себя сервер, а не пользователь.</li>
  </ol>
  <h3 id="yGzA">Плюсы и Минусы Монолитной Архитектуры:</h3>
  <p id="GwOA"><strong>Плюсы:</strong></p>
  <ol id="n5wi">
    <li id="bDs6"><strong>Простота</strong>: Проще создавать и тестировать, так как все функции в одном месте.</li>
    <li id="NgDU"><strong>Меньше взаимодействий</strong>: Нет необходимости в сетевых вызовах между компонентами.</li>
    <li id="sDrd"><strong>Производительность</strong>: Обычно быстрее из-за прямых вызовов функций.</li>
  </ol>
  <p id="cQ7z"><strong>Минусы:</strong></p>
  <ol id="tuLT">
    <li id="yYH2"><strong>Масштабирование</strong>: Затруднено горизонтальное масштабирование из-за требований к целостности данных.</li>
    <li id="lsFV"><strong>Сложность обновлений</strong>: Изменения в большом приложении могут быть сложными и опасными.</li>
    <li id="Gimu"><strong>Гибкость</strong>: Недостаточно гибкая для больших и комплексных проектов.</li>
  </ol>
  <h3 id="Jdm6">Плюсы и Минусы Микросервисной Архитектуры:</h3>
  <p id="vBxK"><strong>Плюсы:</strong></p>
  <ol id="J8ZL">
    <li id="uunX"><strong>Гибкость</strong>: Легко масштабировать и обновлять отдельные микросервисы.</li>
    <li id="4jRq"><strong>Распределенная разработка</strong>: Команды могут работать независимо друг от друга на разных сервисах.</li>
    <li id="FY16"><strong>Отказоустойчивость</strong>: Если один сервис падает, другие могут продолжать работу.</li>
  </ol>
  <p id="9xEI"><strong>Минусы:</strong></p>
  <ol id="W1IX">
    <li id="fP4u"><strong>Сложность управления</strong>: Необходимо учитывать большое количество сервисов и их взаимодействие.</li>
    <li id="RWOp"><strong>Сложнее отлаживать</strong>: Взаимодействие между микросервисами может быть сложным для отладки.</li>
    <li id="p87H"><strong>Затраты на инфраструктуру</strong>: Дополнительные расходы на поддержку и развертывание сервисов.</li>
  </ol>
  <hr />
  <h2 id="rbG1">HTTP ПРОТОКОЛЫ</h2>
  <p id="icnk"><strong>HTTP</strong>- «протокол передачи <a href="https://ru.wikipedia.org/wiki/%D0%93%D0%B8%D0%BF%D0%B5%D1%80%D1%82%D0%B5%D0%BA%D1%81%D1%82" target="_blank">гипертекста</a>») — <a href="https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9_%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB" target="_blank">протокол</a> <a href="https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%8B_%D0%BF%D1%80%D0%B8%D0%BA%D0%BB%D0%B0%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE_%D1%83%D1%80%D0%BE%D0%B2%D0%BD%D1%8F" target="_blank">прикладного уровня</a> передачи данных, изначально — в виде гипертекстовых документов в формате <a href="https://ru.wikipedia.org/wiki/HTML" target="_blank">HTML</a>.</p>
  <p id="8Pz6"><strong>Протокол</strong> – набор правил передачи информации. Мы регламентируем то, как будет передаваться в сети интернет наша информация.</p>
  <h3 id="7cYE">Метод HTTP</h3>
  <p id="v99M"><strong>GET </strong>- запрос для получения статуса, получение какой либо информации от сервера</p>
  <p id="7TTT"><strong>POST</strong> – отправка данных, файлов</p>
  <p id="SNJc"><strong>PUT</strong> – изменение данных</p>
  <p id="oIE1"><strong>DELETE</strong> – удаление данных</p>
  <h3 id="Oe12">Коды состояния запроса</h3>
  <p id="jluf"><strong>100-е </strong>– это информационный код состояния, дает информационные сообщения.</p>
  <p id="O8qw"><strong>200-е </strong>– информируют нас об успешной отработке запроса</p>
  <p id="KVh1"><strong>300-е </strong>– это перенаправление, то есть, к примеру, когда был изменен url и нужно идти на другой. </p>
  <p id="7P10"><strong>400-е</strong> – обозначают что на стороне клиента есть ошибка.</p>
  <p id="RVfF"><strong>500-е </strong>– это ошибка на стороне сервера.</p>
  <h3 id="yS55"><strong>Передача протокола осуществляется по Модели TCP/IP.</strong></h3>
  <p id="K5aj">Уровни TCP/IP:</p>
  <ul id="qQ7Q">
    <li id="sBJw"><strong>сетевые интерфейсы</strong> – передаются физические импульсы (оптоволокно) (протокол Ethernet)</li>
    <li id="QqVD"><strong>сетевой</strong> – происходит передача физических сигналов, основной протокол –IP</li>
    <li id="U5RZ"><strong>транспортный</strong> – транспортные взаимодействия в нашей сети:</li>
  </ul>
  <p id="cxla"><strong>TCP</strong> - надежный транспортный протокол, в результате которого происходит гарантия того, что информация доходит до клиента, если нет подтверждения о получении информации, то происходит повторная отправка, например в почтовых сервисах, где очень важно чтоб письмо дошло до адресатов.</p>
  <p id="9JkN"><strong>UDP</strong> – нет гарантии того что информация дошла, она идет непрерывным потоком, нет обратной связи, то есть подтверждения получения, например в онлайн-играх.</p>
  <hr />
  <h2 id="hG9v">SOAP И REST</h2>
  <p id="eNcW"><strong>SOAP (Simple Object Access Protocol) </strong>— стандартный протокол. Четко структурирован и задокументирован.</p>
  <p id="h5gw"><strong>REST (Representational State Transfer)</strong> — архитектурный стиль взаимодействия компьютерных систем в сети, основанный на методах протокола HTTP.</p>
  <h3 id="pKJZ">SOAP</h3>
  <p id="um3f">Любое сообщение в протоколе SOAP — это XML документ</p>
  <h3 id="wpLy">REST</h3>
  <p id="myrb"><strong>REST (Representational State Transfer)</strong> — на самом деле архитектурный стиль, а не протокол.</p>
  <p id="PlMr">Управление данными происходит с помощью методов HTTP: GET, POST, PUT, DELETE.</p>
  <p id="JJOg"><strong>Разница между архитектурным стилем и протоколом в том что к АС не применяются какие-то жесткие правила</strong></p>
  <p id="a4B0">REST (Representational State Transfer) и SOAP (Simple Object Access Protocol) - это два различных способа построения архитектуры для веб-сервисов. Вот основные различия между ними:</p>
  <ol id="ww2Q">
    <li id="g5ht"><strong>Принципы дизайна:<br /></strong>REST базируется на принципах архитектуры веб, таких как использование HTTP методов (GET, POST, PUT, DELETE), представление ресурсов через URL<br />SOAP основывается на строгих стандартах и предполагает использование XML для обмена сообщениями</li>
    <li id="7xDY"><strong>Формат сообщений:<br /></strong>REST использует различные форматы для обмена данными, такие как JSON, XML, HTML, и другие.<br />SOAP использует только XML в качестве формата сообщений.</li>
    <li id="sm0R"><strong>Простота и гибкость:<br /></strong>REST считается более простым и гибким для использования.<br />SOAP предлагает большую степень стандартизации</li>
    <li id="64yf"><strong>Производительность:<br /></strong>REST обычно обеспечивает более высокую производительность благодаря более легковесным форматам данных и возможности кэширования.<br />SOAP зачастую требует большего объема данных из-за использования XML, что может негативно отразиться на производительности.</li>
  </ol>
  <h3 id="7Qnf">Что выбрать SOAP или REST?</h3>
  <p id="Ix4w">Обычно, SOAP используется в крупных корпоративных системах со сложной логикой, когда требуются четкие стандарты, подкрепленные временем.</p>
  <p id="8gHS">Если же вы разрабатываете публичное API и логика взаимодействия во многом покрывается действиями: чтение, добавление, изменение и удаление данных (те самые наши 4 метода get, post, put, delete ) — смело выбирайте REST. Он наиболее популярен и быстр.</p>
  <hr />
  <h2 id="KQCp">POSTMAN И API</h2>
  <p id="A1CQ"><strong>API</strong> – интерфейс, который определяет, как одна программа должна взаимодействовать с другой программой.</p>
  <p id="3NF8"><strong>Типы API:</strong></p>
  <ol id="69pk">
    <li id="FTsm">Локальные API - то, что позволяет компонентам одной системы взаимодействовать между собой (микросервисная архитектура)</li>
    <li id="TVQP">Удаленные API - позволяет связывать между собой несколько систем (SOAP и REST).</li>
  </ol>
  <p id="xcys"><strong>API появляется раньше GUI поэтому API тестируется раньше.</strong></p>
  <p id="Z9oF"><strong>Как работает API:</strong></p>
  <ol id="w3Ux">
    <li id="ijoK">Вызов операции (GET, POST, PUT, DELETE)</li>
    <li id="bCNy">Входные данные (HTTP Request)</li>
    <li id="o2tq">Выходные данные (РЕЕЗ Response)</li>
  </ol>
  <p id="jKhs"><strong>Способы вызова API:</strong></p>
  <ol id="Zq6j">
    <li id="G11I">Вызов функции системой (прямой вызов)</li>
    <li id="aIA6">Вызов метода другой системой (прямой вызов)</li>
    <li id="NG7C">Вызов метода человеком (прямой вызов)</li>
    <li id="0tnv">GUI -&gt; API. (косвенный)</li>
  </ol>
  <p id="Aubu"><strong>Коллекции в Postman</strong> представляют собой группы запросов, скриптов и переменных, организованные вместе для удобного управления и использования</p>
  <p id="RL7k">Вот несколько основных целей использования коллекций в Postman:</p>
  <ol id="rkuu">
    <li id="P304"><strong>Организация запросов:</strong></li>
    <ul id="YNo7">
      <li id="zvQT">Коллекции позволяют организовать ваши API-запросы по темам, проектам или любым другим категориям. Это облегчает навигацию и поиск конкретных запросов.</li>
    </ul>
    <li id="rY21"><strong>Совместная работа:</strong></li>
    <ul id="JDgU">
      <li id="iiUg">Вы можете делиться коллекциями с другими участниками команды, что упрощает совместную работу над API и обмен знаниями.</li>
    </ul>
    <li id="iNzL"><strong>Использование переменных и сред:</strong></li>
    <ul id="3dPj">
      <li id="1lhn">В коллекциях можно определять переменные и среды, что облегчает настройку запросов для различных сред или конфигураций.</li>
    </ul>
    <li id="JE8A"><strong>Управление тестами:</strong></li>
    <ul id="rS2Z">
      <li id="eapy">Коллекции позволяют легко настраивать и управлять тестами для ваших API-запросов, что помогает обеспечить качество и надежность вашего API.</li>
    </ul>
    <li id="HyoL"><strong>Сценарии и потоки работы:</strong></li>
    <ul id="AaT6">
      <li id="GBvs">Postman позволяет создавать сценарии и потоки работы с помощью коллекций, что полезно для тестирования API и взаимодействия с ними в различных сценариях использования.</li>
    </ul>
  </ol>
  <p id="4Z2k"></p>
  <h2 id="huwB">МОБИЛЬНОЕ ТЕСТИРОВАНИЕ</h2>
  <h3 id="ikK4">Типы мобильных приложений:</h3>
  <p id="iMxh"><strong>Нативными - </strong>написаны на родном (с англ. native – родной) для определённой платформы языке программирования.</p>
  <p id="cl83"><strong>Web</strong> – веб-сайт, адаптированный для нашего мобильного приложения.<br />Веб-приложение, представляет собой сайт, который адаптирован и оптимизирован под любой смартфон.</p>
  <p id="DsTK"><strong>Гибридные приложения</strong> представляют собой сочетание веб и нативных приложений. Они могут быть загружены из маркетов вроде Google Play и App Store. Для их работы необходимо интернет-подключение.<br />Так же часто гибридные приложения являются <strong>кроссплатформенными</strong>, что ускоряет и облегчает процесс разработки.</p>
  <h3 id="AsBl">Тестирование и особенности тестирования мобильных приложений</h3>
  <h3 id="UnHC">Зависимости мобильного тестирования:</h3>
  <p id="3GgS"><strong>1. Интернет:</strong></p>
  <p id="9a40">- тип соединения</p>
  <p id="9emG">- изменение типа соединения</p>
  <p id="baGA">- качество соединения</p>
  <p id="6t1h">- потеря связи</p>
  <p id="KLf2"><strong>2.Проверки на прерывание:</strong></p>
  <p id="np2o">- исходящие/входящие вызовы</p>
  <p id="7piw">- всплывающие окна/уведомления</p>
  <p id="j6He">- прерывания при разрядке/подзарядке</p>
  <p id="xf0o">- сворачивание/разворачивание приложения</p>
  <p id="a0CV"><strong>3.Тестирование установки</strong></p>
  <p id="fFEM">Установка.</p>
  <p id="a3bP">Удаление и переустановка.</p>
  <p id="OPIy">Обновление.</p>
  <p id="1lkj"><strong>4.Работа с функциями телефона:</strong></p>
  <p id="phBt">- GPS</p>
  <p id="TIkZ">- видео/фото</p>
  <p id="yrsK">- размер экрана, разрешение, ориентация</p>
  <p id="96s5">- работа с жестами</p>
  <p id="dUzh">- отпечаток пальца, узнавание лица, пароль, графический ключ</p>
  <p id="XSZ4">- клавиатура</p>
  <p id="qHHT">- Bluetooеh</p>
  <p id="AC76">- работа со съемными картами памяти</p>
  <p id="kTOo">- нажатие</p>
  <p id="2MPG">- комбинации кнопок</p>
  <p id="Zt6M">- динамики, микрофоны, гнездо для гарнитуры</p>
  <p id="49hf"><strong>5.Тестирование производительности:</strong></p>
  <p id="EBKv">- загрузка оперативной памяти</p>
  <p id="69VD">- зависимость от заряда батареи</p>
  <p id="aNdl">- запуск с внутренней памяти/ с накопителя</p>
  <p id="lCyJ"><strong>6. Тестирование на соответствие гайдлайнам и мокапам</strong></p>
  <hr />
  <h2 id="262c">ЛОКАЛИЗАЦИЯ БАГА</h2>
  <p id="YIgC"><strong>Локализация бага</strong> - процесс обнаружения бага и поиск условий, при которых баг повторяется. Найти конкретные условия и минимальные для воспроизведения шаги.</p>
  <p id="ZauS">Локализация - это поиск первопричины возникновения ошибки.</p>
  <p id="Eo0o">Нужно проверить себя еще раз: воспроизвести баг снова при тех же условиях. Если ошибка не повторилась при очередном тестировании, то нужно разобраться, точно ли были соблюдены все действия и шаги воспроизведения, приведшие к этому результату. Для того, чтобы более точно определить условия воспроизведения ошибки, необходимо эту ошибку локализовать.</p>
  <p id="ptGz"><strong>Чтобы локализовать баг, необходимо собрать максимальное количество информации о его воспроизведении:</strong></p>
  <ul id="7uwm">
    <li id="jVN0">Выявить причины возникновения дефекта</li>
    <li id="fVSo">Проанализировать возможность влияния найденного дефекта на другие области</li>
    <li id="hIto">Отклонение от ожидаемого результата</li>
    <li id="skzw">Исследовать окружение</li>
    <li id="Qgf7">Проверить на разных устройствах</li>
    <li id="oSPp">Проверить в разных версиях ПО</li>
    <li id="4Nsx">Проанализировать ресурсы системы</li>
  </ul>
  <p id="FSqf"><strong>Локализация бага на интеграционном уровне</strong></p>
  <p id="YiCM">Локализация бага (дефекта) включает в себя процесс анализа проблемы с целью выявления максимальной детализации причины ее возникновения. Чем больше информации о проблеме собрано, тем быстрее ее решит команда.</p>
  <hr />
  <h2 id="msVl">DEVTOOLS</h2>
  <ol id="81xd">
    <li id="KlHK">Консоль - прописываются действия и ошибка JS. Так же в этой консоли можно исполнять JS. Ошибки, предупреждения о возможных ошибках. Все эти ошибки копируются (текст из консоли) и отправляется в баг репорт. </li>
    <li id="CkgZ">Источники - здесь содержится информация о серверах, к которым общается клиент. </li>
    <li id="m8Y2">Сеть - информация об общении сервера и клиента. Показывает запросы, которые отправляет клиент и ответы, которые отправляет сервер. </li>
    <li id="KwXP">Производительность - для оценки быстродействия сайта. </li>
    <li id="ppIk">Защита - проверка на безопасность протоколов.</li>
  </ol>
  <hr />
  <h2 id="NaF9">СНИФФЕРЫ</h2>
  <p id="qPEP"><strong>Снифферы</strong> - инструменты, которые позволяют отслеживать запросы и ответы от сервера, и, при необходимости, их изменять. Используются для тестирования веб-приложений или мобильного тестирования.</p>
  <p id="Z2yy">Самые популярные инструменты: Charles и Fiddler.</p>
  <h3 id="9B2P">Charles</h3>
  <p id="bsif">При работе в браузере все запросы и ответы будут отображаться в программе.</p>
  <p id="UOJI">Можно выбирать запрос и нажать на Focus. И тогда можно отслеживать именно этот запрос. Так же, как и в devtools.</p>
  <p id="5czx">Что можно посмотреть в запросах: header, body, служебную информацию, статус коды, методы (http).</p>
  <p id="T5Mg">Так же можно с помощью Charles отслеживать трафик с телефона или эмулятора. Для этого в настройках WiFi нужно выбрать сеть, к которой подключен компьютер с Charles на борту и подключится к той же WiFi сети, а так же настроить прокси для этой сети. В прокси нужно вписать ip адрес компьютера. Порт - 8888. Так же на телефоне нужно установить сертификат чтобы перехватывать трафик.</p>
  <p id="nKkP"><strong>Что можно тестировать в Charles:</strong></p>
  <ol id="WsSZ">
    <li id="JUwy">Переадресация (Tools - Map Remote). Можно выставить поведение при переадресации. Например, чтобы с сайта google.com происходила переадресация на ya.ru. </li>
    <li id="kc34">Подмена (Tools - Rewrite). Используется чаще всего. Можно подменить запросы, URL, ответы, отдельные параметры, отдельные header. </li>
    <li id="hDhR">Подмена ответа сервера в целом (Tools - Map Local). Например, работаем на сайте и загружаем определенную картинку или заказчик что то загрузил на сайт и появилась ошибка. Нужно запросить у заказчика материал и попробовать повторить его путь. Берем эту картинку, добавляем ее в body и смотрим, что происходит. Тогда могут пригодится ответы сервера. </li>
    <li id="HTN1">Занижать скорость интернета (Tools - Enable Trottling).</li>
    <li id="feE0">Работа с breakpoint (Proxy - Breakpointing Settings). Можно ставить как для ответа, так и для запроса.</li>
  </ol>
  <hr />
  <h2 id="7jzb">SQL</h2>
  <h3 id="10ok">Первичный и внешний ключи:</h3>
  <p id="zgNq">Первичный ключ (PRIMARY KEY) - это уникальный идентификатор для каждой строки в таблице. Он используется для определения единственности данных и обеспечения быстрого доступа к ним. <br />Код: <code>PRIMARY KEY</code></p>
  <p id="5pD9">Внешний ключ (FOREIGN KEY) - это отношение между двумя таблицами, которое устанавливает связь между ними. Внешний ключ используется для ограничения взаимосвязи между таблицами и предотвращения несоответствий данных. Внешний ключ ссылается на первичный ключ другой таблицы.<br />Код: <code>band_id INTEGER REFERENCES band(band_id)</code></p>
  <h3 id="aZ9O">Типы взаимосвязи таблиц SQL</h3>
  <p id="7bIR"><strong>1. Связь один ко многим (one-to-many):</strong> Это тип взаимосвязи, когда одна запись в одной таблице может относиться к нескольким записям в другой таблице.</p>
  <p id="YX3m"><strong>2. Связь многие ко одному (many-to-one):</strong> Это тип взаимосвязи, когда несколько записей в одной таблице могут относиться только к одной записи в другой таблице.</p>
  <p id="ueeg"><strong>3. Связь один к одному (one-to-one)</strong> - это тип взаимосвязи между двумя таблицами в базе данных, когда каждая запись в одной таблице связана с только одной записью в другой таблице. </p>
  <p id="sGkC"><strong>4. Связь многие ко многим (many-to-many)</strong> - это тип взаимосвязи между двумя таблицами в базе данных, когда каждая запись в одной таблице может быть связана с несколькими записями в другой таблице, и наоборот. </p>
  <h3 id="t2ca"><strong>Inner Join и Outer Join</strong></h3>
  <p id="50om"><strong>INNER JOIN</strong> - способ соединения таблиц, при котором остаются те строки, где значения ключа совпадают в обеих таблицах.</p>
  <p id="SVXT"><strong>LEFT OUTER JOIN</strong> - способ соединения таблиц, при котором возвращаются все строки из левой таблицы и соответствующие строки из правой таблицы. Если в правой таблице нет соответствующих строк, тогда возвращает NULL </p>
  <p id="47rQ"><strong>FULL OUTER JOIN</strong> - способ соединения таблиц, при котором возвращаются строки из обеих таблиц. Если в левой или правой таблице нет соответствующих данных для второй таблицы - тогда подставляется NULL </p>
  <h3 id="h0ue">Основные запросы:</h3>
  <p id="R5DI">CREATE - Создает новую таблицу, представление таблицы или другой объект в БД</p>
  <p id="DBDT">DROP - Удаляет существующую таблицу</p>
  <p id="0Bsx">SELECT - Извлекает записи из одной или нескольких таблиц</p>
  <p id="CQLk">INSERT - Создает записи </p>
  <p id="0RQ2">UPDATE - Модифицирует записи</p>
  <p id="I148">DELETE - Удаляет записи</p>
  <p id="5Kh7">AND - Объединяет условия</p>
  <p id="6P17">BETWEEN - Проверяет вхождение значения в диапазон от минимального до максимального</p>
  <p id="WANe">IN - Выполняет поиск значения в списке значений</p>
  <p id="IvKy">LIKE - Сравнивает значение с похожими</p>
  <p id="nOHx">NOT - Инвертирует (меняет на противоположное) смысл других логических операторов</p>
  <p id="ot8H">OR - Комбинирует условия (одно из условий должно совпадать)</p>
  <p id="F4tH">IS NULL - Определяет, является ли значение нулевым</p>
  <p id="FRG6">UNIQUE - Определяет уникальность строки</p>
  <h2 id="D7DO">KAFKA, СИНХРОННОЕ И АСИНХРОННОЕ ВЗАИМОДЕЙСТВИЕ</h2>
  <h3 id="19jn">Kafka</h3>
  <p id="Lv73">Кафка позволяет различным приложениям отправлять, получать и обрабатывать данные, такие как сообщения, логи и события, в режиме, близком к реальному времени. Это позволяет создавать масштабируемые и отказоустойчивые системы обработки данных.</p>
  <p id="wmrC">Главное отличие Кафки от большинства брокеров в том, что Кафка добавляет сообщения в журнал (в топик), а консьюмер сам забирает из этого журнала данные. Кафку часто используют для сбора и агрегации из большого количества источников. </p>
  <p id="klqa">Плюсы Кафки:</p>
  <ol id="oEUE">
    <li id="L7rl">Более высокая производительность.</li>
    <li id="3fQq">Все сообщения после прочтения не удаляются и могут быть прочитаны консьюмерами повторно. Удаление задается вручную.</li>
    <li id="s8k7">Из Кафки нельзя удалить конкретное сообщение (партицию), а только удалить топик целиком.</li>
    <li id="W2l1">При перезапуске консьюмера в брокере сохраняется коммит (снимок состояния), и тем самым происходит фиксация и консьюмер продолжает читать. </li>
  </ol>
  <h3 id="p6i6">Синхронное взаимодействие:</h3>
  <ul id="6PQo">
    <li id="JUlE"><strong>Определение:</strong> В синхронном взаимодействии одна часть программы ждет завершения другой части программы, прежде чем продолжить свое выполнение.</li>
  </ul>
  <h3 id="mXjN">Асинхронное взаимодействие:</h3>
  <ul id="1ZPX">
    <li id="dGUB"><strong>Определение:</strong> В асинхронном взаимодействии части программы могут работать параллельно без ожидания завершения друг друга.</li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/7aYUT-9OJpG</guid><link>https://teletype.in/@alexbrin/7aYUT-9OJpG?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/7aYUT-9OJpG?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>Шпаргалка для собеса тестировщика</title><pubDate>Wed, 20 Mar 2024 21:16:54 GMT</pubDate><description><![CDATA[Тестирование - процесс, направленный на исследование, испытание программного продукта (ПП) на соответствие ожидаемого результата поведения программного продукта и фактического.]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#a1tp">1. Что такое тестирование программного обеспечения?</a></li>
      <li class="m_level_1"><a href="#5w1w">2. Что такое контроль качества и обеспечение качества?</a></li>
      <li class="m_level_1"><a href="#tf5H">3. Что такое SDLC (Жизненный цикл разработки программного продукта)?</a></li>
      <li class="m_level_1"><a href="#nMGO">4. Что такое STLC Жизненный цикл тестирования программного продукта?</a></li>
      <li class="m_level_1"><a href="#rmNK">5. Что такое тест-кейс?</a></li>
      <li class="m_level_1"><a href="#EGbp">6. Атрибуты тест-кейсов, что в себя включает тест-кейс?</a></li>
      <li class="m_level_1"><a href="#e3WA">7. Что такое тестовый набор?</a></li>
      <li class="m_level_1"><a href="#bYXI">8. Атрибуты тестового набора, что в себя включает тестовый набор?</a></li>
      <li class="m_level_1"><a href="#Ofvf">9. Что такое чек-лист?</a></li>
      <li class="m_level_1"><a href="#ILGn">10. Атрибуты чек-листа, что включает в себя чек-лист?</a></li>
      <li class="m_level_1"><a href="#DaGi">11. Что такое план тестирования?</a></li>
      <li class="m_level_1"><a href="#kcAY">12. Для чего проводится тестирование ПО?</a></li>
      <li class="m_level_1"><a href="#Bie7">13. Принципы тестирования</a></li>
      <li class="m_level_1"><a href="#2W8U">14. В чем разница между верификацией и валидацией?</a></li>
      <li class="m_level_1"><a href="#XrmS">15. Что такое требования?</a></li>
      <li class="m_level_1"><a href="#TYkL">16. Что такое баг и баг-репорт?</a></li>
      <li class="m_level_1"><a href="#0QJx">17. Атрибуты баг-репорта</a></li>
      <li class="m_level_1"><a href="#g9IT">18. Приоритет устранения и серьезность бага</a></li>
      <li class="m_level_1"><a href="#bzHz">Основные виды тестирования ПО</a></li>
      <li class="m_level_2"><a href="#zXou">19. Классификация по запуску кода на исполнение:</a></li>
      <li class="m_level_2"><a href="#MChp">20. Классификация по доступу к коду и архитектуре:</a></li>
      <li class="m_level_2"><a href="#VZBu">21. Классификация по уровню детализации приложения (Пирамида тестирования):</a></li>
      <li class="m_level_2"><a href="#IP8i">22. Классификация по принципам работы с приложением</a></li>
      <li class="m_level_2"><a href="#JUF6">23. Классификация по целям тестирования</a></li>
      <li class="m_level_2"><a href="#fGFp">24. Функциональное тестирование</a></li>
      <li class="m_level_2"><a href="#hbBn">25. Нефункциональное тестирование</a></li>
      <li class="m_level_2"><a href="#8MiB">25.1. Классификация по цели тестирования</a></li>
      <li class="m_level_2"><a href="#1bKC">26. Что такое Тест-дизайн?</a></li>
      <li class="m_level_2"><a href="#fCbG">27. Техники тест-дизайна</a></li>
    </ul>
  </nav>
  <h3 id="a1tp">1. Что такое тестирование программного обеспечения?</h3>
  <p id="yNgD"><strong>Тестирование </strong>- процесс, направленный на исследование, испытание программного продукта (ПП) на соответствие ожидаемого результата поведения программного продукта и фактического.</p>
  <h3 id="5w1w">2. Что такое контроль качества и обеспечение качества?</h3>
  <p id="ndZU"><strong>Контроль качества</strong> <strong>QC (Quality Control)</strong> — это тщательное тестирование программы на наличие дефектов, а также проверка того, что программное обеспечение соответствует всем требованиям, выдвинутым заказчиком.</p>
  <p id="wTVi"><strong>Обеспечение качества QA (Quality assurance)</strong> – это подход, который помогает убедиться, что методы, технологии и процессы, используемые для создания качественных результатов, применяются правильно.</p>
  <h3 id="tf5H">3. Что такое SDLC (Жизненный цикл разработки программного продукта)?</h3>
  <p id="VGm9"><strong>Жизненный цикл разработки программного продукта </strong>- процесс, направленный на создание, поддержание работоспособности, качества и надежности ПП.</p>
  <p id="Ms65"><strong><a href="https://teletype.in/@alexbrin/17vvQqv6Crz" target="_blank">Этапы SDLC:</a></strong></p>
  <ol id="x4Ie">
    <li id="Pugv">Требования</li>
    <li id="7fkI">Проектирование</li>
    <li id="B8hN">Разработка</li>
    <li id="5E29">Тестирование</li>
    <li id="JbLe">Релиз</li>
    <li id="3RHw">Поддержка</li>
  </ol>
  <h3 id="nMGO">4. Что такое STLC Жизненный цикл тестирования программного продукта?</h3>
  <p id="kz6d"><strong>Жизненный цикл тестирования программного продукта</strong> (STLC – Software <em>testing lifecycle) - </em>процесс, направленный на тестирование программного продукта.</p>
  <p id="Uc3Y"><strong><a href="https://teletype.in/@alexbrin/17vvQqv6Crz#gC6n" target="_blank">Этапы STLC</a></strong></p>
  <ol id="iSKC">
    <li id="K3P2">Анализ требований</li>
    <li id="is0j">Тестовое планирование</li>
    <li id="wY9U">Написание тестовых сценариев</li>
    <li id="miwG">Подготовка тестовой среды</li>
    <li id="EHPf">Выполнение тестов</li>
    <li id="d1pC">Завершающая фаза</li>
  </ol>
  <h3 id="rmNK">5. Что такое тест-кейс?</h3>
  <p id="TYYR"><strong><a href="https://teletype.in/@alexbrin/5DYHUp5ZBEu#He3t" target="_blank">Тест-кейс</a> – </strong>пошаговый сценарий, описывающий как проводится тестирование, и включающий более детализированные проверки (шаги).</p>
  <p id="vRbY">То есть если в чек-листах мы указывали название самих проверок, не детализировали их, то в тест-кейсах необходимо расписать каждый шаг, то есть переход по ссылкам, заполнение полей, нажатие кнопок и т.д.</p>
  <h3 id="EGbp">6. Атрибуты тест-кейсов, что в себя включает тест-кейс?</h3>
  <ol id="2rK2">
    <li id="aPtN"><strong>Название проекта </strong>– здесь указывается название проекта, для которого мы пишем сценарии проверки</li>
    <li id="sSt4"><strong>ID</strong> – это уникальный Идентификатор, уникальный номер тест-кейса, в нашей системе, на одном проекте не должно быть 2-х одинаковых тест-кейсов, это необходимо для того чтоб мы могли всегда корректно ссылаться на наш документ, при общении с другими коллегами, указанием в других системах и т.д.</li>
    <li id="JO6a"><strong>Требования</strong> – ссылка на документ, на основании которого составлен данный документ</li>
    <li id="QrZj"><strong>Модуль </strong>– название модуля к которому относится данный функционал</li>
    <li id="qoxk"><strong>Название </strong>- здесь идет название нашей проверки, отображающее то, что именно мы будет проверять в данном тесте</li>
    <li id="i6Lq"><strong>Приоритет -</strong> показывает, на сколько важно проведение данного теста<br />P1 Высокий (High)<br />P2 Средний (Medium)<br />P3 Низкий (Low)<br /><strong>Тестировщик самостоятельно выставляет данный приоритет, основываясь на своем опыте.</strong></li>
    <li id="bott"><strong>Среда тестирования</strong> – здесь мы указываем окружение, на котором мы будем проводить тестирование – то есть наша платформа, версия браузера (если это веб-продукт) и т.д.</li>
    <li id="9Yyh"><strong>Шаги-теста</strong> – самый главный атрибут нашего документа, в котором мы подробно расписываем все шаги прохождения нашего теста</li>
    <li id="UkCN"><strong>Ожидаемый результат</strong> – в данном атрибуте мы указываем, а какой именно результат мы ожидаем получить, после того как мы выполним данный шаг, очень важно писать результат по каждому шагу, а не один для всех шагов. Это позволит любому члену команды повторить данный тест.</li>
  </ol>
  <h3 id="e3WA">7. Что такое тестовый набор?</h3>
  <p id="VeCr"><strong><a href="https://teletype.in/@alexbrin/5DYHUp5ZBEu#He3t" target="_blank">Тестовый набор (Testsuite)</a> – </strong>набор тест-кейсов, объединенный по одному модулю или цели проверки.</p>
  <h3 id="bYXI">8. Атрибуты тестового набора, что в себя включает тестовый набор?</h3>
  <p id="2PMy">Они дублируют с атрибутами тест-кейсов.</p>
  <ol id="U8tu">
    <li id="0MXG"><strong>ID тест-кейса</strong></li>
    <li id="IBrg"><strong>Название проекта</strong></li>
    <li id="z00L"><strong>Модуль</strong></li>
    <li id="8auL"><strong>Описание теста</strong></li>
    <li id="6Yuc"><strong>Ожидаемый результат</strong></li>
    <li id="67US"><strong>Приоритет -</strong> показывает, на сколько важно проведение данного теста:<br />P1 Высокий (High)<br />P2 Средний (Medium)<br />P3 Низкий (Low)</li>
    <li id="wUqD"><strong>Дата проведения теста</strong></li>
    <li id="vsGV"><strong>Исполнитель</strong></li>
    <li id="vwV5"><strong>Среда тестирования</strong></li>
    <li id="6CtN"><strong>Статус</strong></li>
  </ol>
  <h3 id="Ofvf">9. Что такое чек-лист?</h3>
  <p id="H0ah"><strong><a href="https://teletype.in/@alexbrin/5DYHUp5ZBEu#He3t" target="_blank">Чек-лист</a></strong>- список проверок, в котором мы указываем, что мы будем тестировать, результат и статус проверок.</p>
  <h3 id="ILGn">10. Атрибуты чек-листа, что включает в себя чек-лист?</h3>
  <ol id="Yxug">
    <li id="PgjA"><strong>Проект</strong> – здесь указывается название проекта, для которого мы пишем сценарии проверки;</li>
    <li id="sCb8"><strong>Цель проверки</strong> - здесь идет название модуля который будет проверять в данном документе;</li>
    <li id="ztop"><strong>Идентификатор</strong> -это уникальный Идентификатор документа;</li>
    <li id="XGn0"><strong>Требования</strong> - ссылка на документ, на основании которого составлен данный документ;</li>
    <li id="u5Gv"><strong>Дата проведения;</strong></li>
    <li id="2JET"><strong>Исполнитель;</strong></li>
    <li id="XBya"><strong>Среда тестирования </strong>– здесь мы указываем окружение, на котором мы будем проводить тестирование – то есть наша платформа, версия браузера (если это веб-продукт) и т.д.</li>
    <li id="MxEJ"><strong>Тип тестов;</strong></li>
    <li id="zpo7"><strong>Название проверок</strong> - здесь идет название нашей проверки, отображающее то, что именно мы будет проверять в данном тесте;</li>
    <li id="d0jK"><strong>Результат проверки</strong></li>
  </ol>
  <h3 id="DaGi">11. Что такое план тестирования?</h3>
  <p id="yUpJ"><strong>План тестирования</strong> – это официальный документ, определяющий объем тестирования, используемый метод, необходимые ресурсы и расчетное время для завершения процесса. Он составляется на основе спецификаций (требований к программному обеспечению).</p>
  <h3 id="kcAY">12. <strong>Для чего проводится тестирование ПО?</strong></h3>
  <ol id="SOdW">
    <li id="kJE6">Для проверки соответствия требованиям.</li>
    <li id="BsU9">Для обнаружения проблем на более ранних этапах разработки и предотвращения повышения стоимости продукта.</li>
    <li id="4Qbk">Обнаружения вариантов использования, которые не были предусмотрены при разработке. А также взгляд на продукт со стороны пользователя.</li>
    <li id="CqYp">Повышения лояльности к компании и продукту, т.к. любой обнаруженный дефект негативно влияет на доверие пользователей.</li>
  </ol>
  <h3 id="Bie7">13. Принципы тестирования</h3>
  <ul id="fUtV">
    <li id="YRu3"><strong>Принцип 1 — Тестирование демонстрирует наличие дефектов</strong><br />Тестирование только снижает вероятность наличия дефектов, которые находятся в программном обеспечении, но не гарантирует их отсутствия.</li>
    <li id="xVMv"><strong>Принцип 2 — Исчерпывающее тестирование невозможно</strong><br />Полное тестирование с использованием всех входных комбинаций данных, результатов и предусловий физически невыполнимо (исключение — тривиальные случаи).</li>
    <li id="G8eE"><strong>Принцип 3 — Раннее тестирование</strong><br />Следует начинать тестирование на ранних стадиях жизненного цикла разработки ПО, чтобы найти дефекты как можно раньше.</li>
    <li id="nAUZ"><strong>Принцип 4 — Скопление дефектов</strong><br />Большая часть дефектов находится в ограниченном количестве модулей.</li>
    <li id="ADmz"><strong>Принцип 5 — Парадокс пестицида</strong><br />Если повторять те же тестовые сценарии снова и снова, в какой-то момент этот набор тестов перестанет выявлять новые дефекты.</li>
    <li id="JAsx"><strong>Принцип 6 — Тестирование зависит от контекста<br /></strong>Тестирование проводится по-разному в зависимости от контекста. Например, программное обеспечение, в котором критически важна безопасность, тестируется иначе, чем новостной портал.</li>
    <li id="hrqQ"><strong>Принцип 7 — Заблуждение об отсутствии ошибок</strong><br />Отсутствие найденных дефектов при тестировании не всегда означает готовность продукта к релизу. Система должна быть удобна пользователю в использовании и удовлетворять его ожиданиям и потребностям.</li>
  </ul>
  <h3 id="2W8U">14. В чем разница между верификацией и валидацией?</h3>
  <p id="OuvC"><strong>Верификация</strong> оценивает программное обеспечение на этапе разработки, выясняя, соответствует ли продукт ожидаемым требованиям. <br /><strong>Валидация</strong> оценивает готовое ПО на соответствие требованиям заказчика и конечного пользователя.</p>
  <h3 id="XrmS"><strong>15. Что такое требования?</strong></h3>
  <p id="n0Zb"><strong>Требования</strong> — это спецификация (описание) того, что должно быть реализовано.<br />Требования описывают то, что необходимо реализовать, без детализации технической стороны решения.</p>
  <h3 id="TYkL">16. Что такое баг и баг-репорт?</h3>
  <p id="Dcyn"><strong>Баг</strong> – это дефект – это отклонение ожидаемого поведения работы программного продукта от фактического.</p>
  <p id="YUQn"><strong>Баг-репорт</strong> – это отчет об ошибках.</p>
  <p id="mGt9"><strong>Отчёт о дефекте (bug report)</strong> — документ, который содержит отчет о любом недостатке в компоненте или системе, который потенциально может привести компонент или систему к невозможности выполнить требуемую функцию.</p>
  <h3 id="0QJx">17. Атрибуты баг-репорта</h3>
  <ol id="PYOH">
    <li id="x8RO"><strong>Проект</strong></li>
    <li id="dxAP"><strong>Название документа</strong></li>
    <li id="KI8f"><strong>Ссылка на требования</strong></li>
    <li id="qzo6"><strong>Цель проверки</strong></li>
    <li id="J09U"><strong>Дата проведения</strong></li>
    <li id="pSMw"><strong>Исполнитель</strong></li>
    <li id="a2vD"><strong>Среда тестирования</strong></li>
    <li id="FoYP"><strong>Шаги теста</strong></li>
    <li id="qwYC"><strong>Ожидаемый результат</strong></li>
    <li id="8o1m"><strong>Фактический результат</strong></li>
    <li id="42rQ"><strong>Статус бага</strong></li>
    <li id="Tegi"><strong>Серьезность бага</strong></li>
    <li id="MEz2"><strong>Приоритет устранения бага</strong></li>
    <li id="ngkB"><strong>Прикрепленный файл</strong></li>
  </ol>
  <h3 id="g9IT">18. Приоритет устранения и серьезность бага</h3>
  <p id="tVWd"><strong>Серьезность (severity) – </strong>показывает степень ущерба, который наносится проекту существованием дефекта. Severity выставляется тестировщиком.</p>
  <p id="IFZK"><strong>У серьезности могут быть следующие статусы:</strong></p>
  <ul id="UCqM">
    <li id="Tlkp"><strong>Blocker – </strong>блокировка, работа ПО невозможна</li>
    <li id="Mye6"><strong>Critical –</strong>критический, приводит наш функционал в нерабочее состояние, отклонение от БЛ ПО, не реализация функций, потеря пользовательских данных</li>
    <li id="fd9B"><strong>Major-</strong>серьезные ошибки, которые свидетельствуют об отклонении работы от БЛ или нарушающие работу программы, но не имеют критическое воздействие на ПО</li>
    <li id="R0a2"><strong>Minor – </strong>незначительный дефект не нарушающий функционал нашего приложения, который является несоответствием ожидаемого результата (ошибка дизайна, пример)</li>
    <li id="zblv"><strong>Trivial</strong> –не имеет влияния на функционал и работу нашей программы, но может быть обнаружен визуально.</li>
  </ul>
  <p id="WBWm"><strong>Приоритет -</strong> показывает, как быстро дефект должен быть устранён. Priority выставляется менеджером, team-lead или заказчиком.</p>
  <ul id="OtUs">
    <li id="0Xb4"><strong>P1 Высокий (High</strong>)<br />Критическая для проекта ошибка. Должна быть исправлена как можно быстрее.</li>
    <li id="x2fj"><strong>P2 Средний (Medium)</strong><br />Не критичная для проекта ошибка, однако требует обязательного решения.</li>
    <li id="mokX"><strong>P3 Низкий (Low)</strong><br />Наличие данной ошибки не является критичным и не требует срочного решения. Может быть исправлена, когда у команды появится время на ее устранение.</li>
  </ul>
  <h2 id="bzHz"><strong>Основные виды тестирования ПО</strong></h2>
  <h3 id="zXou"><strong>19. Классификация по запуску кода на исполнение:</strong></h3>
  <ul id="airX">
    <li id="3lut"><strong>Статическое тестирование</strong> — тестирование без запуска кода на исполнение. Это процесс обнаружения и устранения ошибок и дефектов в документации: программного кода компонент, требований, системных спецификаций, функциональных спецификаций, документов проектирования и архитектуры программных систем и их компонентов.</li>
    <li id="FU14"><strong>Динамическое тестирование</strong> — тестирование проводится на работающей системе, не может быть осуществлено без запуска программного кода приложения.<br />Запускаться на исполнение может как код всего приложения целиком (системное тестирование), так и код нескольких взаимосвязанных частей (интеграционное тестирование), отдельных частей и даже отдельные участки кода.</li>
  </ul>
  <h3 id="MChp">20. <strong>Классификация по доступу к коду и архитектуре:</strong></h3>
  <ul id="zaNz">
    <li id="TPkW"><strong>Тестирование белого ящика</strong> — метод тестирования ПО, который предполагает полный доступ к коду проекта.</li>
    <li id="ODW4"><strong>Тестирование серого ящика</strong> — метод тестирования ПО, который предполагает частичный доступ к коду проекта (комбинация White Box и Black Box методов).</li>
    <li id="E69B"><strong>Тестирование чёрного ящика</strong> — метод тестирования ПО, который не предполагает доступа (полного или частичного) к системе. Основывается на работе исключительно с внешним интерфейсом тестируемой системы.</li>
  </ul>
  <h3 id="VZBu"><strong>21. Классификация по уровню детализации приложения (Пирамида тестирования):</strong></h3>
  <ol id="ht7D">
    <li id="DQWg"><strong>Модульное тестирование или юнит-тестирование (англ. unit testing)</strong> — проводится для тестирования какого-либо одного логически выделенного и изолированного элемента (модуля) системы в коде. Проводится самими разработчиками, так как предполагает полный доступ к коду.<br /><strong>Модульное тестирование производят сами разработчики, не тестировщики.</strong></li>
    <li id="OmhB"><strong>Интеграционное тестирование (Integration testing)</strong> — тестирование, направленное на проверку корректности взаимодействия нескольких модулей, объединенных в единое целое.<br /><strong>Взаимодействие компонентов, модулей и иных систем между собой. Тестирование части системы, состоящей из 2-х и более модулей.</strong></li>
    <li id="rKlg"><strong>Системное тестирование (System testing)</strong> — тестирование взаимодействия между всеми компонентами системы или разных систем между собой или тестирование интерфейсов, между которыми взаимодействует система. Полная проверка приложения, всех модулей, можно ли пройти весь бизнес путь.</li>
    <li id="cJew"><strong>Приёмочное тестирование</strong> <strong>(acceptance test) — </strong>тестирование на сдаче приемки всего программного продукта или его части Заказчику<br />А) <strong>Пользовательское приемное тестирование (User Acceptance Testing)</strong> – перед релизом собирается группа конечных пользователей, тестируется основной функционал, при наличии дефектов-устраняются.<br />Б)<strong> Эксплуатационное (Operational acceptance testing) </strong>– производится пользователем или администратором в среде, которая имитирует реальные условия эксплуатации ПО, производится тестирование резервного копирования, аварийное восстановление системы, безопасность ПО.<br />В) <strong>На соответствие контракту</strong> – на соответствие гостов, нормативных актов и т.д</li>
  </ol>
  <h3 id="IP8i"><strong>22. Классификация по принципам работы с приложением</strong></h3>
  <ul id="4fht">
    <li id="sRon"><strong>Позитивное тестирование</strong> — тестирование, при котором используются только корректные данные.</li>
    <li id="tRrK"><strong>Негативное тестирование</strong> — тестирование приложения, при котором используются некорректные данные и выполняются некорректные операции.</li>
  </ul>
  <h3 id="JUF6">23. Классификация по целям тестирования</h3>
  <ol id="SDrt">
    <li id="irsE"><strong>Функциональное тестирование</strong> – тестирование которое направленно на проверку соответствия функциональных требований ПО к его реальным характеристикам. Подтверждение того, что наш продукт обладает всем функционалом, который требует заказчик.<br /><strong>Функциональное тестирование отвечает на вопрос – что должен делать наш продукт?</strong></li>
    <li id="HK25"><strong>Нефункциональное тестирование</strong> – направленно на проверку соответствия свойств ПО с его нефункциональными требованиями. Тестирование свойств, которые не относятся к функциональности системы – надежность, производительность и т.д.<br /><strong>Нефункциональное тестирование отвечает на вопрос – как это должен делать наш продукт?</strong></li>
  </ol>
  <h3 id="fGFp"><strong>24. Функциональное тестирование</strong></h3>
  <ol id="qkDU">
    <li id="Ugoy"><strong>Smoke test</strong> — тестирование, которое проводится после появления нового билда . Направлено на проверку готовности разработанного продукта к проведению расширенного тестирования и определения общего качества продукта.<br /><strong>Проверяет заявленную бизнес-логику ПО.</strong></li>
    <li id="6Ofd"><strong>Тестирование критического пути</strong> (critical path) — направлено для проверки функциональности, используемой обычными пользователями во время их повседневной деятельности.<br /><strong>Основной тип тестовых испытаний, во время которого значимые элементы и функции приложения проверяются на предмет правильности работы при их стандартном использовании.</strong></li>
    <li id="IfOq"><strong>Расширенное тестирование</strong> (extended) — направлено на исследование всей заявленной в требованиях функциональности.<br /><strong>Проверка нестандартного использования продукта (например, вводить не корректные логин и пароль в окне авторизации, работать на многих вкладках одновременно, подгрузка файлов недопустимых размеров или форматов. Максимально загружать нашу систему, проводить множество негативных тестов.</strong></li>
  </ol>
  <h3 id="hbBn"><strong>25. Нефункциональное тестирование</strong></h3>
  <ol id="yej0">
    <li id="BPBb"><strong>Тестирование доступности</strong> - доступно ли людям с ограниченными возможностями.<br /><em>Пример: Может ли человек, получив голосовое, прослушать его из верхнего динамика.</em></li>
    <li id="x5S0"><strong>Тестирование локализации и интернетизации</strong> - тестирование с целью проверки адаптации ПО к любой культуре или особенностям языка другой страны.<br /><em>Пример: Можно ли писать сообщения иероглифами (поддерживает ли кодировку)(локализация) или есть ли функция в мессенджере для оповещения о молитвенном времени (интернационализация).</em></li>
    <li id="mGEe"><strong>Тестирование безопасности</strong> - тестирование направленное на проверку безопасности конфиденциальных данных и защиту от хакерских атак, вирусов и тд.<br /><em>Пример: Отправить файл, зараженный вирусом и проверить, пропустит ли его мессенджер. Или встроить в картинку инъекцию.</em></li>
    <li id="bC1I"><strong>Проверка удобства</strong> - тестирование направленное на удобство пользования и дизайна.<br /><em>Пример: Проверить, удобно ли будет пользоваться одной рукой, не режет ли глаз цвета, не маленькая ли кнопка отправить и тд.</em></li>
    <li id="6hYL"><strong>Нагрузочное тестирование</strong> - проводимое тестирование использования в пределах нормы.<br /><em>Пример: Сервер мессенджера рассчитан на 10 человек, и им пользуются 10 человек, отправляя сообщения и допустимые файлы допустимых размеров.</em></li>
    <li id="uEev"><strong>Стресс-тестирование</strong> - нагрузка, превышающая норму в несколько раз.<br /><em>Пример: Сервер мессенджера рассчитан на 10 человек, а им одновременно пользуются 30 человек, активно отправляя сообщения, фото и файлы друг другу.</em></li>
    <li id="CAdC"><strong>Тестирование стабильности</strong> - тестирование, направленное на продолжительное испытание в пределах нормы.<br /><em>Пример: Сервер мессенджера рассчитан на 10 человек, им пользуются 10 человек в рамках стандартного использования в течении месяца (переписываются, отправляют картинки и тд).</em></li>
    <li id="HRG1"><strong>Инсталляционное тестирование</strong> - тестирование, направленное на проверку установки, обновления и удаления приложения.<br /><em>Пример: Скачать приложение, установить его, удалить, установить еще раз и после обновить.</em></li>
  </ol>
  <h3 id="8MiB">25.1. Классификация по цели тестирования</h3>
  <ol id="V2z7">
    <li id="35bC"><strong>Тестирование новой функциональности (new feature test) – </strong>производится, как только была разработана новая функциональность.<br />То есть, как только разработчик выполнил свою часть работы, по созданию новой функциональности, он передает ее на тестирование.</li>
    <li id="8Lwo"><strong>Re-test – </strong>проверка правильности исправления дефекта. Повторное тестирование функционала, в котором был найден дефект, то есть баг.</li>
    <li id="Z3qx"><strong>Регрессионное тестирование –</strong> повторная проверка ранее разработанного функционала, после появления нового билда, то есть новой версии нашего программного продукта, для того, чтоб убедиться, что новый функционал билда никак ему не навредил.<br /><strong>Регрессионное тестирование проводится:<br /></strong>- после появления нового билда (новой версии нашего продукта)<br />- тестирование того функционала в котором часто обнаруживаются дефекты<br />- плановое тестирование<br />- того функционала, который часто меняется в ходе разработки</li>
  </ol>
  <h3 id="1bKC">26. Что такое Тест-дизайн?</h3>
  <p id="p8O8"><strong>Тест-дизайн</strong> — это этап тестирования ПО, на котором проектируются и создаются тестовые случаи (тест-кейсы).</p>
  <h3 id="fCbG"><strong>27. Техники тест-дизайна</strong></h3>
  <ol id="k6FF">
    <li id="GnNy"><strong>Тестирование на основе классов эквивалентности (equivalence partitioning)</strong> — это техника, при которой мы разделяем диапазон возможных вводимых значений на группы эквивалентных по своему влиянию на систему значений.</li>
    <li id="Dddi"><strong>Техника анализа граничных значений (boundary value testing)</strong> — это техника проверки поведения продукта на граничных значениях входных данных.</li>
    <li id="5N0s"><strong>Попарное тестирование (pairwise testing)</strong> — это техника формирования наборов тестовых данных из полного набора входных данных в системе, которая позволяет существенно сократить количество тест-кейсов.</li>
    <li id="l2rg"><strong>Тестирование на основе состояний и переходов (State-Transition Testing)</strong> — применяется для фиксирования требований и описания дизайна приложения.</li>
    <li id="B5QJ"><strong>Таблицы принятия решений (Decision Table Testing)</strong> — техника тестирования, основанная на методе чёрного ящика, которая применяется для систем со сложной логикой.</li>
    <li id="Mznz"><strong>Доменный анализ (Domain Analysis Testing)</strong> — это техника основана на разбиении диапазона возможных значений переменной на поддиапазоны, с последующим выбором одного или нескольких значений из каждого домена для тестирования.</li>
    <li id="zOl9"><strong>Сценарий использования (Use Case Testing)</strong> — Use Case описывает сценарий взаимодействия двух и более участников (как правило — пользователя и системы).</li>
  </ol>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/EVWXQ0UDG9u</guid><link>https://teletype.in/@alexbrin/EVWXQ0UDG9u?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/EVWXQ0UDG9u?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>f-строки (очень удобно)</title><pubDate>Thu, 07 Mar 2024 21:14:08 GMT</pubDate><category>python course for me</category><description><![CDATA[Когда вы указываете перед стройкой f python воспринимает её как необычную строку и каждое содержимое фигурных скобок он будет воспринимать как выражение на языке программирования. В фигурных скобках вы можете писать свои какие-либо выражения и никто не запрещает вам воспользоваться математическими операциями.]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#dvl7">Код внутри скобок</a></li>
      <li class="m_level_1"><a href="#k5Pw">Вывод переменных</a></li>
      <li class="m_level_2"><a href="#aYZ3">С обозначением переменных</a></li>
      <li class="m_level_1"><a href="#I6n6">Формат вывода дробной части числа</a></li>
      <li class="m_level_1"><a href="#442D">Формат вывода целых чисел</a></li>
      <li class="m_level_2"><a href="#piVR">Пробелы перед числом (выравнивание)</a></li>
      <li class="m_level_2"><a href="#ZAgu">Выравнивание с помощью нулей (добавление в начало нулей)</a></li>
      <li class="m_level_2"><a href="#rJKQ">Разделение разрядов числа (например, вместо 1000000 - 1_000_000)</a></li>
      <li class="m_level_1"><a href="#OJc3">Выравнивание</a></li>
      <li class="m_level_2"><a href="#yA6k">Практический пример выравнивания</a></li>
    </ul>
  </nav>
  <h2 id="dvl7">Код внутри скобок</h2>
  <p id="lrxM">Когда вы указываете перед стройкой <code>f</code> python воспринимает её как необычную строку и каждое содержимое фигурных скобок он будет воспринимать как выражение на языке программирования. В фигурных скобках вы можете писать свои какие-либо выражения и никто не запрещает вам воспользоваться математическими операциями.</p>
  <figure id="viqR" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/9de41bb244?start=result"></iframe>
  </figure>
  <p id="z4Fz">Вы можете пользоваться всеми возможностями ваших объектов. В нашем случае переменная name является строкой и мы знаем что у каждой строки есть метод lower. Давайте мы применим метод lower делает все буквы строки маленькими.</p>
  <figure id="S7I6" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/e3c39774ba?start=result"></iframe>
  </figure>
  <p id="U207">В скобках вы можете вообще не использовать переменные. То есть вы можете просто написать здесь какие-либо числа и это выражение также посчитается и будет выведен его результат.</p>
  <figure id="iuBR" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/aaa892022a?start=result"></iframe>
  </figure>
  <p id="ZDaj">Внутри скобок вы можете также вызвать другие функции. Например, мы можем вызвать функцию abs() от отрицательного числа</p>
  <figure id="mPCC" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/4adf2130d7?start=result"></iframe>
  </figure>
  <h2 id="k5Pw">Вывод переменных</h2>
  <h3 id="aYZ3">С обозначением переменных</h3>
  <p id="PHrU">Начиная с версии <code>Python 3.8</code> функционал <code>f-строк</code> был дополнен новой возможностью по выводу имён переменных и их значений. Посмотрите как теперь это можно сделать:</p>
  <figure id="rkS4" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/0ab823c015?start=result"></iframe>
  </figure>
  <p id="pun5">Вам достаточно указать название переменной и знак равно. Будет выведено автоматически и имя переменной и ее значение. При этом и знаки пробелов, если они указаны, будут учтены.</p>
  <h2 id="I6n6">Формат вывода дробной части числа</h2>
  <p id="apqh">Встречаются задачи, где нужно вывести только определенное количество знаков после запятой. Допустим, мы хотим вывести ровно три знака после запятой для любого числа. Но далеко не у всех чисел в представлении есть эти три знака после запятой. У некоторых чисел они есть, у других либо не хватает знаков, либо имеется больше чем хотелось бы</p>
  <p id="ldvG">Ответ простой - форматировать. <code>F-строки</code> поддерживают <a href="https://docs.python.org/3/reference/lexical_analysis.html#f-strings" target="_blank">функционал форматирования</a>. Мы указываем специальным образом после имени переменной сколько символов ожидаем увидеть.</p>
  <figure id="m93J" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/2252d21fba?start=result"></iframe>
  </figure>
  <p id="4X78">Запись <code>c:.3f</code> говорит, что переменную <code>c</code> нужно представить в вещественном виде (это знак <code>f</code>) и отобразить три символа после запятой. Если у переменной <code>c</code> не хватает символов для трех знаков, проставятся нули. Если символов в избытке, произойдет округление до третьего символа после запятой.</p>
  <p id="m4TB">Над целыми числами тоже можно так издеваться)</p>
  <figure id="hRhZ" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/9387b32722?start=result"></iframe>
  </figure>
  <h2 id="442D">Формат вывода целых чисел</h2>
  <h3 id="piVR">Пробелы перед числом (выравнивание)</h3>
  <p id="cEwr">При помощи <code>f-строк</code> мы можем влиять и на отображение целых чисел.</p>
  <figure id="SHT0" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/2b9a7a78c5?start=result"></iframe>
  </figure>
  <p id="UuvY">Запись <code>n:7d</code> говорит, что переменную <code>n</code> нужно представить в виде целого числа (это знак  d ) и на отображение всего числа выделить 7 знаков. Если у переменной <code>n</code> не хватает разрядов до семи, то впереди отображения появятся знаки пробелов.</p>
  <h3 id="ZAgu">Выравнивание с помощью нулей (добавление в начало нулей)</h3>
  <p id="SM74">Можно вместо пробелов добавить незначащие нули, для этого нужно подписать 0 перед количеством разрядов</p>
  <figure id="wAIM" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/18cbb779c1?start=result"></iframe>
  </figure>
  <h3 id="rJKQ">Разделение разрядов числа (например, вместо 1000000 - 1_000_000)</h3>
  <p id="lcFZ">Можно также влиять на знак разделителя между группами чисел, посмотрите пример ниже</p>
  <figure id="sZxa" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/f2aa2cf3ea?start=result"></iframe>
  </figure>
  <h2 id="OJc3">Выравнивание</h2>
  <p id="uP98">Существует несколько способов выравнивания переменных в <code>f-строках</code>. Различные варианты выравнивания следует:</p>
  <p id="HrqT"><code>&lt;</code> - Выравнивает выражение в фигурных скобках по левому краю. У строк такое поведение по умолчанию</p>
  <p id="KTq4"><code>&gt;</code> - Выравнивает выражение в фигурных скобках по правому краю. У чисел такое поведение по умолчанию</p>
  <p id="ol1O"><code>^</code> - Выравнивает выражение в фигурных скобках по центру</p>
  <p id="P2QN">Ниже приведен пример использования выравнивания как для чисел, так и для строк.</p>
  <figure id="vHRt" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/02106a0e80?start=result"></iframe>
  </figure>
  <p id="GraL">Символы &quot;|&quot; используются в <code>f-строке</code>, чтобы помочь очертить интервал. Число после «:» указывает на количество символов в ширину.</p>
  <p id="dbsd">По умолчанию символом заполнителем является пробел, но можно его заменить на другое значение</p>
  <figure id="uvLc" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/db51de6167?start=result"></iframe>
  </figure>
  <h3 id="yA6k">Практический пример выравнивания</h3>
  <p id="4Jhr">Давайте с вами смоделируем чек покупки. Пример ниже</p>
  <figure id="rsRy" class="m_full_width">
    <iframe src="https://trinket.io/embed/python3/d227ac6fa0?start=result"></iframe>
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/84vyhNqmW6L</guid><link>https://teletype.in/@alexbrin/84vyhNqmW6L?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/84vyhNqmW6L?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>14.5 Создание запросов в ручную</title><pubDate>Wed, 21 Feb 2024 16:15:56 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/d0/5d/d05dbab7-0f17-4ad9-a46e-4a13c57c5d39.png"></media:content><category>Алекс Смит: Тестирование ПО с Нуля до Специалиста</category><description><![CDATA[<img src="https://img2.teletype.in/files/57/b2/57b20406-6ecb-4ded-95ee-8d55155de06e.png"></img>1. Пользователь открыл Википедию для того, чтобы открыть какую либо статью.]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#5PoJ">Создаем первый тестовый сценарий</a></li>
      <li class="m_level_2"><a href="#SHpy">Сымитируем следующую деятельность пользователя:</a></li>
      <li class="m_level_2"><a href="#sP3e">Теперь запишем по запросам все шаги:</a></li>
    </ul>
  </nav>
  <h2 id="5PoJ">Создаем первый тестовый сценарий</h2>
  <h3 id="SHpy">Сымитируем следующую деятельность пользователя:</h3>
  <p id="vnvr">1. Пользователь открыл Википедию для того, чтобы открыть какую либо статью.</p>
  <p id="ePVu">2. Далее ему нужно нажать кнопку поиска либо ввести какие то данные в поле &quot;Искать в Википедии&quot;. Но в нашей ситуации он нажал кнопку &quot;Поиск&quot;.</p>
  <p id="slFi">3. Перешли на поисковую страницу с полем для запроса и фильтрами.</p>
  <figure id="HHm4" class="m_column">
    <img src="https://img2.teletype.in/files/57/b2/57b20406-6ecb-4ded-95ee-8d55155de06e.png" width="986" />
  </figure>
  <p id="NFiw">4. Пользователь вводит в поле поиска слово &quot;Париж&quot; и нажимает кнопку &quot;Найти&quot;. Ему выдаются результаты поиска.</p>
  <figure id="2ywE" class="m_column">
    <img src="https://img2.teletype.in/files/16/5b/165bd195-db94-41aa-bd7b-54fa62fca03a.png" width="1003" />
  </figure>
  <p id="3xmn">5. В результатах поиска ему нужно выбрать ту статью, которую он хочет почитать. Допустим, он хочет почитать про город Париж.</p>
  <figure id="CyOX" class="m_column">
    <img src="https://img3.teletype.in/files/28/b9/28b9905f-a983-4ab8-964a-e1ed9e3bb00a.png" width="1127" />
  </figure>
  <p id="EEEd"><strong>Мы обозначили тот тестовый сценарий, который мы выполнили.</strong></p>
  <h3 id="sP3e">Теперь запишем по запросам все шаги:</h3>
  <figure id="QPQ1" class="m_column">
    <img src="https://img3.teletype.in/files/af/92/af92e3c6-98e8-47b1-b05a-933eea3d50db.png" width="613" />
  </figure>
  <p id="SAjs">Jmeter - это не браузер, не Selenium. В процессе работы мы не обращаемся к браузеру, а работаем только с конечными точками (с ссылками). А на основании расположения запросов создаем сценарий. </p>
  <p id="2PFn">Если запустить тест с 5 пользователями, то нарушается порядок прохождения тестов</p>
  <figure id="f18w" class="m_column">
    <img src="https://img1.teletype.in/files/03/09/0309c793-04ac-488a-ae0d-bc645bc79b24.png" width="891" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/D3Ygp9zBdfN</guid><link>https://teletype.in/@alexbrin/D3Ygp9zBdfN?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/D3Ygp9zBdfN?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>13.4 Методика нагрузочного тестирования</title><pubDate>Wed, 21 Feb 2024 14:55:56 GMT</pubDate><category>Алекс Смит: Тестирование ПО с Нуля до Специалиста</category><description><![CDATA[Методика нагрузочного тестирования – это документ, который включает в себя: цели тестирования, объект тестирования, стратегию тестирования, описание тестового стенда, моделирование нагрузки описание заглушек, эмуляторов, баз данных средств. Данный документ обязательно должен согласоваться.]]></description><content:encoded><![CDATA[
  <p id="I2wV">Методика нагрузочного тестирования – это документ, который включает в себя: цели тестирования, объект тестирования, стратегию тестирования, описание тестового стенда, моделирование нагрузки описание заглушек, эмуляторов, баз данных средств. Данный документ обязательно должен согласоваться.</p>
  <p id="4ttR">Давайте более подробней пройдемся по каждому пункту:</p>
  <p id="UN0S"><strong>1. Цели тестирования, их разделяют:</strong></p>
  <p id="h5zF"><strong>Технические цели </strong>– например, тестирование надежности, отказоустойчивости и т.д.</p>
  <p id="3PLU"><strong>Бизнес цели</strong> – к примеру, изменение информационной инфраструктуры или системы, то есть проверка нового ПО и его функционала.</p>
  <p id="O4oz"><strong>2. Объект тестирования</strong> – данный раздел включает в себя архитектуры системы, то есть ее характеристики, ее компоненты и взаимосвязь компонентов между собой.</p>
  <p id="yvyl"><strong>3. Стратегия тестирования</strong> - он включает в себя описание проводимых испытаний для каждой цели тестирования.</p>
  <p id="kTov">Давайте рассмотрим пример:</p>
  <h3 id="Mv0D">Тестирование надежности</h3>
  <p id="U4Ry">Тест надежности выполняется на уровне нагрузки:</p>
  <p id="SPks">1. Нагрузка системы в количестве 70-90 % от уровня найденной максимальной производительности.</p>
  <p id="pwdd">2. При повторном тестировании и тестировании нового функционала нагружаем на 100-120% от пиковой производительности нашей системы. Что это значит, мы анализируем нагрузку, которая поступает на наш сервер в течении всей недели, отбираем к примеру день, когда у нас максимальная нагрузка, отбираем час, когда у нас максимальная нагрузка (например это 11 часов дня, в это время у нас самое большое количество пользователей на нашем сайте, они совершают максимальную нагрузку нашего сервера) мы берем либо этот час, либо среднее по всем часам, например, суммируем всю нагрузку с 11-12:00 и делим на 7. Это наш показатель, от которого мы отталкиваемся и нагружаем нашу систему на 100-120%, если система выдерживает данную нагрузку, значит и с остальной она справится.</p>
  <p id="ctQ7">Длительность тестирования определяется требуемым интервалом доступности системы (в идеале 24х7). Но здесь надо анализировать, что есть так же привязанность к датам, например на сайте большая активность в конце месяца или в какое-то определенное число, например день отчетности, и именно в этот день у нас максимальная нагрузка нашего стенда, в идеале, чтоб именно этот день попадал в наш период.</p>
  <p id="3jD9">И так по каждой цели тестирования, то есть данный раздел очень объемным.</p>
  <p id="htMr">Мы обязательно должны указать в данном разделе критерии успешного завершения нагрузочного тестирования являются:</p>
  <p id="MWg3">1)выполнение всех запланированных тестов</p>
  <p id="5Gsx">2)получение данных с мониторинга</p>
  <p id="2twE"><strong>4. Тестовый стенд</strong></p>
  <p id="3ptY">Здесь указывается:</p>
  <p id="XRr8">1)архитектура тестового стенда – описание самого стенда, описание смежных систем</p>
  <p id="as6e">2)требования к оборудованию тестового стенда, его характеристики</p>
  <p id="GR0F">3)очень важны пункт – сравнение тестового и пользовательского, так как нам очень важно, чтобы они были равны</p>
  <p id="wVJn"><strong>5. Моделирование нагрузки</strong> - описанием процессов, операций, которые проводят пользователи в нашей системе.</p>
  <p id="Z7KB">Здесь идет описание наших операций, например авторизация на сайте, подача каких-либо заявок в банковском софте, покупок в интернет магазине, поиск данных в поисковом сервисе и т.д. указывается количество дынных операций в пиковый час, среднее количество.</p>
  <p id="mNrG">Так же здесь у нас указывается профиль нагрузки, где у нас идут данные за весь месяц 24 на 7.</p>
  <p id="Sg1T"><strong>6. Описание заглушек и эмуляторов</strong>, в которых мы описываем их характеристики и что они выполняют</p>
  <p id="taph"><strong>7. Базы данных</strong></p>
  <p id="XS7a">В нем описываются характеристики БД, ее наполнение, то есть количество данных в ней</p>
  <p id="1vVw"><strong>8. Мониторинг</strong></p>
  <p id="caUh">Мониторинг необходим для сбора характеристик производительности компонент системы. В данном разделе описывается вспомогательное ПО для проведения мониторинга</p>
  <p id="S7fV">Как вы уже могли понять данный документ очень Важен и к его составлению необходимо подходить очень тщательно</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/KwteANVnACz</guid><link>https://teletype.in/@alexbrin/KwteANVnACz?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/KwteANVnACz?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>13.3 Этапы нагрузочного тестирования</title><pubDate>Wed, 21 Feb 2024 14:36:49 GMT</pubDate><category>Алекс Смит: Тестирование ПО с Нуля до Специалиста</category><description><![CDATA[Прежде чем приступать к самому процессу тестирования, нам необходимо к нему подготовиться, учесть все особенности системы, подготовить документацию и тестовые данные, инструменты, стенды и т.д.]]></description><content:encoded><![CDATA[
  <p id="LBjM">Прежде чем приступать к самому процессу тестирования, нам необходимо к нему подготовиться, учесть все особенности системы, подготовить документацию и тестовые данные, инструменты, стенды и т.д.</p>
  <nav>
    <ul>
      <li class="m_level_1"><a href="#ouyf">Основные этапы проведения нагрузочного тестирования:</a></li>
      <li class="m_level_2"><a href="#hs42">1.  Определение и постановка задачи</a></li>
      <li class="m_level_2"><a href="#iqo1">2. Подготовка тестового стенда и средств тестирования</a></li>
      <li class="m_level_2"><a href="#1cD3">3. Подготовка тестового плана или как его еще называют методики Нагрузочного Тестирования</a></li>
      <li class="m_level_2"><a href="#qGO4">4.  Настройка тестового стенда и вспомогательного ПО</a></li>
      <li class="m_level_2"><a href="#YGrt">5. Проведение нагрузочного тестирования</a></li>
      <li class="m_level_2"><a href="#TGsf">6.  Подготовка отчета и анализ результата тестирования</a></li>
    </ul>
  </nav>
  <h2 id="ouyf">Основные этапы проведения нагрузочного тестирования:</h2>
  <ol id="q46K">
    <li id="iRe3">Определение и постановка задач.</li>
    <li id="g8hO">Подготовка тестового стенда и средства тестирования.</li>
    <li id="6trn">Подготовка тестового плана (методики НТ).</li>
    <li id="KGme">Настройка тестового стенда и вспомогательного ПО.</li>
    <li id="BksX">Проведение нагрузочных тестов.</li>
    <li id="NJNi">Подготовка отчетов и анализ результатов тестирования.</li>
  </ol>
  <h3 id="hs42"><strong>1.  Определение и постановка задачи</strong></h3>
  <p id="DQYa">На данном этапе:</p>
  <ul id="Ishm">
    <li id="DLyo"><strong>Сбор информации о продукте:</strong> мы собираем всю информацию о продукте: требования к производительности продукта, какие операции совершают наши пользователи, для того, чтоб в дальнейшем составить тест-кейсы. Определяем цели тестирования.</li>
    <li id="R8Vp"><strong>Определение состава группы по нагрузочному тестированию:</strong> определяем состав группу, количество тестировщиков занятых в данном процессе, так же других участников, например аналитики, архитекторы, проджект менеджеры и т.д.</li>
    <li id="2xNX"><strong>Определение и согласование целей тестирования:</strong> определяем цели нашего тестирования и обязательно согласовываем их с вышестоящим руководством.</li>
  </ul>
  <h3 id="iqo1">2. <strong>Подготовка тестового стенда и средств тестирования</strong></h3>
  <p id="vY1s">На данном этапе:</p>
  <ul id="IGVE">
    <li id="oEGu"><strong>Подготовка стендов для тестирования:</strong> подготовка стенда, который по своим характеристикам максимально приближен к продакшену, сюда можно отнести, к примеру базу данных, которая должна быть загружена по объему максимально близко к базе данных продакшена, так как нам необходимо максимально точно воссоздать условия нашего тестирования.</li>
    <li id="gagY"><strong>Подготовка ПО для тестировщиков</strong>, то есть установка всех необходимых программ.</li>
    <li id="FHjs"><strong>Получение доступов к стендам для тестировщиков.</strong></li>
  </ul>
  <h3 id="1cD3">3. <strong>Подготовка тестового плана или как его еще называют методики Нагрузочного Тестирования</strong></h3>
  <p id="eH5y">На данном этапе:</p>
  <ul id="0qs6">
    <li id="sUsC"><strong>Написание тест-кейсов.</strong></li>
    <li id="EuVf"><strong>Согласование сроков.</strong></li>
    <li id="2Qq3"><strong>Согласование участников тестирования.</strong></li>
    <li id="7fj7"><strong>Частота проведения тестов.</strong></li>
  </ul>
  <p id="s1ZL">В данном документе описываются тест-кейсы, то есть тестовые сценарии процессов, шагов, которые мы будем проводить во время нашего тестирования, с целью сымитировать деятельность конечных пользователей, так же здесь описываются сроки, количество участников, частота проведения наших тестов и т.д.</p>
  <h3 id="qGO4">4.  <strong>Настройка тестового стенда и вспомогательного ПО</strong></h3>
  <p id="lnJy">Окончательная настройка нашего стенда, вспомогательного ПО, подготовка эмуляторов и заглушек для нашей системы.</p>
  <p id="VCTj"><strong>Заглушка</strong> – это часть нашей системы, которая всегда отвечает одинаково, то есть когда мы отправляем в нее запрос, она всегда отвечает однотипно.</p>
  <p id="2Gi8"><strong>Эмулятор</strong> же в свою очередь, обладает большей логикой и способен выдавать различные ответы.</p>
  <h3 id="YGrt">5. <strong>Проведение нагрузочного тестирования</strong></h3>
  <ul id="MUC9">
    <li id="7eYX"><strong>Дымовое тестирование:</strong> В первую очередь мы проводим smoke тестирование, то есть прогоняем небольшие тесты, для того чтоб проверить что наша система вообще работает и выполняет свою основную бизнес-логику. Это обязательное условие перед полноценным тестированием, это можно сравнить с разведкой обстановки.</li>
    <li id="MBHg"><strong>Определение максимальной производительности системы:</strong> Определение максимальной производительности, то есть мы хотим узнать предельные способности нашей системы, этот показатель очень важен для нас и будет в дальнейшем использоваться и сравниваться с другими показателями нашей системы.</li>
    <li id="ZJEg"><strong>90% от максимальной производительности системы:</strong> Нам необходимо повторно произвести определение максимальной производительности, процентов 90 от предыдущего значения, для того, чтоб убедиться что мы получили верные данные.</li>
    <li id="WBDF"><strong>Тестирование надежности.</strong></li>
  </ul>
  <h3 id="TGsf"><strong>6.  Подготовка отчета и анализ результата тестирования</strong></h3>
  <ul id="y0J9">
    <li id="qZwE"><strong>Фиксирование процента успешных операций:</strong> процент успешных операций, так называемая доступность.</li>
    <li id="dLP2"><strong>Фиксирование отклика системы на нагрузку:</strong> время отклика системы на нагрузку.</li>
    <li id="uyDM"><strong>Фиксирование пропускной способности системы:</strong> пропускная способность—количество операций в единицу времени, которое способна выполнять система.</li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/otQJ1Mlh7gF</guid><link>https://teletype.in/@alexbrin/otQJ1Mlh7gF?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/otQJ1Mlh7gF?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>13.2 Когда необходимо проводить нагрузочное тестирование</title><pubDate>Wed, 21 Feb 2024 13:01:07 GMT</pubDate><category>Алекс Смит: Тестирование ПО с Нуля до Специалиста</category><description><![CDATA[Когда проводится нагрузочное тестирование:]]></description><content:encoded><![CDATA[
  <p id="KI8V">Когда проводится нагрузочное тестирование:</p>
  <p id="IXql">1.  <strong>Выпуск нового ПО</strong> - мы только выпустили наше программное обеспечение и мы хотим выяснить, соответствует ли оно заявленным требованиям или нет, проводим определение максимальной производительности, выявляем узкие места, стресс тестирование и осуществляем проверку отказоустойчивости;</p>
  <p id="FpQj">2.  <strong>Появление нового функционала </strong>– в нем мы нагружаем именно новый функционал, например почтовый сервис решил добавить новую функцию, в виде поисковой системы. Если ранее мы тестировали только то, что связано отправкой сообщений, то теперь нам необходимо так же протестировать и саму поисковую систему на ту нагрузку которая она способна выдержать;</p>
  <p id="P1QV">3.  <strong>Регрессионное тестирование</strong> <strong>или плановое</strong> <strong>тестирование</strong> - то есть тестирование, которое производится после разработки нового функционала или по плану( у вас есть определённое расписание, когда вы производите нагрузочное тестирование Вашего продукта);</p>
  <p id="CHXH">4.  <strong>Исследовательское</strong> - это тестирование когда мы хотим выяснить максимальные возможности нашей системы, то есть мы проводим определение максимальной производительности, нагружаем нашу систему в течении длительного времени, производим стрессовое тестирование и т.д.;</p>
  <p id="vsbx">5.  <strong>Смена технологий</strong> - когда наша система переходит с одной базы данных на другую, меняется оборудование и мощности. Мы нагружаем нашу систему и смотрим, чтоб она работала в соответствии с требованиями, предъявленными к ней;</p>
  <p id="jKDO">6.  <strong>При поступлении багов с продакшен сервера</strong> - нам необходимо воспроизвести те же самые условия на тестовом стенде максимально близко к реальным, выяснить, почему наша система не справилась.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/IOy5y4F2PQP</guid><link>https://teletype.in/@alexbrin/IOy5y4F2PQP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/IOy5y4F2PQP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>13.1 Введение в Нагрузочное тестирование. Цели нагрузочного тестирова</title><pubDate>Wed, 21 Feb 2024 12:44:58 GMT</pubDate><category>Алекс Смит: Тестирование ПО с Нуля до Специалиста</category><description><![CDATA[От любой системы требуется быстро и правильно отвечать на запросы пользователей, то есть выполнять те команды и задачи, которые требует от нее пользователь. Например, выдавать результат поиска на поисковых сайтах, например Яндекс или Google, или отправка сообщения в социальных сетях и т.д.]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#LAce">Для чего нужно нагрузочное тестирование?</a></li>
      <li class="m_level_2"><a href="#VUMj">Нагрузочное тестирование</a></li>
      <li class="m_level_1"><a href="#RfPV">Цели нагрузочного тестирования</a></li>
    </ul>
  </nav>
  <p id="Tpsz">От любой системы требуется быстро и правильно отвечать на запросы пользователей, то есть выполнять те команды и задачи, которые требует от нее пользователь. Например, выдавать результат поиска на поисковых сайтах, например Яндекс или Google, или отправка сообщения в социальных сетях и т.д.</p>
  <h2 id="LAce">Для чего нужно нагрузочное тестирование?</h2>
  <p id="LPD7">За правильность - отвечают функциональные свойства продукта, а вот за скорость подачи запроса, отработки и возвращения ответа отвечают нефункциональные свойства нашего продукта.</p>
  <p id="ePIR">Среди тестировщиков и тестирования в целом, есть распределение на функциональных тестировщиков, как раз тех, которые проверяют функциональные свойства продукта, так и нефункциональных тестировщиков, часть из которых как раз занимается нагрузочным тестированием, то есть тестированием производительности.</p>
  <p id="JaZH">Для чего же необходимо производить нагрузочное тестирование, давайте разберем пример:</p>
  <blockquote id="aVzj">Все мы знаем про черную пятницу, это день скидок, когда мы можем купить товар с большой скидкой. Представим, что у нас есть интернет-магазин по продаже электроники, и для него норма производительности, скажем 1000 пользователей, одновременно находящихся на сайте и выполняющие определенные действия -регистрация, поиск товара, оформление товара, покупка.<br />Наступает черная пятница, и вместо 1000 человек, на нашем сайте одновременно находится 10000 человек, что же произойдет? Норма превышена в 10 раз и в лучшем случае сайт будет работать медленней, часть операций не будет проходить, а в худшем случае наш сервер вовсе выйдет из строя и хозяева данного ресурса понесут большие убытки.</blockquote>
  <p id="FI4e">Так вот чтоб это предотвратить, необходимо производить нагрузочное тестирование, смотреть на его пропускную способность, то есть количество операций в единицу времени, которое способна выполнять Система, улучшать свои мощности. Так же примером может послужить онлайн игры, ведь не зря там идет разбивка на различные сервера, и не только по причине разделения по территории, языку, но и в том числе, чтоб распределить нагрузку равномерно и пользователи получили комфортную игру.</p>
  <h3 id="VUMj">Нагрузочное тестирование</h3>
  <p id="GUyd"><strong>Нагрузочное тестирование</strong> – это получение и анализ показателей производительности программного продукта (системы), в ответ на полученную нагрузку извне, с целью установления соответствия ожидаемого результата поведения программного продукта и фактического.</p>
  <p id="KKqI">Под ожидаемым результатом, здесь понимаются показатели, которые указаны в требованиях, которые предъявляются к нашему продукту, а фактические – это те, которые мы получаем в ходе проверки. Проще говоря – это проверка того, как ведет себя система под нагрузкой.</p>
  <h2 id="RfPV">Цели нагрузочного тестирования</h2>
  <p id="3Llv">1.  <strong>Определение максимальной производительности системы</strong> - в ходе данного тестирования, мы максимально нагружаем нашу систему запросами и смотрим на время отклика системы и количество ошибок (сбоев) системы.</p>
  <p id="tE0d">2.  <strong>Выявление проблемных участков </strong>или как их еще называют- «узких мест»;</p>
  <p id="1dbO">3.  <strong>Проверка стабильности (</strong>в некоторых источниках вы можете встретить название надежности) – длительная нагрузка нашей системы при нормальных условиях 70-80 % от максимума(который указан в требованиях и который должна выдерживать наша система);</p>
  <blockquote id="hY7o">Предположим что у нас есть интернет магазин. Заказчик закладывает что <strong>норма</strong> посещения сайта 500 пользователей одновременно. То есть по статистике больше не сидит. Прописывает <strong>максимум</strong> системы, то есть максимальное количество пользователей, который сайт должен выдерживать, например 1000, вдруг праздники, распродажи и т.д</blockquote>
  <p id="n61D">4.  <strong>Проверка системы под действием стресс-нагрузки</strong> – это тестирование, когда мы нагружаем нашу систему нагрузкой, которая в несколько раз превышает норму. Это как раз тот сценарий с черной пятницей в интернет-магазине, о котором я говорил;</p>
  <p id="10vH">5.  <strong>Re-test</strong>, то есть проверка исправления ошибки - когда мы обнаружили проблемный участок в нашей системе, разработчики его поправили и мы производим повторную проверку;</p>
  <p id="9DJB">6.  <strong>Проверка отказоустойчивости</strong> - отключаем часть сервисов в нашей системе, у нас копится нагрузка, очереди запросов. Потом мы их включаем и смотрим как быстро система восстановится. Включаем и отключаем компоненты системы, смотрим как система будет на это реагировать.</p>
  <blockquote id="NcXI">Приведу простой пример: у нас есть ванна, в которой мы моемся, мы включаем воду, вода уходит в отверстие и наша ванна постоянно пуста. Теперь представьте, что мы закрыли данное отверстие пробкой и вода начала скапливаться, достигла определенного объема, ванна полная и мы вытащили нашу пробку, вода начала уходить, освобождая нашу ванну. Так вот время пока вода полностью не уйдет, это как раз время, за которое наша система восстановится.</blockquote>
  <p id="Eub7">7.  <strong>Воспроизведение проблем промышленной среды</strong> - представим что на Проде, на нашем боевом сервере, обнаружилась ошибка и мы пытаемся ее воспроизвести на нашем тестовом стенде. Тестовый стенд всегда отличается от Прода, даже если установлена одна версия ПО. Если мы на Проде получили проблему, ее нужно постараться воспроизвести на тестовом стенде максимально похоже.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@alexbrin/kcKuxSh6jQl</guid><link>https://teletype.in/@alexbrin/kcKuxSh6jQl?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin</link><comments>https://teletype.in/@alexbrin/kcKuxSh6jQl?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alexbrin#comments</comments><dc:creator>alexbrin</dc:creator><title>Работа над ошибками в коммитах</title><pubDate>Mon, 19 Feb 2024 14:38:52 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/4d/fa/4dfac0b5-5c19-49a2-b62c-789221a2792c.png"></media:content><category>Git Яндекс Практикум</category><description><![CDATA[<img src="https://img4.teletype.in/files/3f/3a/3f3a5aaa-4797-48a8-ae21-038e8bc20a28.png"></img>То, как написаны сообщения коммитов, тоже может подчиняться определённым правилам. Иногда эти правила продиктованы культурой команды, а иногда техническими ограничениями.]]></description><content:encoded><![CDATA[
  <nav>
    <ul>
      <li class="m_level_1"><a href="#aNX3">Зачем вообще писать сообщения</a></li>
      <li class="m_level_1"><a href="#Zcwk">Стили оформления</a></li>
      <li class="m_level_2"><a href="#rhpo">Корпоративный</a></li>
      <li class="m_level_2"><a href="#ZoWY">Conventional Commits</a></li>
      <li class="m_level_2"><a href="#mUbh">GitHub-стиль</a></li>
      <li class="m_level_1"><a href="#Fgmt">Как исправить коммит</a></li>
      <li class="m_level_2"><a href="#28pY">Подготавливаем репозиторий</a></li>
      <li class="m_level_2"><a href="#p7bk">Дополнить коммит новыми файлами — git commit --amend --no-edit</a></li>
      <li class="m_level_2"><a href="#Arqp">Изменить сообщение коммита — git commit --amend -m "Новое сообщение"</a></li>
      <li class="m_level_1"><a href="#na8h">Как откатиться назад, если «всё сломалось»</a></li>
      <li class="m_level_2"><a href="#YMem">Выполнить unstage изменений — git restore --staged <file></a></li>
      <li class="m_level_2"><a href="#uX7S">«Откатить» коммит — git reset --hard <commit hash></a></li>
      <li class="m_level_2"><a href="#6KTO">«Откатить» изменения, которые не попали ни в staging, ни в коммит, — git restore <file></a></li>
    </ul>
  </nav>
  <p id="zHev">То, как написаны сообщения коммитов, тоже может подчиняться определённым правилам. Иногда эти правила продиктованы культурой команды, а иногда техническими ограничениями.</p>
  <p id="mCbg">Например, в выводе команды <code>git log --oneline</code> умещается максимум 7272 первых символа сообщения, поэтому многие правила включают пункт: «Сообщение не должно быть длиннее 7272 символов».</p>
  <p id="8bAq">В этом уроке рассмотрим несколько популярных подходов к оформлению сообщений коммитов. Но сначала разберём, почему такие сообщения важны и зачем соблюдать правила их оформления.</p>
  <h3 id="aNX3">Зачем вообще писать сообщения</h3>
  <p id="WnvY">У каждого коммита в Git есть сообщение — то, что передаётся после параметра <code>-m</code>. Например: <code>git commit -m &quot;Добавить урок про оформление сообщений коммитов&quot;</code>.</p>
  <p id="UgUd">Сообщения коммитов можно сравнить с надписями на коробках в кладовке. Если надписей нет, то нужную коробку будет сложно найти: придётся заглянуть в каждую, чтобы понять, что там. А если надписи есть, то нужная найдётся сразу.</p>
  <p id="32ps">Как и надпись на коробке, сообщение коммита должно помочь определить, что внутри. Например, надпись на коробке «всякое разное» не очень полезная. Сообщение коммита «небольшие исправления» тоже: непонятно, что было исправлено в таком коммите и зачем.</p>
  <p id="F8MM">Есть общие рекомендации по тому, как правильно составить сообщение. Оно должно быть:</p>
  <ul id="w3Xi">
    <li id="BHFg">относительно коротким, чтобы его было легко прочитать;</li>
    <li id="DINB">информативным.</li>
  </ul>
  <p id="i9n9">Вот пример полезного сообщения в репозитории новостного сайта: <code>Исправление опечатки в заголовке главной страницы на хорватском</code>. Такое сообщение даёт много информации:</p>
  <ul id="4EgV">
    <li id="VDgi"><code>Исправление опечатки</code> значит, что исправлена ошибка, которая была допущена при наборе. Такое исправление не меняет смысл. То есть, например, главному редактору не нужно перепроверять этот заголовок.</li>
    <li id="E6vM"><code>На хорватском</code> говорит о том, что переводчикам на другие языки этот коммит можно смело пропускать.</li>
    <li id="YYbK"><code>В заголовке главной страницы</code> указывает, где произошли изменения. Если, например, кто-то зайдёт на сайт и ему не понравится новый заголовок, он легко найдёт по истории (<code>git log</code>) автора этого коммита и спросит у него, почему заголовок теперь такой.</li>
  </ul>
  <p id="oiie">Пример плохого сообщения для того же коммита: <code>Исправлена опечатка</code>. Это сообщение даёт мало информации. В такой коммит придётся «заглядывать» — разбираться, что именно поменялось и зачем.</p>
  <h2 id="Zcwk">Стили оформления</h2>
  <p id="9ZNL">Все люди разные и у всех есть предпочтения — в том числе, как формулировать сообщения коммитов. Кто-то использует инфинитивы: <code>Исправить сообщение об ошибке E123</code>, кто-то — глаголы в прошедшем времени: <code>Исправил…</code>, кто-то — существительные: <code>Исправление…</code>.</p>
  <p id="ttJy">Без единообразия коммитов нет и эффективной работы в Git. Это может показаться мелочью, но когда коммиты с сообщениями в разных стилях идут друг за другом, их может быть сложно читать.</p>
  <p id="inAO">Чтобы упростить работу, команды или даже целые компании часто договариваются об определённом стиле (то есть о правилах) оформления сообщений коммитов.</p>
  <p id="eaxS">Например, правила могут быть такие:</p>
  <ul id="mNDS">
    <li id="uN5X">длина сообщения от 3030 до 7272 символов;</li>
    <li id="fhoo">первое слово — глагол в инфинитиве («исправить», «дополнить», «добавить» и другие);</li>
    <li id="FDYQ">и так далее.</li>
  </ul>
  <p id="dg3S">Есть много подходов к оформлению сообщений коммитов, но мы расскажем о нескольких популярных. Их используют как отдельные команды, так и целые проекты.</p>
  <h3 id="rhpo">Корпоративный</h3>
  <p id="3Tkh">Во многих компаниях применяется Jira — система для организации проектов и задач. У каждой задачи в Jira есть идентификатор из нескольких заглавных латинских букв и номера. Например, <code>LGS-239</code> значит, что это 239239-я задача в проекте <strong>LGS</strong> (сокращение от англ. <em><strong>l</strong>o<strong>g</strong>istic<strong>s</strong></em> — «логистика»).</p>
  <p id="TnU4">В корпоративном стиле в начале сообщения обычно указывают Jira-ID, а после — текст сообщения.</p>
  <pre id="89QK">$ git commit -m &quot;LGS-239: Дополнить список пасхалок новыми числами&quot;</pre>
  <p id="msad">Какие-то команды могут договариваться, с какой части речи начинать сообщение и какой длины оно должно быть, какие-то — нет. Но требование о наличии Jira-ID обычно строгое: оно позволяет автоматически связывать коммиты с задачами и проектами.</p>
  <h3 id="ZoWY">Conventional Commits</h3>
  <p id="BNwH">Стандарт <strong>Conventional Commits</strong> (англ. «соглашение о коммитах») отличается качественной документацией и подробной проработкой. Он подходит для репозиториев с исходным кодом программ. Использовать его для других типов проектов (например, для перевода книги) было бы неудобно.Conventional Commits предлагает такой формат коммита: <code>&lt;type&gt;: &lt;сообщение&gt;</code>. Первая часть <code>type</code> — это тип изменений. Таких типов достаточно много. Вот два примера:</p>
  <ul id="MkFT">
    <li id="KLfr"><code>feat</code> (сокращение от англ. <em>feature</em>) — для новой функциональности;</li>
    <li id="ljKc"><code>fix</code> (от англ. «исправить», «устранить») — для исправленных ошибок.</li>
  </ul>
  <p id="OMEQ">Более подробный список можно увидеть <a href="https://www.conventionalcommits.org/ru/v1.0.0-beta.4/#%D1%81%D0%BF%D0%B5%D1%86%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F" target="_blank">на сайте с описанием этого стиля</a>.</p>
  <p id="YM68">Например, сообщение может быть таким.</p>
  <pre id="V9yN">git commit -m &quot;feat: добавить подсчёт суммы заказов за неделю&quot;</pre>
  <h3 id="mUbh">GitHub-стиль</h3>
  <p id="xVUG">GitHub можно использовать не только для хранения файлов проекта, но и для ведения списка <strong>задач</strong> (англ. <em>issue</em>) этого проекта. Если коммит «закрывает» или «решает» какую-то задачу, то в его сообщении удобно указывать ссылку на неё. Для этого в любом месте сообщения нужно указать <code>#&lt;номер задачи&gt;</code>. Например, вот так.</p>
  <pre id="CQCe">$ git commit -m &quot;Исправить #334, добавить график температуры&quot; </pre>
  <p id="gtG9">В таком случае GitHub свяжет коммит и задачу.</p>
  <h2 id="Fgmt">Как исправить коммит</h2>
  <p id="biSo">Иногда в только что выполненном коммите нужно что-то поменять: например, добавить ещё пару файлов или заменить сообщение на более информативное.</p>
  <p id="AGWG">В таком случае можно внести правки в уже сделанный коммит с помощью опции <code>--amend</code> (от англ. <em>amend —</em> «исправить», «дополнить») у команды <code>commit</code>: <code>git commit --amend</code>. Разберём, как она работает.</p>
  <blockquote id="v2cD">💡 Важно: опция <code>--amend</code> работает только с последним коммитом (<code>HEAD</code>). Для исправления более ранних коммитов есть другие команды. Мы рассмотрим их в следующих модулях курса.</blockquote>
  <h3 id="28pY">Подготавливаем репозиторий</h3>
  <p id="qF7r">Создайте тренировочный репозиторий для отработки команды.</p>
  <pre id="bSxN">$ mkdir ~/dev/commit-amend-fun
$ cd ~/dev/commit-amend-fun
$ git init
# пропустим вывод git init </pre>
  <h3 id="p7bk">Дополнить коммит новыми файлами — <code>git commit --amend --no-edit</code></h3>
  <p id="4KpG">Представьте, что делаете небольшой сайт и для этого создали файл-страницу <code>main.html</code>, а также файл со стилями <code>common.css</code>.</p>
  <pre id="a9Hg">$ touch main.html 
$ touch common.css 
# дальше отредактировали оба файла</pre>
  <p id="08wQ">В какой-то момент вы забыли о файле <code>common.css</code> и добавили в коммит только <code>main.html</code>.</p>
  <pre id="BIRH">$ git add main.html 
$ git commit -m &quot;Добавить главную страницу&quot; 
$ git log --oneline 
777fec3 Добавить главную страницу</pre>
  <p id="LVJG">Файл <code>common.css</code> так и остался «висеть» в <code>untracked</code>. В этом легко убедиться, если вызвать <code>git status</code>.</p>
  <figure id="Khwy" class="m_original">
    <img src="https://img4.teletype.in/files/3f/3a/3f3a5aaa-4797-48a8-ae21-038e8bc20a28.png" width="652" />
  </figure>
  <p id="OeLG">Дополните последний коммит забытым файлом <code>common.css</code> с помощью опции <code>--amend</code>.</p>
  <pre id="xOfb">$ git add common.css 
# добавили файл common.css в список на коммит как обычно 

# но вместо команды commit -m &#x27;...&#x27; 
# будет: 
$ git commit --amend --no-edit 

$ git log --oneline 
8340eb2 Добавить главную страницу 
# коммит в истории всё ещё один (но у него новый хеш)</pre>
  <figure id="4B7U" class="m_column">
    <img src="https://img4.teletype.in/files/31/f4/31f4c652-7fe4-4b35-a2a5-70009bdbda32.png" width="819" />
  </figure>
  <p id="9fWy">С опцией <code>--amend</code> команда <code>commit</code> не создаст новый коммит, а дополнит последний, просто добавив в него файл <code>common.css</code>. При этом хеш последнего коммита изменится, потому что изменился список файлов в коммите.Обратите внимание на опцию <code>--no-edit</code>. Она сообщает команде <code>commit</code>, что сообщение коммита нужно оставить как было.</p>
  <p id="w3MD">Точно так же можно добавить не новый файл, а дополнительные изменения в уже добавленном в коммит файле.</p>
  <pre id="LD39"># ещё раз отредактировали main.html

$ git add main.html # добавили в список на коммит
$ git commit --amend --no-edit </pre>
  <blockquote id="ONaX">💡 <strong>Что же выбрать: новый коммит или <code>--amend</code>?</strong> <br />В нашем примере вместо изменения последнего коммита можно было также выполнить новый коммит с одним файлом <code>common.css</code>. Кажется, что так проще, но добавить изменения в уже существующий коммит может быть правильнее.<br />Например, через месяц кто-то захочет просмотреть историю изменений. Намного проще понять, что изменилось, если оба файла находятся в одном коммите. Иначе коммит со второй порцией изменений придётся искать.</blockquote>
  <h3 id="Arqp">Изменить сообщение коммита — <code>git commit --amend -m &quot;Новое сообщение&quot;</code></h3>
  <p id="MkYz">Может быть и так, что добавлять новые файлы в коммит не нужно, зато понадобилось изменить сообщение.</p>
  <p id="jToR">Допустим, хочется заменить сообщение <code>Добавить главную страницу</code> на <code>Добавить главную страницу и стили</code>. Сделать это можно через <code>commit --amend</code> с флагом <code>-m</code>.</p>
  <pre id="jSOX">$ git commit --amend -m &quot;Добавить главную страницу и стили&quot;
$ git log --oneline
a31fa24 Добавить главную страницу и стили </pre>
  <figure id="Tl0O" class="m_original">
    <img src="https://img4.teletype.in/files/77/26/7726cc23-ed0c-4241-85c5-57bbfa861cd0.png" width="635" />
  </figure>
  <p id="wOD3">Хеш коммита снова поменялся, потому что изменились сообщение и время коммита. При этом файлы в коммите остались те же: <code>main.html</code> и <code>common.css</code>.</p>
  <h2 id="na8h">Как откатиться назад, если «всё сломалось»</h2>
  <p id="iXJ7">На разных этапах работы с Git могут происходить похожие ситуации:</p>
  <ul id="9Dgw">
    <li id="nFb5">В список на коммит попал лишний файл (например, временный). Нужно «вынуть» его из списка.</li>
    <li id="U8uP">Последние несколько коммитов ошибочные: например, сделали не то, что было нужно, или нарушили логику. Хочется «откатить» сразу несколько коммитов, вернуть «как было вчера».</li>
    <li id="0Fhi">Случайно изменился файл, который вообще не должен был меняться. Например, вы открыли не тот файл в редакторе и начали его исправлять.</li>
  </ul>
  <p id="8WPw">В этом уроке рассмотрим такие случаи и научим вас «откатывать» нежелательные изменения.</p>
  <h3 id="YMem">Выполнить unstage изменений — <code>git restore --staged &lt;file&gt;</code></h3>
  <p id="nT6B">Допустим, вы создали или изменили какой-то файл и добавили его в список «на коммит» (staging area) с помощью <code>git add</code>, но потом передумали включать его туда. Убрать файл из staging поможет команда <code>git restore --staged &lt;file&gt;</code> (от англ. <em>restore</em> — «восстановить»).</p>
  <p id="nzAf">В терминале это будет выглядеть примерно так.</p>
  <pre id="vu6S">$ touch example.txt # создали ненужный файл
$ git add example.txt # добавили его в staged

$ git status # проверили статус
Changes to be committed:
  (use &quot;git restore --staged &lt;file&gt;...&quot; to unstage)
        new file:   example.txt

$ git restore --staged example.txt
$ git status # проверили статус

Untracked files:
  (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)
        example.txt

no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)
# файл example.txt из staged вернулся обратно в untracked </pre>
  <figure id="ZQTo" class="m_column">
    <img src="https://img1.teletype.in/files/85/24/8524fab6-a441-41ec-9d90-9e7ff8482c61.png" width="647" />
  </figure>
  <p id="RD57">Вызов <code>git restore --staged example.txt</code> перевёл <code>example.txt</code> из <code>staged</code> обратно в <code>untracked</code>.</p>
  <p id="v2rK">Чтобы «сбросить» все файлы из <code>staged</code> обратно в <code>untracked</code>/<code>modified</code>, можно воспользоваться командой <code>git restore --staged .</code>: она сбросит всю текущую папку (<code>.</code>).</p>
  <h3 id="uX7S">«Откатить» коммит — <code>git reset --hard &lt;commit hash&gt;</code></h3>
  <p id="BiD0">Иногда нужно «откатить» то, что уже было закоммичено, то есть вернуть состояние репозитория к более раннему. Для этого используют команду <code>git reset --hard &lt;commit hash&gt;</code> (от англ. <em>reset</em> — «сброс», «обнуление» и <em>hard</em> — «суровый»).</p>
  <pre id="fndm">$ git log --oneline # хеш можно найти в истории
7b972f5 (HEAD -&gt; master) style: добавить комментарии, расставить отступы
b576d89 feat: добавить массив Expenses и цикл для добавления трат # вот сюда и вернёмся
4b58962 refactor: разделить analyzeExpenses() на countSum() и saveExpenses()

$ git reset --hard b576d89
# теперь мы на этом коммите
HEAD is now at b576d89 feat: добавить массив Expenses и цикл для добавления трат </pre>
  <p id="uiCZ">Теперь коммит <code>b576d89</code> стал последним: вся дальнейшая разработка будет вестись от него. Файл также вернулся к тому состоянию, в котором был в момент этого коммита. А коммит <code>7b972f5</code> Git просто удалил. Это можно проверить, снова запросив лог. Он покажет следующее.</p>
  <pre id="U7j2">$ git log --oneline
b576d89 (HEAD -&gt; master) feat: добавить массив Expenses и цикл для добавления трат
4b58962 refactor: разделить analyzeExpenses() на countSum() и saveExpenses() </pre>
  <p id="rWGP">Вот так схематично выглядит весь процесс «отката» с помощью <code>git reset --hard &lt;hash&gt;</code>.</p>
  <figure id="kg4j" class="m_column">
    <img src="https://img1.teletype.in/files/03/ca/03ca3933-c9bb-4714-9c93-114fedc81d5d.png" width="2902" />
  </figure>
  <h3 id="6KTO">«Откатить» изменения, которые не попали ни в staging, ни в коммит, — <code>git restore &lt;file&gt;</code></h3>
  <p id="As7z">Может быть так, что вы случайно изменили файл, который не планировали. Теперь он отображается в <code>Changes not staged for commit</code> (<code>modified</code>). Чтобы вернуть всё «как было», можно выполнить команду <code>git restore &lt;file&gt;</code>.</p>
  <pre id="xMV4"># случайно изменили файл example.txt
$ git status
On branch main
Changes not staged for commit:
  (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)
  (use &quot;git restore &lt;file&gt;...&quot; to discard changes in working directory)
          modified:   example.txt

$ git restore example.txt
$ git status
On branch main
nothing to commit, working tree clean </pre>
  <p id="uAR7">Изменения в файле «откатятся» до последней версии, которая была сохранена через <code>git commit</code> или <code>git add</code>.</p>
  <p id="ZqlL">Вот о чём мы рассказали:</p>
  <ul id="fKFi">
    <li id="pbwQ">Команда <code>git restore --staged &lt;file&gt;</code> переведёт файл из <code>staged</code> обратно в <code>modified</code> или <code>untracked</code>.</li>
    <li id="dtBm">Команда <code>git reset --hard &lt;commit hash&gt;</code> «откатит» историю до коммита с хешем <code>&lt;hash&gt;</code>. Более поздние коммиты потеряются!</li>
    <li id="mm4K">Команда <code>git restore &lt;file&gt;</code> «откатит» изменения в файле до последней сохранённой (в коммите или в staging) версии.</li>
  </ul>

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