Результати пошуку
ITVDN: курси програмування
Відеокурси з
програмування
Підписка

300+ курсів за популярними IT-напрямками

Вибери свою IT спеціальність

Підписка
Підписка

300+ курсів за популярними IT-напрямками

Результати пошуку за запитом: курс - практикум по frontend разработке*
Як правильно працювати з REST API

Автор: Zell Liew

Коротко про мене Мене звати Зел, я розробник-фрілансер із Сінгапуру. У вільний від роботи час я люблю розбиратися в коді і принагідно публікувати у своєму блозі ті цікавості, які я виявив чи вивчив. Вступ Швидше за все вам уже доводилося чути про такий термін, як REST API, особливо якщо ви стикалися з необхідністю отримання даних з іншого джерела (такого як Twitter або GitHub). Але що ж все-таки це таке? Що ми можемо робити з цим і як ми можемо це використовувати? У цій статті ви дізнаєтеся все про REST API для того, щоб працювати з ними та читати пов'язану з ними документацію. Що ж таке REST API? Давайте уявимо, що ви намагаєтеся знайти фільми про Бетмена на YouTube. Ви відкриваєте сайт, вбиваєте у форму пошуку слово «Бетмен», тиснете «Окей» і бачите список фільмів про супергероя. Так само працює і WEB API. Ви шукаєте щось і отримуєте список результатів від ресурсу, до якого здійснюєте запит. Дослівно API розшифровується як Application Programming Interface. Це набір правил, що дозволяє програмам спілкуватися одна з одною. Розробник створює API на сервері та дозволяє клієнтам звертатися до нього. REST – це архітектурний підхід, що визначає, як API мають виглядати. Читається як "Representational State Transfer". Цьому набору правил і слідує розробник під час створення свого застосунку. Одне з цих правил каже, що при зверненні до певної адреси ви повинні отримувати певний набір даних (ресурс). Кожна адреса - маршрут, пакет даних - запит, у той час як результуючий ресурс – відповідь. Анатомія запиту Важливо розуміти структуру запиту: Маршрут відправки. Тип методу. Заголовки. Тіло (або дані). Маршрут – це адреса, за якою надсилається ваш запит. Його структура приблизно така: Root-endpoint - це точка прийому запиту на стороні сервера (API). Наприклад, кінцева точка GitHub - https://api.github.com. Шлях визначає ресурс, до якого здійснюється запит. Це щось на кшталт автовідповідача, який просить вас натиснути 1 для одного сервісу, 2 для іншого і так далі. Для розуміння того, які саме шляхи вам доступні, вам слід переглянути документацію. Наприклад, припустимо, ви хочете отримати список репозиторіїв для конкретного користувача на Git. Згідно з документацією, ви можете використати наступний шлях для цього: Вам слід підставити під пропуск ім'я користувача. Наприклад, щоб знайти список моїх репозиторіїв, ви можете використати маршрут: Остання частина маршруту – це параметри запиту. Технічно запити не є частиною REST-архітектури, але на практиці зараз все ґрунтується на них. Тож давайте поговоримо про них детальніше. Параметри запиту дозволяють використовувати у запиті набори пар «ключ-значення». Вони завжди починаються знаком питання. Кожна пара параметрів після чого розділяється амперсандом (щось подібне до цього): Як тільки ви намагаєтеся отримати список репозиторіїв для користувача, ви додаєте ці три опціональні параметри і після чого отримуєте наступний результат: Якщо ж ви бажаєте отримати список моїх недавно запушених репозиторіїв, вам слід ввести наступне: Отже, як же зрозуміти, що маршрути робочі? Що ж, настав час перевірити їх на практиці! Тестування за допомогою Curl Ви можете надіслати запит за допомогою будь-якої мови програмування. JavaScript може використовувати методи на кшталт Fetch API або JQuery`s Ajax Method. Рубі використовує інше. І так далі. У цій статті я використовуватиму таку утилітку, як Curl. Справа в тому, що вона вказана в офіційній документації для веб-сервісів. Якщо ви зрозумієте, як використовувати цю утиліту, ви зрозумієте, як працювати з API. Після чого ви можете робити запити будь-якою зручною для вас мовою. Перед тим, як продовжити, слід переконатися, що Curl встановлений на вашій машині. Якщо ж він не встановлений, саме час встановити. У такому разі ви отримаєте помилку "command not found". Для того щоб використовувати утиліту, необхідно ввести наступне (за прикладом): І як тільки ви підтверджуєте введення, ви отримуєте відповідь (на зразок цього): Щоб отримати список користувацьких репозиторіїв, вам слід змінити запит за тим же принципом, який був обговорений раніше. Наприклад, щоб отримати список моїх репозиторіїв, вам слід ввести наступне: Якщо ж ви бажаєте включити параметри запитів, переконайтеся, що ви їх екрануєте. Справа в тому, що без екранування знаки питання і рівності розцінюються системою як спецсимволи і виконання команди відбудеться з помилкою. Також спробуйте інші команди та зробіть запити! В результаті ви отримуєте схожі відповіді. JSON JSON – JavaScript Object Notation – загальний формат для надсилання та прийому даних за допомогою REST API. Відповідь, що відправляється Github, також міститься у форматі JSON. Зміст об'єкту цього формату приблизно наступний: Повертаємось до анатомії запиту. Ви вивчили, що запит складається із чотирьох частин: Маршрут відправки. Тип методу. Заголовки. Тіло (або дані). Тепер давайте спробуємо розібратися з рештою. Тип методу Метод позначає тип запиту, який здійснюється; де-факто він є специфікацією операції, яку повинен здійснити сервер. Усього існує п'ять типів запитів: GET POST PUT PATCH DELETE GET – використовується для отримання з боку серверу певного ресурсу. Якщо ви здійснюєте цей запит, сервер шукає інформацію та відправляє її вам назад. По суті, він здійснює операцію читання на сервері. Дефолтний тип запитів. POST – необхідний для створення певного ресурсу на сервері. Сервер створює в базі даних нову сутність та сповіщує вас, чи був процес створення успішним. По суті, це операція створення. PUT та PATCH – використовуються для оновлення певної інформації на сервері. У такому разі сервер просто змінює інформацію існуючих сутностей у базі даних та повідомляє про успіх виконання операції. DELETE – як і випливає з назви, видаляє вказану сутність із бази чи сигналізує про помилку, якщо такої сутності в базі не було. Сам же API дозволяє вказати, який метод має бути використаний у певних контекстних ситуаціях. GET запит у цьому випадку необхідний, щоб одержати список всіх репозиторіїв зазначеного користувача. Також можна використовувати curl: Спробуйте надіслати цей запит. Як відповідь ви отримаєте вимогу про аутентифікацію. Заголовки Заголовки використовуються для надання інформації як клієнту, так і серверу. Взагалі, їх можна використовувати для багато чого; наприклад, та сама автентифікація та авторизація. На офіційній сторінці MDN можна знайти список доступних заголовків. Заголовки являють собою пари ключів-значень. Приклад: Також приклад із використанням curl: (Примітка: заголовок Content-Type у випадку Github для роботи не є обов'язковим. Це всього лише приклад використання заголовка в запиті, нічого більше). Для перегляду надісланих заголовком даних можна використовувати наступне: Тут зірочка відноситься до додаткової інформації, наданої за допомогою curl. > відноситься до заголовків запиту, а <, відповідно, - до заголовків відповіді. Щоб надіслати інформацію з curl, використовуйте наступне: Для відправки множинних полів ми можемо використати декілька подібних конструкцій: Також, якщо необхідно, ви можете розбити ваш запит на декілька ліній для забезпечення більшої читабельності: Якщо ви знаєте, як розгорнути сервер, ви можете створити власний API та протестувати свої запити. Якщо ж ні, обов'язково спробуйте. Існує безліч інформації, присвяченої цьому. Якщо ж бажання розгортати свій сервер немає, спробуйте безкоштовну опцію Request bin. Після чого ви отримаєте адресу, яку спокійно зможете тестувати. Переконайтеся, що ви створюєте власний request bin, якщо ви хочете протестувати саме ваш запит. Зважайте на те, що дефолтний час існування request bin – 48 годин. Тому ті приклади адрес, які я тут наводжу, на момент прочитання статті давно застаріли. Тепер спробуйте надіслати деяку інформацію, після чого оновіть свою сторінку. Якщо все пройде успішно, ви побачите наступне: За замовчуванням curl відправляє дані так, ніби вони були відправлені за допомогою полів форм. Якщо ви бажаєте надіслати дані через JSON, ваш Content-Type повинен дорівнювати application\json, внаслідок чого вам необхідно відформатувати дані у вигляді JSON-об'єкту. По суті, це все, що вам необхідно знати про структуру запиту. Тепер давайте згадаємо про аутентифікацію. Що ж це таке і навіщо вона потрібна? Аутентифікація Ви б не дозволили нікому чужому отримати доступ до вашого банківського рахунку без спеціального дозволу, чи не так? За таким же принципом розробники не дозволяють неавторизованим користувачам робити на сервері все, що їм заманеться. Оскільки POST, PUT, PATCH, DELETE запити змінюють базу даних, розробники повинні завжди бути на варті неавторизованого доступу до них. Проте іноді GET запити також вимагають аутентифікації (наприклад, коли ви хочете переглянути стан вашого банківського рахунку). У випадку з вебом існує два способи представитися системі: Через нік і пароль (базова автентифікація) Через секретний токен Секретний токен дозволяє представити вас системі через соцмережі на кшталт Github, Google, Twitter і так далі. Тут же я розгляну лише базову автентифікацію. Для виконання базової аутентифікації ви можете використовувати наступне: Спробуйте залогінитися під свій профіль за запитом, вказаним вище. Як тільки ви успішно увійдете у свій профіль, ви побачите відповідь "problems parsing JSON". Чому? Все просто: системі ви представилися, але - от біда - нічого корисного їй не надали. Усі типи запитів потребують певної інформації. Тепер же давайте поговоримо про статус-коди та можливі помилки. Статус-коди та можливі помилки Деякі з повідомлень, наведених вище, якраз і належать до кодів помилок. Логічно, що вони з'являються лише тоді, коли щось іде не зовсім так, як було заплановано. Що ж до статусу кодів, вони дозволяють вам пізнати успіх (або невдачу) під час виконання певного запиту. Бувають статус-коди від 100 до 500+. Загалом їх можна поділити на такі групи: 200+: запит успішний 300+: запит перенаправлений на інший маршрут 400+: помилка на стороні клієнта 500+: помилка на стороні сервера Ви можете відлагодити статус відповіді за допомогою –v або –verbose. Наприклад, я спробував отримати доступ до певного ресурсу без авторизації. Відповідно, я спіймав помилку: У випадку ж, коли запит невірний через помилку в самій інформації, що передається, ви отримуєте статус-код 400: Версії API Час від часу розробники оновлюють свої API. Іноді оновлення можуть бути такими сильними, що розробник бажає здійснити реліз нової версії. У такому випадку, якщо ваш застосунок ламається, це відбувається через те, що ви писали код з урахуванням старого компонента, тоді як новий дещо відрізняється в плані реалізації. Запросити поточну версію API можна двома шляхами. Через маршурт Через заголовок Наприклад Твіттер використовує перший спосіб. На момент написання версія Twitter API була 1.1. Водночас GitHub використовує інший спосіб: На закінчення У цій статті ми розглянули, що таке REST API і як його можна використовувати спільно з curl. Крім того, ви також вивчили, як залогінитись за допомогою запиту і що таке статус-код. Я щиро сподіваюся, що ця стаття дозволила вам підвищити свій рівень загальних і не дуже знань щодо такого важливого аспекту веб-розробки. Буду радий будь-яким вашим коментарям тут. Автор перекладу: Євген Лукашук Джерело Ще більше матеріалів на цю тему: ASP.NET Core Web API. Практичний курс ASP.NET WEB API 2 REST API в Node.js  JAX-RS Client API. Asynchronous REST Створення API на PHP та JavaScirpt
10 заповідей Node.js розробника

Автор: Редакция ITVDN

10 отменных советов как стать лучшим Node.JS разработчиком 2018 года от автора Азата Мардана. Эта статья содержит в себе собранный и тщательно отфильтрованный опыт писателей и спикеров технологии всего Веб-сообщества. Заметка: первоначально заголовком статьи должно было быть «Лучшие практики Node.JS от Гуру Технологии». Эта статья охватывает не «новые» и «лучшие» практики 2017-2018 года, а тщательно выверенные и проверенные временем и практикой паттерны, которые стопроцентно приведут к успеху. И хотя многие из проверенных практик Вам определенно пригодятся в 2018, 2019 и даже более поздних годах, статья не включает в себя такие новшества, как async/await и прочее. Почему? Потому что эти фичи не включены в состав, собственно говоря, кода Node.JS-ядра или кода таких популярных проектов как npm, Express и прочие. Полноценно заниматься разработкой на Node.JS я начал в 2012 году, когда присоединился к Storify. С тех пор я никогда не жалел о принятом решении и не ощущал, как будто я многое потерял, закинув Python, Ruby, Java или PHP – языки, с которыми я работал на протяжении предыдущего десятилетия. Работа в компании Storify для мня оказалась достаточно интенсивной. В отличии от большинства компаний, все приложения Storify работают исключительно на JavaScript. Как вы понимаете, большинство компаний, особенно такие крупные как PayPal, Walmart или Capital One, используют Node.JS только для конкретных определенных задач. Как правило, это gateway API. Однако, с точки зрения программиста, ничего не может быть лучше, чем работа и погружение с головой в одну определенную технологию. Краткая сводка: Избегайте нагромождения – пытайтесь разбивать свой код на столько мелких составных частей, насколько это вообще возможно. И даже больше. Используйте асинхронный подход – избегайте синхронное программирование словно чумы. Избегайте блокировки потоков – помещайте ВСЕ требуемые утверждения в начало файла, ибо они синхронные и, следовательно, будут блокировать программу. Require должен быть закеширован – считайте, это такая фича в Вашем коде. Или баг. Как Вам угодно. Всегда проверяйте свой код – ошибки – это не вышивание, которое можно выбросить в любом момент. Никогда не упускайте обнаруженные ошибки! Используйте try…catch только в синхронном потоке – try…catch бесполезен в асинхронном коде. Кроме того, v8 никогда не оптимизирует try…catch-код. Возвращайте значения или используйте if…else – просто на всякий случай: возвращайте значения что бы остановить выполнение участка кода. Обращайте внимание на события ошибок – почти все Node.JS-классы или объекты реализуют паттерн-наблюдатель и производят события-ошибки. Не стоит пропускать их. Познайте свой npm – устанавливайте модули с ключами –S или –D вместо –save или –save-dev. Используйте текущие версии в package.json – при работе с npm он по-тупому просто добавляет верхнюю скобочку по умолчанию при использовании вместе с ключом –S. Дабы избежать этого, просто вручную блокируйте версии. Никогда не доверяйте semver в своих приложениях, но доверьтесь ему в модулях с открытым исходным кодом. Бонус – используйте разные зависимости. Помещайте то, что требует проект только в процессе разработки в devDependencies. После этого используйте npm i –production. Чем больше ненужных зависимостей используется, тем больше риск возникновения уязвимостей.   Давайте разберем некоторые из этих пунктов поподробнее: Избегайте нагромождения Взгляните на некоторые модули, написанные Исааком З. Шлейтером, создателем npm. К примеру, use-strict включает «строгий» режим написания JavaScript-модульного кода. Включается эта опция всего лишь в три строчки: Но почему-же все-таки стоит избегать нагромождения кода? Одна известная фраза американского воздушного флота гласит: «все должно быть просто до идиотизма». И на это существуют свои причины. Человеческий разум не может держать в памяти больше чем от 5 до 7 вещей одновременно. Это просто как факт. Разбивая код на небольшие составные части, Вы и другие разработчики легко сможете разобраться в нем и понять, для чего он предназначен. Так же упрощается процесс тестирования. Вот пример:   Или еще: Уверен, большинство из Вас отдадут предпочтение второму примеру, когда имена переменных сразу же делают понятной их суть. Конечно, в процессе написания кода Вы можете думать, что Вы понимаете, как он работает и так. Возможно, Вам даже захочется продемонстрировать свою смекалку и сообразительность, объединив несколько методов вместе в одну строку. Пожалуйста, пишите так, как если бы Вы были более неопытны. Как если бы Вы не смотрели в код на протяжении 6 месяцев, или очень устали и, кроме того, еще и выпили. Если Вы пишете код на пике своей ментальной активности, Вам будет труднее понимать его позже, не говоря уже о Ваших коллегах, которые даже не знакомы с ходом Ваших мыслей. Держать все в относительной простоте единственно верный метод – особенно в рамках Node.JS-технологии, где используется асинхронный подход. Другими словами, преимущества от использования подхода малых частей значительно более перевешивают недостатки. Помимо прочего, они позволяют значительно быстрее исправить различные ошибки, которые могут возникнуть по разным причинам в процессе работы с Node.JS-приложением.   Используйте асинхронный подход Синхронный код мало где используется в нынешнем Node.JS. Как правило, он находит свое применение в написании CLI-команд или скриптов, не связанных с веб-приложениями. Что же касательно веб-разработки, Node.JS программисты предпочитают использовать асинхронный подход, так как это позволяет избежать блокировки потоков. К примеру, синхронный код будет приемлем, если мы строит скрипт для работы с базой данных, не системы для обработки параллельных/конкурентных задач: Но, в случае веб-приложения, лучше использовать следующее: Отличительная особенность состоит в том, пишите ли вы долго исполняемый конкурентный код или небольшой скрипт с малым временем жизни. А вообще, лучше запомните одно хорошее правило: всегда пишите асинхронный код в Node.JS.   Избегайте блокировки require S обладает простой системой загрузки модулей, которая использует общий формат CommonJS. Самый простой способ подключить модули, разбросанные по отдельным файлам – использовать встроенную функцию require. В отличии о AMD/requirejs, Node/CommonJS синхронна. По сути, функция работает согласно следующему принципу: Вы импортируете то, что было экспортировано в виде модуля или файла. О чем большинство разработчиков даже не догадывается, так это о том, что require кэшируемая. Потому, до тех пор, пока нет заметных изменений зарезервированного имени файла (и, в случае использования npm-модулей, их нет), код модуля будет выполнен и подгружен в переменную только единожды (для обработки). Подобная методика позитивно сказывается на оптимизации. Однако, даже с кэширование, лучше сначала попробуйте обойтись без require. Попробуйте использовать axios-модули. Путь /connect в свою очередь будет медленнее чем требуется, ибо импорт модулей происходит после генерации запроса: Гораздо лучше будет загрузить модули тогда, когда сервер еще даже не определен, не в маршруте: Require должен быть закэширован Хотя я и упоминал о том, что require может быть закэширован, но что так же интересно, так это то, что мы можем поместить код вне module.exports. К примеру: Зная, что некоторые участки кода могут быть запущены только один раз, подобная реализация окажется более чем полезной.   Всегда проверяйте свой код Node.JS – это Вам не Java. В Java Вы выкидываете исключения потому как в большинстве случаев Ваше Java-приложение не должно продолжать работать в случае ошибки. В Java для этого Вы просто используете try…catch. В случае Node.JS история обстоит несколько по-иному. Так как технология выполняется в асинхронном режиме, контекст ошибки всегда будет отделен от любого перехватчика (такого как try…catch) в случае возникновения самой ошибки. Этот код в Node.JS будет просто-напросто бесполезен: Но! Привычный try…catch все еще может быть использован в синхронном режиме. Вот более действенный рефакторинг предыдущего участка кода: Если мы не можем обернуть request-вызов в блок try…catch, ошибка будет не перехвачена. Однако, это легко решается при помощи callback-аргумента error. Кроме того, Вам нужно всегда вручную отлавливать error в каждом и каждом callback`е. Проверяйте наличие ошибки (и убедитесь, что она не равна null) и затем, или демонстрируйте содержание ошибки пользователю или клиенту и потому логируйте ее, или отправляйте ее обратно в место вызова при помощи error-callback`а. В качестве небольшого фокуса Вы можете использовать библиотеку okay. Применяйте ее как наведено ниже что бы обойти ручной проверки на ошибки: Возвращайте значения или используйте if…else .JS – параллельный. Эта особенность может привести к багам, если не отнестись к ней с должной осторожностью. Что бы обезопасить себя, останавливайте выполнение участка кода при помощи ключевого слова return: Избегайте бессмысленной работы (и ошибок) из-за неостановленного вовремя исполнения: Просто убедитесь, что return всегда будет стоять на страже целесообразности работы Вашего кода.   Обращайте внимание на события ошибок Почти все классы/объекты Node.JS реализую паттерн-наблюдатель, который порождает событие-ошибку. Это прекрасная возможность для разработчика отловить особо подлые ошибки и придушить их до того, как они устроят хаос. В качестве полезной привычки было бы неплохо создавать программы-прослушиватели событий-ошибок при помощи использования .on(): Познайте свой npm Многие Node.JS и front-end событийные разработчики знают, что –save (для npm install) не только установит модуль, но так же и создаст запись в package.json с упоминанием текущей версии модуля. Для аналогичных целей существует и –save-dev, опция для модулей, которые нужны только во время разработки. Но знаете ли Вы, что вместо этого можно спокойно использовать –S и –D? Теперь да. И пока Вы в режиме установки модулей, удаляйте символ ^, который будут порождать команды –S и –D. Эти значки могут быть особенно опасными, так как они позволят npm автоматически обновить модуль к последней незначительной версии (вторая цифра в семантике версирования). К примеру, с версии 6.1.0 до версии 6.2.0. Команда NPM полагается на semver, но Вы не должны. Я хочу сказать, что они используют авто обновления к промежуточным версиям модулей с открытым исходным кодом, так как они полагают, что никаких радикальных изменений в этих самых промежуточных версиях не будет. Мой вам совет: не стоит слишком в это верить. Более того, используйте npm shrinkwrap. Команда создаст новый файл с текущими версиями зависимостей зависимостей. И в заключение В этом посте мы охватили много всего: от работы с callback'ами до работы с асинхронными потоками, проверки на ошибки и снятия блокировки зависимостей. Надеюсь, Вы нашли для себя что-то новое и познавательное здесь. Немного об авторе Азат является техническим консультантом и менеджером в Capital One. JavaScript/Node.js-эксперт, автор различных онлайн-курсов. Издатель более чем 12 книг, посвященных теме, включающие такие хиты продаж как Full Stack JavaScript, React Quickly, Practical Node.JS и Pro Express.js и другие. В свое свободное время Азат читает о технике на Webapplog.com, проводит конференции и работает над продуктами с открытым исходным кодом. До того, как стать экспертом Node.JS, работал в федеральных правительственных агентствах США, принимал участие в небольших старт-апах и больших корпорациях, имея дело с такими технологиями, как Java, SQL, PHP, Ruby и прочие. Азат обожает все, что связано с технологиями и финансами, так же увлекается инновационными способами обучения и просвещения людей. Автор перевода: Евгений Лукашук Источник
Основи тестування. Як правильно скласти баг-репорт

Автор: Армен Маїлян

Навіщо потрібний гарний баг-репорт? Які якості гарного баг-репорту у розробці програмного забезпечення? Характеристики та методи для повідомлення про баг Ефективний баг-репортинг Простий шаблон баг-репорту Важливі фічі у вашому звіті про помилки Номер помилки/ідентифікатор Найменування помилки Пріоритет Платформа/Середовище Опис Кроки для відтворення помилки Очікуваний та фактичний результат Скріншот Додаткові поради для написання гарного баг-репорту Висновок Навіщо потрібний гарний баг-репорт? Баг репорт це звіт про помилки. І якщо його складено правильно, то шанси на швидке виправлення цих багів вищі. Таким чином, виправлення помилки залежить від того, наскільки якісно ви про неї повідомите. Складання звітів про помилки - не що інше, як навичка, і зараз ми розглянемо, як її сформувати. "Сенс написання звіту про проблеми (баг-репорту) полягає в тому, щоб виправити ці проблеми" - Cem Kaner. Якщо тестувальник не повідомляє про помилку правильно, програміст, швидше за все, відхиляє цю помилку, заявивши, що вона невідтворювана. Це може нашкодити робочому настрою тестувальників, зачепити їх професійну гордість, їх его. Які якості гарного баг-репорту у розробці програмного забезпечення? Будь-хто може скласти приклад баг репорту. Але не кожен може написати ефективний баг-репорт. Ви повинні вміти добре розрізняти баг-репорт середньої якості та гарний баг-репорт. Як відрізнити гарний та поганий баг-репорти? Це дуже просто – застосуйте наступні характеристики та методи, щоб якісно повідомити про помилку. Характеристики та методи включають в себе: 1) Наявність чітко визначеного номера помилки: Завжди надавайте унікальний номер кожному повідомленню про помилку. Це, у свою чергу, допоможе вам чітко ідентифікувати запис про помилку. Якщо ви використовуєте будь-який інструмент автоматичного формування баг-репортів, цей унікальний номер буде генеруватися автоматично кожного разу, коли ви робите звіт. Запишіть номер та короткий опис кожної помилки, про яку ви повідомили. 2) Відтворюваність: Якщо знайдена вами помилка невідтворювана, вона ніколи не буде виправлена. Ви повинні чітко вказати кроки для відтворення помилки. Не приймайте та не пропускайте жодного кроку відтворення. Помилку, яка описана крок за кроком, легко відтворити та виправити. 3) Будьте конкретні: Не пишіть нарис про проблему. Пишіть конкретно і по суті. Спробуйте описати виявлену проблему мінімальною кількістю слів та максимально ефективним способом. Не поєднуйте описи кількох багів в одному звіті, навіть якщо вони здаються схожими. Напишіть різні звіти для кожної проблеми. Ефективний баг-репортинг Звіти про помилки є важливим аспектом тестування програмного забезпечення. Ефективний баг-репорт добре розуміється командою розробників і дозволяє уникнути плутанини чи непорозуміння. Гарний звіт про помилку має бути чітким і коротким, без будь-яких пропущених ключових моментів. Будь-яка відсутність ясності веде до непорозуміння та уповільнює процес розробки. Опис дефектів та складання звітів – одна з найважливіших, але часто ігнорованих областей у життєвому циклі тестування. Правильно складений текст звіту про знайдений баг є дуже важливим для реєстрації помилки. Один із важливих моментів, які повинен мати на увазі тестер, - це не використовувати командний тон у звіті. Такий тон порушує моральний стан колективу та створює нездорові робочі відносини. Використовуйте нейтральний тон. Не думайте, що якщо розробник припустився помилки, то ви можете використовувати грубі слова. Перш ніж повідомляти, не менш важливо перевірити, чи був баг-репорт за цією помилкою раніше, чи ні. Дублікати помилок – це постійна проблема у циклі тестування. Перевіряйте весь список виявлених багів. Іноді розробники можуть знати про проблему і ігнорувати її в майбутньому випуску. Використовуйте спеціальні інструменти, такі як Bugzilla, який автоматично шукає дублікати помилок. Тим не менш, найкраще додатково вручну шукати дублікати помилок. Чітко вказуйте інформацію про помилку: «Як?» і «Де?". Звіт повинен ясно показувати, як було виконано тест і де саме стався дефект. Читач звіту повинен легко відтворити помилку та знайти її. Майте на увазі, що мета написання баг-репорту – дати розробнику можливість візуалізувати проблему. Він повинен чітко розуміти суть дефекту, прочитавши звіт про помилку. Не забудьте надати всю необхідну інформацію, яку розробник шукає. Крім того, майте на увазі, що звіт про помилки буде збережено для майбутнього використання і він повинен бути гарно написаний та містити необхідну інформацію. Використовуйте змістовні речення та прості слова, щоб описати знайдені помилки. Не використовуйте заплутані твердження, які витрачають час читача. Повідомляйте про кожну помилку як про окрему проблему. У разі опису кількох багів в одному звіті, ви не зможете закрити його, доки всі проблеми не будуть вирішені. Таким чином, краще за все розбити великі проблеми на окремі баги. Це гарантує, що кожна помилка може бути оброблена окремо. Добре написаний баг-репорт допомагає розробнику відтворити помилку у своєму терміналі. Це також допомагає їм правильно діагностувати проблему. Простий баг репорт шаблон Це проста форма баг-репорту. Його зміст може змінюватись в залежності від використовуваного вами інструменту для створення звітів про помилки. Якщо ви пишете баг-репорт вручну, необхідно згадати деякі поля, наприклад номер помилки, який повинен бути призначений вручну. Укладач звіту: Ваше ім'я та адреса електронної пошти. Продукт: У якому продукті ви знайшли цю помилку. Версія: Версія продукту з помилкою, якщо така є. Компонент: Основні підмодулі продукту. Платформа: Вкажіть апаратну платформу, де ви виявили цю помилку. Різні платформи, такі як "ПК", "MAC", "HP", "Sun" і т. д. Операційна система: Вкажіть усі операційні системи, у яких ви виявили помилку. Операційні системи, як-от Windows, Linux, Unix, SunOS, Mac OS. Згадайте різні версії ОС, такі як Windows NT, Windows 2000, Windows XP і т. д., якщо це можна застосувати. Пріоритет: Коли потрібно виправляти помилку? Пріоритет зазвичай встановлюється від P1 до P5. P1 слід розуміти як "виправити помилку з найвищим пріоритетом" і P5 - "виправити, якщо дозволяє час". Серйозність помилки: Визначає вплив помилки. Типи Серйозності помилки: Блокувальник (Blocker): подальша робота з тестування неможлива. Критична (Critical): збій застосунку, втрата даних. Major: серйозна втрата функціональності. Minor: незначна втрата функціональності. Незначна (Trivial): деякі поліпшення інтерфейсу користувача. Поліпшення (Enhancement): запит нової функції або деякого покращення існуючої. Статус помилки: Коли ви реєструєте помилку в будь-якій системі відстеження помилок, за замовчуванням статус помилки буде «Новий». Пізніше помилка проходить через різні етапи, такі як "Виправлено", "Перевірено", "Повторно відкрито", "Не виправлено" тощо. Призначити розробнику: Якщо ви знаєте, який розробник відповідає за той конкретний модуль, в якому виникла помилка, ви можете вказати адресу електронної пошти цього розробника. В іншому випадку залиште це поле порожнім, оскільки це надасть полю авторства помилки значення власника модуля, якщо менеджер не призначить помилку розробнику. URL: URL-адреса сторінки, на якій сталася помилка. Коротке резюме: Додайте короткий опис помилки. Орієнтуйтесь на 60 слів або менше. Переконайтеся, що складене резюме відображає проблему та місце, де вона знаходиться. Опис: Детальний опис помилки. Використовуйте такі поля для поля опису: Відтворювані кроки: чітко згадайте кроки для відтворення помилки. Очікуваний результат: як додаток має поводитися на вказаних вище етапах. Фактичний результат: який фактичний результат виконання вищезгаданих кроків, тобто поведінка помилки. Це важливі кроки у звіті про помилки. Ви також можете додати "Тип звіту" як ще одне поле, яке описуватиме тип помилки. Типи звітів включають в себе: Помилка в коді Помилка проєктування Нова пропозиція Проблема із документацією Апаратна проблема Важливі фічі у вашому звіті про помилки Розглянемо кілька складових звіту про знайдений баг. Нижче наведено важливі елементи баг-репорту: 1) Номер помилки/ідентифікатор: Номер помилки або ідентифікаційний номер (наприклад, xyz007) значно спрощує складання баг-репорту та пошук місця помилки. Розробник може легко перевірити, чи виправлено конкретну помилку, чи ні. Це робить весь процес тестування та повторного тестування більш плавним та легким. 2) Найменування помилки: Заголовок помилки читається частіше, ніж будь-яка інша частина баг-репорту. Варто вказати в ньому все про те, що входить в баг. Назва помилки має бути досить осмисленою, щоб читач міг її зрозуміти. Чіткий заголовок помилки полегшує розуміння, і читач легко зможе перевірити, чи було повідомлення про помилку раніше і чи було її виправлено. 3) Пріоритет:  В залежності від серйозності помилки для неї може бути встановлений пріоритет. Помилка може бути Blocker, Critical, Major, Minor, Trivial або пропозицією щодо покращення функціоналу. Пріоритет помилки від P1 до P5 може бути заданий так, щоб найважливіші з них переглядалися першими. 4) Платформа/Середовище:  Вказівка ​​конфігурації ОС та браузера потрібна для більшої точності в баг-репорті. Це найкращий спосіб повідомити, як можна відтворити помилку. Без точної платформи або середовища програма може поводитися по-іншому, і помилка на стороні тестувальника може не повторюватися на стороні розробника. Тому краще чітко вказати середовище, в якому було виявлено помилку. 5) Опис:  Правильний опис помилки допомагає розробнику зрозуміти помилку. Він описує проблему, що виникла. Поганий опис створить плутанину та витратить час розробників і тестерів. Необхідно чітко повідомити про ефект в описі. Завжди корисно використовувати повні речення. Рекомендується описувати кожну проблему окремо. Не використовуйте такі терміни, як «я думаю» чи «я вважаю». 6) Кроки для відтворення помилки:  Гарний звіт про помилку має чітко вказувати кроки для відтворення. Кроки повинні включати дії, які спричиняють помилку. Не робіть загальних заяв. Будьте конкретні у наступних кроках. Гарний приклад правильно написаної покрокової процедури наведено нижче: Послідовність кроків: Виберіть продукт wer05. Натисніть на «Додати до кошика». Натисніть «Видалити», щоб видалити продукт із кошика. 7) Очікуваний та фактичний результат:  Опис помилки буде неповним без зазначення очікуваних та фактичних результатів. Необхідно описати в загальних рисах, який результат тесту і що очікував користувач у разі коректної роботи програми. Читач звіту повинен знати, який результат тесту буде коректним. Чітко згадайте, що сталося під час тесту і який був результат. 8) Скріншот: Одна картинка коштує тисячі слів. Зробіть скріншот із прикладом збою з відповідними виділеннями, щоб вказати дефект. Виділіть несподівані повідомлення про помилки світло-червоним кольором. Це привертає увагу до необхідної області. Деякі додаткові поради для написання гарного баг-репорту Нижче наведено деякі додаткові поради, щоб написати гарний звіт про помилку: 1) Негайно повідомте про проблему: Якщо ви виявите будь-яку помилку під час тестування, не потрібно чекати, щоб написати докладний звіт про помилку пізніше. Натомість напишіть звіт про помилку негайно. Це забезпечить гарну якість звіту та відтворюваність кроків отримання помилок. Якщо ви вирішите написати звіт про помилку пізніше, то є великі шанси пропустити важливі деталі в баг-репорті. 2) Відтворіть помилку тричі перед написанням баг-репорту: Ваш баг має бути відтворюваним. Переконайтеся, що ваші кроки досить чіткі, щоб відтворити помилку без будь-якої двозначності. Якщо ваша помилка не відтворюється щоразу, ви все одно можете помилитися, вказавши періодичну природу багу. 3) Протестуйте цю ж помилку на інших схожих модулях:  Іноді розробник використовує один і той самий код для різних схожих модулів. Таким чином, ймовірність того, що помилка в одному модулі виникне і в інших подібних модулях, вища. Ви навіть можете спробувати знайти серйознішу версію знайденої помилки. 4) Складіть гарне резюме помилки: Короткий опис помилки допоможе розробникам швидко проаналізувати природу помилки. Низька якість звіту надмірно збільшить час розробки та тестування. Правильно взаємодійте з вашим баг-репортом. Майте на увазі, що зведення про помилки використовується як довідкова інформація для пошуку помилки в інвентарі помилок. 5) Прочитайте декілька разів звіт про помилку, перш ніж натиснути кнопку «Надіслати»:  Прочитайте всі речення, формулювання та кроки, які використовуються у баг-репорті. Подивіться, чи не створює якесь речення двозначність, яка може призвести до неправильної інтерпретації. Слід уникати слів або речень, що вводять в оману, щоб скласти чітке повідомлення про помилку. 6) Не використовуйте образливих виразів:  Приємно, що ви зробили хорошу роботу і виявили помилку, але не використовуєте це для критики розробника чи нападок на будь-яку людину. Висновок Що таке баги? Це недосконалості ПЗ, з якими необхідно боротися, і один із головних помічників у цьому – репорти про помилки. Ми розглянули деякі особливості складання звіту про знайдений баг. Немає сумнівів, що ваш баг-репорт повинен бути якісним документом. Зосередьтеся на написанні гарних звітів про помилки і витратьте деякий час на виконання цього завдання, оскільки саме якісний баг-репорт є основною точкою зв'язку між тестером, розробником та менеджером. Менеджери зі свого боку повинні пояснити своїй команді, що складання гарного звіту про помилки є основним обов'язком будь-якого тестувальника. Ваші зусилля щодо написання гарного звіту про помилки не тільки збережуть ресурси компанії, але й створять гарні стосунки між вами та розробниками. Для кращої продуктивності команди намагайтеся написати якомога гарний звіт про помилки. З нашого боку для якісної підготовки тестувальників пропонуємо вам ознайомитися з курсом підготовки спеціаліста-тестувальника на ITVDN - Quality Assurance. За матеріалами статті.
Junior Java Developer – питання на співбесіді

Автор: Армен Маїлян

В этой статье мы рассмотрим 25 наиболее часто встречающихся вопросов на интервью для новичков в программировании на Java. Все это реальные вопросы на собеседовании Java Junior Developer.   Можно ли в Java переопределить статический метод? Нет, статический метод в Java мы не можем переопределить. Мы можем только скрыть его. В Java статические методы - это те методы, которые можно вызывать без создания экземпляра класса. С другой стороны, если подкласс имеет ту же сигнатуру метода, что и базовый класс - это будет переопределением метода. Статический метод в Java не может быть переопределен по таким причинам: Статические методы - это те, которые принадлежат непосредственно классу. Они не принадлежат объекту, и при переопределении объект решает, какой метод должен быть вызван. Переопределение метода происходит динамически (во время выполнения), это означает, что определение того, какая версия метода будет использоваться происходит во время выполнения в соответствии с объектом, используемым для вызова, в то время как статические методы ищутся статически (во время компиляции). Когда вы запустите программу выше, вы получите следующий результат: Hello...Good morning Hello...Good morning Hello...everyone Согласно правилам переопределения методов, вызов метода разрешается во время выполнения по типу object. Таким образом, в нашем примере выше d.hello (), во втором вызове, должен вызывать метод hello () класса DisplayMessage, поскольку ссылочная переменная класса Display ссылается на объект DisplayMessage, но вызывает hello () самого класса Display. Это происходит потому, что выполнение статического метода разрешается во время компиляции. Таким образом, если статический метод у производного класса имеет ту же сигнатуру, что и статический метод базового класса, это будет называться сокрытием метода, а не переопределением метода. Можно ли выполнить перегрузку метода main() в Java? Достаточно распространенный по языку Java вопрос на интервью. Да, вы можете перегрузить метод main() в Java. В Java можно выполнить перегрузку метода main(), но когда мы запустим нашу программу, JVM будет искать общедоступный статический void main (String [] args) и выполнит этот метод. Перегрузка метода main() в Java: Когда вы запустите программу выше, вы получите такой результат: Inside main(String[] args) Видно, что метод main() у нас перегружен, но все же JVM вызывает метод с подписью public static void main (String [] args). Обратите внимание, что JVM считает var args public static void main (String... args) таким же, как public static void main (String [] args). Если мы хотим вызвать именно перегруженный метод, то вам нужно вызвать его из метода main с сигнатурой public static void main (String [] args). Например: Когда вы запустите программу выше, вы получите такой результат: Inside main(String[] args) Inside main(Integer args) Inside main(Integer arr) Как видите, мы вызвали перегруженные методы из main() с помощью аргумента String []. Можем ли мы в Java переопределить приватные методы? В Java мы не можем переопределить private методы, так как они видны только классу-владельцу. Каков базовый класс для всех классов в Java? java.lang.Object - это базовый класс для всех объектов. Можете ли вы перечислить некоторые важные методы из класса object? Среди важных методов класса object выделяют: hashcode - в качестве возвращаемого значения имеет хеш-значение объекта; equals - сравнивает ссылки на объекты; wait -  текущий поток ожидает, пока не будет вызвано notify или notifyAll; notify - пробуждает один поток, который ожидает блокировки; notifyAll - пробуждает все потоки, ожидающие блокировки; toString - обеспечивает представление объекта в виде строкового значения; clone - этот метод применяется для клонирования объекта; finalize - этот метод вызывается, когда объект подвергается обработке сборщиком мусора. Какие два метода вам нужно переопределить при помещении пользовательского объекта в качестве ключа для HashMap? Вам нужно будет переопределить методы hashcode() и equals() в пользовательском классе, помещая объекты пользовательского класса в HashMap.   В чем отличия в Java между HashMap и HashSet? HashMap В HashMap реализован интерфейс Map, который выполняет сопоставление некого ключа со значением. Он не синхронизирован и не является потокобезопасным. Не допускаются дублирующиеся ключи, а также null ключи и null значения. HashSet В HashSet реализован интерфейс Set, не допускающий дублирования значений. Он не синхронизирован и не является потокобезопасным. Выше employeeSet будет иметь 2 элемента, так как Set не допускает повторяющихся значений. Метод add применяется для добавления элементов в HashSet. Если этот метод возвращает true, тогда элемент добавляется успешно, но, если возвращается false – это значит, что вы пытаетесь вставить дублирующее значение. public boolean add(Object o) Одна из главных особенностей HashSet - объекты, которые мы собираемся добавить в HashSet, должны реализовывать методы Hashcode() и equals(), чтобы мы могли проверять наличие дублирующихся значений. Если мы добавляем пользовательские объекты в HashSet, то мы должны переопределить методы Hashcode() и equals() в соответствии с нашими потребностями. Если HashMap и HashSet не будут переопределены, объект будет принимать реализацию по умолчанию, что может быть нежелательно. HashMap vs HashSet:   Можем ли мы иметь абстрактный класс без какого-либо абстрактного метода в нем? Да, вы можете иметь абстрактный класс без создания какого-либо абстрактного метода.   Что вы знаете о переменной с модификатором transient? Когда вы будете ее использовать? Переменные с модификатором transient (нерезидент) применяются при сериализации. Если вы не хотите делать сериализуемую переменную, вы можете сделать ее переменной с модификатором transient. Transient переменная - это переменная, значение которой не будет сериализоваться во время сериализации объекта. А при десериализации - вы получите значение по умолчанию для этих переменных. Допустим, у вас есть класс Country, и вы не хотите сериализовать атрибут населения, поскольку он будет меняться со временем, поэтому вы можете объявить атрибут населения как transient, и он больше не будет сериализован.   Можете ли вы вызвать метод start() дважды в Java? Нет, вы не можете вызвать метод start() дважды. Это вызовет llegalStateException. После того как поток был запущен, он не может быть запущен снова. Если вы попытаетесь снова запустить поток, он выдаст исключение IllegalThreadStateException Давайте разберемся с помощью примера: Когда вы запустите программу выше, вы получите такой результат: Thread is runningException in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:705) at org.arpit.java2blog.StartThreadAgainMain.main(StartThreadAgainMain.java:16) Как вы можете видеть, когда мы пытались запустить поток во второй раз, он вызывал исключение IllegalThreadStateException. Если вы попытаетесь снова запустить поток, он выдаст исключение IllegalThreadStateException   Почему String неизменяемый (immutable) в Java? В Java класс String неизменяемый. Если вы возьмете словарное значение слова «immutable», это означает, что он не может быть изменен с течением времени, соответственно строка не может быть изменена в Java. Давайте разберемся с примером. Как видите, значение str1 не изменилось. Она создала другой объект String со значением «Hellojava2blog», но не изменил String str1. Это объясняет, что String является неизменяемым по своей природе. Теперь давайте разберемся, каковы потенциальные причины сделать String неизменной в Java. Пул строк: Если вы просто присваиваете значение String, используя двойные кавычки, это значение сохраняется в области, называемой строковым пулом, и на одну строку могут ссылаться многие ссылочные переменные. Если бы String оказался изменяемым, то это повлияло бы на все ссылающиеся на нее переменные. Потокобезопасность: Неизменяемые объекты по умолчанию являются потокобезопасными, поэтому вам не нужно устанавливать для них синхронизацию, и экземпляр String можно безопасно разделить между несколькими потоками. Безопасность: Если бы String был изменяемым, это могло бы привести к множественным проблемам безопасности. Например, при подключении к базе данных вы предоставляете имя пользователя, пароль, порт и имя хоста и т. д. в виде строки. Если бы строка - была изменяемая, то любой хакер мог бы изменить ссылочное значение, что было бы угрозой безопасности для приложения. Хэш-значение кэша: Когда вы используете String в качестве ключа в HashMap или HashSet или любой другой коллекции, вы можете кэшировать ее хеш-значение. Поскольку String является неизменяемым по своей природе, вам не нужно пересчитывать хэш каждый раз, поскольку он будет постоянным. Это значительно повышает производительность для этой коллекции на основе хеша. Загрузка классов: Строка используется в механизме загрузки классов. Она передается в качестве параметра. Если бы строка оказалась изменяемой, это вызвало бы прямую угрозу безопасности, поскольку любой хакер мог бы ее изменить.   Знаете ли вы, как сделать класс неизменным (immutable)? Можете ли вы предоставить шаги для этого? Неизменяемый класс - это класс, состояние которого нельзя изменить после создания. Пример: String - лучший пример неизменяемого класса. Создав строку, вы не сможете ее изменить. Неизменяемый класс очень прост для понимания, он имеет только одно состояние. Неизменяемые классы являются потокобезопасными. Это самое большое преимущество неизменяемого класса, потому что, - вам не нужно применять синхронизацию для неизменяемых объектов. Также, неизменяемый класс может быть полезен при помещении объекта неизменяемого класса в HashMap или может использоваться для целей кэширования, поскольку его значение не изменится. Неизменяемые объекты по умолчанию являются потокобезопасными. Шаги для создания неизменяемого класса: Финализируйте свой класс: Если вы финализируете свой класс - ни один класс не сможет его расширить, следовательно, не сможет переопределить методы этого класса. Пометьте все переменные класса модификаторами доступа private и final: Если вы сделаете переменную экземпляра private - ни один внешний класс не сможет получить доступ к переменным экземпляра, и, если вы сделаете их final - вы не сможете их изменить. Скажите «нет» методам-мутаторам: Не создавайте метод set для некоторых переменных класса, тогда не будет возможности явно изменить состояние переменных экземпляра. Выполните клонирование изменяемых объектов при возврате из метода получения: Если вы вернете клон объекта из метода get, то вернется объект. При этом, ваш оригинальный объект останется без изменений.   Можем ли мы иметь статический метод в интерфейсе? Да, у нас может быть статический метод в интерфейсе из Java 8.   Можете ли вы объявить конструктор финальным (final)? Нет, вы не можете объявить конструктор финальным.     В чем разница между StringBuffer и StringBuilder? Что такое Java ClassPath? ClassPath - это переменная окружения, которую виртуальная машина Java (JVM) использует для определения местоположения всех классов, используемых программой. Например: jre / lib / rt.jar имеет все классы Java, и вам также необходимо включить файлы jar или файл классов, которые используются программой.   У вас есть список пользовательских объектов? Как вы можете их отсортировать? Вам необходимо использовать интерфейс Comparable или Comparator для сортировки списка пользовательских объектов.   Что такое модификатор volatile в Java? Если вы пометите любую переменную как volatile, эта переменная будет считываться из основной памяти, а не из кэша  центрального процессора, поэтому каждый поток будет иметь обновленное значение в переменной.   Назовите два разных способа вызвать сборщик мусора? System.gc() или Runtime.getRuntime().gc().   Что такое маркерный интерфейс в Java? Можете ли вы привести несколько примеров маркерного интерфейса? Маркерные интерфейсы - это те интерфейсы, которые не содержат в себе никаких методов и полей. Примерами интерфейсов маркеров являются: Serializable, Cloneable, Remote.   Сколько объектов будет создано ниже: String str1= new String("John"); String str2= new String("John");   Здесь будут созданы три объекта, два в динамической памяти и один в постоянном пуле String.   Можете ли вы провести различие между проверяемым исключением (Checked Exception) и непроверяемым исключением (Unchecked Exceptions)? Что такое исключение? Исключением является нежелательная ситуация или условие при выполнении программы. И если вы неправильно обрабатываете исключение, то это может привести к аварийному завершению программы. Что такое проверяемое исключение? Проверяемые исключения - это те исключения, которые проверяются при компиляции. Если вы не обработаете их, вы получите ошибку компиляции. Используя блок try и catch вы можете поместить код ошибки в блок try и перехватить исключение в блоке catch. Что такое непроверяемое исключение? Непроверяемые исключения - это те исключения, которые не проверяются во время компиляции. Java VM не будет «ругаться», если вы не обработаете такие исключения. Если вы выполните код выше вы получите: Exception in thread "main" java.lang.NullPointerException at org.arpit.java2blog.NullPointerExceptionExample.main(NullPointerExceptionExample.java:7)   В чем разница между ArrayList и LinkedList? Как вы решите, какой из них вам нужно использовать? Один из распространенных вопросов интервью: «В чем разница между ArrayList и LinkedList». Прежде чем мы действительно увидим различия, давайте кратко рассмотрим оба. ArrayList: ArrayList – является реализацией интерфейса List. ArrayList не синхронизирован (поэтому не является потокобезопасным). ArrayList реализован с использованием массива в качестве внутренней структуры данных. Его можно динамически изменять. LinkedList: LinkedList является реализацией интерфейса List и интерфейса Deque. LinkedList не синхронизируется. LinkedList реализован с использованием двусвязного списка в качестве внутренней структуры данных.   Свойство ArrayList LinkedList Внутренняя структура данных Использует динамический массив для хранения элементов внутри. Он использует дважды связанный список для внутреннего хранения элементов. Скорость выполнения Если нам нужно вставить или удалить элемент в ArrayList, это может занять O(n), так как он использует массив, и нам может потребоваться сместить элементы в случае вставки или удаления. Если нам нужно вставить или удалить элемент в связанном списке, это займет O(1), так как он внутренне использует двусвязный список. Поиск В ArrayList поиск выполняется быстрее, т.к. он использует массив, основанный на индексах. Сложность - O(1). Поиск в LinkedList идет медленнее, т.к. он использует двусвязанный список. Сложность равна O(n). Интерфейсы ArrayList реализует только интерфейс List, поэтому его можно использовать только как List. LinkedList реализует интерфейсы List, Deque, поэтому его можно использовать как List, Stack или Queue. Когда использовать ArrayList и LinkedList? Это на самом деле зависит от нашей потребности. Если нам требуется произвести большое количество вставок или удалений, то нам следует использовать LinkedList. Если у нас имеется мало вставок или удалений, но выполняется много поисковых операций, то тогда нам следует использовать ArrayList.   В чем разница между wait и sleep в Java? Один из распространенных вопросов на интервью Java разработчика: «В чем разница между wait и sleep в Java?». Прежде чем мы действительно увидим различия, кратко ознакомимся с обоими.     sleep vs wait:   Вы запустили три потока из основного потока. Вы должны убедиться, что основной поток завершился последним. Как вы это сделаете? Вы можете использовать Java Thread Join() для достижения этого сценария. Без использования метода Join:     Когда вы запускаете программу выше, вы получите следующий результат: Main thread ends here T2 in run method T1 in run method T3 in run method С помощью метода Join: Когда вы запустите программу выше, вы получите следующий результат: T2 in run method T3 in run method T1 in run method Main thread ends here Как видите, основной поток завершается последним в этом сценарии.     Итоги Мы с вами рассмотрели 25 распространенных вопросов на собеседовании на должность Junior Java Developer.  Конечно же, полноценная подготовка к собеседованию Java разработчика должна включать и практическую и теоретическую подготовку. Готовясь к собеседованию, имеет смысл с одной стороны подготовиться, используя различные наборы вопросов и ответов Java собеседований, а с другой стороны  - быть готовым к решению задач на собеседованиях Java. С нашей стороны, ITVDN.com предлагает комплексную программу подготовки Java разработчика, включающую в себя видео курсы по Java и сопутствующим технологиям.  Рекомендуем вам также ознакомиться с серией видео «Подготовка к собеседованию в IT компании. Вопросы и ответы. Хитрости. Трюки.»   По материалам статьи.
ТОП-7 популярних IDE для програмування на С++

Автор: Армен Маїлян

Visual Studio Qt Creator CLion Eclipse Xcode Code::Blocks NetBeans   Відмінності між IDE та текстовим редактором Рейтинг IDE для С++ за даними Standard C++ Foundation Рейтинг IDE серед користувачів Reddit Рейтинг IDE для C++ від компанії JetBrains Рейтинг найкращих середовищ розробки для C/C++ IDE від G2 Crowd Висновок У роботі будь-якого сучасного розробника програмного забезпечення є інструменти, які стали практично обов'язковими для щоденного застосування. Якщо говорити про програмування мовою C++, таким інструментом, насамперед, буде звичайно інтегроване середовище розробки або IDE (Integrated Development Environment). Звичайно, досвідчений програміст може обійтися і без використання IDE, але це істотно позначиться на таких моментах, як швидкість розробки, якість коду і, звичайно ж, зручність самого процесу написання цього коду. Сьогодні ми розглянемо ТОП-7 найкращих середовищ програмування на C++. Це найчастіше використовувані інструменти від різних компаній та спільнот.   Відмінності між IDE та текстовим редактором Для початку нагадаємо різницю між текстовим редактором, який використовується для написання програм, і повноцінною IDE. Якщо спростити, текстовий редактор – це програма, за допомогою якої розробник взаємодіє безпосередньо з кодом як з текстом. Використовуючи клавіатуру, за допомогою текстового редактора розробник вводить символи та ключові слова мови програмування, описуючи цими словами якийсь алгоритм, зрозумілий надалі комп'ютеру. Код, написаний на C++ за допомогою текстового редактора коду, потрібно буде відправити на компілювання в іншу програму – компілятор, який не входить до складу текстового редактора. Інтегроване середовище розробки, у свою чергу, є комплексом окремих інструментів розробника, який дозволяє не тільки написати код програми, але й скомпілювати цей код у готовий додаток, провести тестування цієї програми, пошук помилок, рефакторинг та інші дії. До складу сучасних IDE як окремі елементи вже входять: текстовий редактор; компілятор (або інтерпретатор – для інтерпретованих мов програмування); відлагоджувач; система управління версіями; інші інструменти. Сучасні IDE можуть суттєво розширювати свій функціонал завдяки різним плагінам. Варто зазначити, що деякі текстові редактори (наприклад Vim, Visual Studio Code, Emacs), завдяки доступним плагінам, також розширюють свій функціонал, доводячи його до практично IDEшних можливостей. Однак це все ж таки два різних інструменти розробника. Текстовий редактор призначений скоріше для внесення дрібних змін до коду окремих файлів майбутньої програми. IDE, у свою чергу, працює з програмою комплексно, розглядаючи її в цілому як проект або набір проектів, а не як окремі текстові файли з кодом. Звідси й різниця у доступних можливостях цих інструментів.   Рейтинг IDE для С++ за даними Standard C++ Foundation Ознайомимося з даними опитування, проведеного серед 3240 розробників у лютому 2018 року організацією Standard C++ Foundation (Некомерційна організація з Бйорном Страуструпом у якості одного з керівників. Метою організації є підтримка спільноти розробників програмного забезпечення C++). За даними цього опитування, розробники на C++ виділили такі засоби розробки, як найчастіше використовувані: Перше місце серед IDE у Visual Studio з 55.28% розробників, що використовують його, друге у Qt Creator – 24.41% розробників, третє місце у CLion – 14.66%, четверте місце займає Eclipse – 12.78% розробників, п'яте місце у XCode – 12.22% розробників, шосте місце у Android Studio – 5.15%, сьоме у Code::Blocks – 4.85%. Як ми бачимо, багато розробників для роботи використовують текстові редактори з різними розширеннями функцій або без них. До таких входять: Vim – 37.93% розробників, Visual Studio Code – 25.77% розробників, Emacs (технічно, це текстовий редактор з розширеннями функціоналу до IDE) – 13.55%, Sublime – 12.78%.   Рейтинг IDE серед користувачів Reddit За результатами опитування, проведеного серед 1860 учасників наприкінці лютого 2018 року у співтоваристві r/cpp на порталі reddit.com, перше місце також займає Visual Studio – 28.43%:   Серед представників IDE до числа найчастіше використовуваних також увійшли: Qt Creator – 11.64%, CLion – 8.91%, Xcode – 4.05%, Eclipse – 3.98%, Code::Blocks – 2.43%.   Рейтинг IDE для C++ від компанії JetBrains Компанія JetBrains, одна з провідних компаній-творців інструментів для розробників (зокрема творець і власник одного з провідних IDE для C++ – CLion), представила в 2018 році свою статистику інтегрованих середовищ програмування С++, які найчастіше використовуються. За даними цієї статистики, перше місце серед різних середовищ розробки для C++ також отримує Visual Studio, що використовується 32% програмістів. Наступні місця в цьому рейтингу інтегрованих середовищ розробки розподілилися таким чином: друге місце у CLion – 11%, третє місце у Xcode – 5%, четверте місце у Eclipse – 5%, п'яте у QtCreator – 4%, шосте місце у Atom – 3 %, сьоме у NetBeans – 3%. Також корисною буде статистика від тієї ж компанії JetBrains, що показує компілятори, котрі найбільш часто застосовуються в розробці:   Рейтинг найкращих середовищ розробки для C / C++ IDE від G2 Crowd Цікаві дані надає аналітична платформа G2 Crowd. Проаналізувавши частоту використання розробниками різних середовищ розробки на C/C++ та ступінь задоволеності цими інструментами, компанія представила таку інфографіку: З цієї схеми ми все ще спостерігаємо лідирування Visual Studio серед інших середовищ розробки C++. Досить нішевими продуктами виявляються CodeLite та Code::Blocks. Ми розглянули кілька відкритих рейтингів найкращих середовищ програмування C++. Використовуючи вказані дані, ми зробили свій рейтинг найкращих середовищ розробки.   1) Visual Studio Visual Studio посідає перше місце у нашому рейтингу. Це широко відоме повнофункціональне середовище розробки від компанії Microsoft, яке дозволяє працювати з такими платформами, як Windows, Інтернет, хмара та Android. Можливості IDE Visual Studio дозволяють правильно та ефективно писати код, реорганізовувати, аналізувати та виправляти проблеми з кодом. Система IntelliSense передбачає API-інтерфейси в міру їх написання і виконує автоматичне завершення для підвищення швидкості та ефективності розробки. Саме ця IDE дозволяє новачкові найлегше увійти в процес розробки. Офіційний сайт – https://visualstudio.microsoft.com/ru/ Особливості Visual Studio: Свій компілятор – MSVC. Існують версії, що працюють на macOS та Windows. Підтримує такі мови: ASP.NET, Ajax, DHTML, Visual C++, JavaScript, JScript, Visual Basic, Visual C#, Visual F#, XAML та ін. Плюси IDE Visual Studio: Безкоштовно поширюється Visual Studio Community з достатнім набором можливостей. Платні версії можуть надаватися навчальним закладам та студентам безкоштовно. Зручна система розумного автодоповнення. Велика кількість налаштувань середовища розробки під «себе» завдяки вбудованим механізмам і доступним доповненням. Мінуси IDE Visual Studio: Версії Visual Studio Professional та Visual Studio Enterprise є платними. Масштабна IDE, досить вимоглива до заліза. Ряд розробників вважають її надмірною для створення дрібних проектів. Досить невелика швидкість запуску проектів та додатків. Не працює на Linux. Платні версії з розширеним функціоналом розповсюджуються за підпискою: Professional - від 45 $ на місяць, Enterprise - від 250 $ на місяць.   2) Qt Creator Qt Creator – ще одне досить зручне і швидке інтегроване середовище розробки C++, що пропонує цікаві можливості для розробника. Ця кросплатформна IDE має сучасний редактор коду C++, вбудований зручний графічний інтерфейс, дизайнер форм, інструменти навігації та багато іншого. Серед розробників багато хто обирає його за його API та бібліотеки, оскільки вони послідовні, деталізовані, зручні та гарно документовані. Qt Creator поставляється з повним набором інструментів розробника, які призначені для одночасного створення додатків і користувацьких інтерфейсів, а потім для подальшого їх розгортання в різних мобільних ОС і настільних ПК. Часто відзначають простоту та чуйність інтерфейсу. Він включає в себе зручний редактор коду з можливістю підсвічування синтаксису і автозаповненням, можливість створення інтерфейсу користувача використовуючи перетягування, інструмент візуального відлагодження та ін. Офіційний сайт: https://www.qt.io Особливості IDE Qt Creator: Доступні версії під Linux, macOS, Windows. Підтримувані компілятори: GCC / G++; MinGW; Linux ICC; Clang; Nim; QCC; MSVC. Доступні розширення, що дозволяють працювати з такими мовами, як Python, Ruby, Java, PHP та іншими. Плюси IDE Qt Creator: Наявність безкоштовної версії. Інтелектуальна система підказок. Можливість компіляції проектів для різних систем. Мінуси IDE Qt Creator: Платна версія від 459 $ на місяць. Безкоштовна версія має низку обмежень.   3) CLion Clion – це потужне і кросплатформне IDE для C і C++ від компанії JetBrains, яке включає сучасні стандарти C++, libc++ і Boost. Це IDE добре знає коди та спрощує рутину, дозволяючи зосереджуватися на основних речах розробки. Однією з його основних можливостей є рефакторинг, який дозволяє вам перейменовувати символи, зрушувати елементи вгору або вниз за ранжуванням, змінювати сигнатуру функції, а також гарантувати, що її автоматичний рефакторинг правильно генеруватиме необхідні зміни в коді. Інтегрований відлагоджувач аналізує та вирішує проблеми за допомогою дружнього користувацького інтерфейсу IDE з GDB / LLDB в якості бекенду. Більше того, він також віддалено зв'язується з нативними процесами чи відлагодженнями. Офіційний сайт IDE Clion - https://www.jetbrains.com/clion/ Особливості IDE Clion: Лише платні версії IDE. Підтримувані мови C і C++. Доступні версії під Linux, Windows, macOS. Підтримує такі компілятори: GCC / G++; MinGW; MSVC. Плюси IDE Clion: Зручні інструменти для розробки візуальних інтерфейсів. Зручні механізми відлагодження додатків. Можливості розширення функціоналу плагінами. Інструменти пошуку помилок у коді в потоковому режимі. Мінуси IDE Clion: Відсутня безкоштовна версія цього IDE. Річна підписка від 199 $.   4) Eclipse IDE Eclipse, заснована на платформі Eclipse, є однією з провідних IDE для розробників на C++ та C. Eclipse пропонує підтримку розробки проектів та кероване середовище розробки з різними наборами інструментів. Він також підтримує різні інструменти, сортування, навігацію за гіперпосиланнями, редактор коду з функцією підсвічування синтаксису, інструменти візуального відлагодження та багато іншого. Це безкоштовне ПЗ з відкритим вихідним кодом, що працює з усіма основними ОС, включаючи Windows, Mac OS X і Linux. Eclipse може похвалитися зручним інтерфейсом. Особливості IDE Eclipse: Працює на таких ОС: Windows, macOS, Linux. Працює з такими мовами: C, C++, Java, Perl, PHP, Python, Ruby та інші. Працює з такими компіляторами: GCC / G++; MinGW; Cygwin. Плюси IDE Eclipse: Простота як установки, так і застосування. Зручний механізм розроблення графічних інтерфейсів. Інструмент із відкритим вихідним кодом. Розповсюджується безкоштовно. Кросплатформність. Велика кількість доступних модулів розширення – багато розробників відзначають, що можливості модулів цієї IDE значно випереджають такі в інших середовищах розробки. Мінуси IDE Eclipse: Ряд розробників відзначають незручність використання механізмів автодоповнення під час написання коду.   5) Xcode Xcode – це повноцінна IDE, що включає набір інструментів для розробки, створена компанією Apple для написання ПЗ під macOS, iOS, WatchOS і tvOS. Xcode вважається найкращою IDE для Mac, будучи створеною розробниками самої операційної системи. Офіційний сайт IDE Xcode - https://developer.apple.com/xcode/ Особливості IDE Xcode: Працює з такими мовами, як AppleScript, C, C++, Java, Objective-C. Працює лише на macOS. Використовує Apple LLVM та GCC компілятори. Плюси IDE Xcode: Зручні інструменти для створення програмного забезпечення під комплекс платформ Apple. Механізми автодоповнення коду. Зручні інструменти для роботи із графічними інтерфейсами. Мінуси IDE Xcode: На ОС Windows та Linux ця IDE не працює.   6) Code::Blocks Code::Blocks або CodeBlocks – це IDE з відкритим вихідним кодом, що розповсюджується безкоштовно. Code::Blocks написана на C++ з використанням wxWidgets в якості інструментарію GUI. Code::Blocks – це IDE, що розширюється і налаштовується, яка працює на таких платформах, як Windows, Linux і macOS. Різний функціонал може бути доданий до цієї IDE шляхом встановлення або написання плагіну. Наприклад, завдяки таким плагінам доступні функції компіляції та відлагодження. Code::Blocks підтримує додавання різних, як готових, так і користувацьких плагінів. Розробники можуть легко налаштувати цю IDE під свої потреби, і навіть легко переміщатися інтерфейсом вкладок. Спочатку IDE Code::Blocks був створений для роботи з C++, але тепер ви також можете запускати програми на C та Fortran. Офіційний сайт IDE Code::Blocks - http://www.codeblocks.org/ Особливості Code::Blocks: Підтримує роботу з такими компіляторами: MingW / GNU GCC; MSVC++; Clang; Digital Mars; Borland C 5.5; Open Watcom. Повністю написаний C++; Працює на Linux, Mac та Windows; Підтримує такі мови: C, C++, Fortran; Плюси Code::Blocks: Вбудований відлагоджувач. Кросплатформний. Підтримка паралельного збирання. Є відкритим програмним забезпеченням. Повна підтримка точок зупинки. Інтегроване інтелектуальне підсвічування синтаксису. Досить чуйна спільнота. Можливість налаштування IDE розробниками під «себе». Мінуси Code::Blocks: Ця IDE погано підходить для розробки великих проектів.   7) NetBeans NetBeans – це одне з часто використовуваних розробниками інтегроване середовище програмування C++. Спонсорований компанією Oracle, проект IDE NetBeans був переданий у 2016 році до рук фонду Apache. На сьогоднішній день NetBeans поставляється з відкритим вихідним кодом. Написане на Java, це IDE має можливість працювати на всіх системах, які підтримують Java – Windows, Linux, macOS та Solaris. NetBeans IDE виглядає як інтерфейс із функцією перетягування, спільно зі списком шаблонів проектів. Використовувати NetBeans зручно для створення додатків C/C++ як з динамічними, так і зі статичними бібліотеками. Крім того, воно надає великий набір інструментів для програмістів на C/C++. NetBeans має багато плагінів, які можуть розширити можливості програмного забезпечення. Офіційний сайт NetBeans - https://netbeans.apache.org Особливості IDE NetBeans: Знаходиться під управлінням Apache Software Foundation. Підтримує такі мови: Java, HTML, HTML 5, C, C++ та інші. Працює на Windows, Linux, macOS і Solaris. Підтримується робота з такими компіляторами: Oracle Solaris Studio; GCC/G++; CLang / LLVM; Cygwin; MinGW. Плюси IDE NetBeans: Безкоштовне розповсюдження під ліцензією вільного програмного забезпечення. Зручний інтуїтивний інструмент створення графічного інтерфейсу GUI Builder. Велика кількість розширень. Кросплатформність. Інтелектуальне автозавершення коду. Велика спільнота. Мінуси IDE NetBeans: Користувачі відзначають тривалий запуск додатку. Ряд користувачів відзначають незручність роботи з дебагером.   Висновок Існує досить багато інтегрованих середовищ розробки на C++. Для вибору IDE під розробку на C++, як і будь-якого іншого інструмента розробника, справедливий індивідуальний підхід. Відштовхуючись від поточних завдань, базової ОС, мов, необхідних плагінів, вимог команди та інших, суто індивідуальних факторів розробки, вибір вами кращого середовища програмування C++ буде різним. Ми рекомендуємо обирати середовище розробки з нашого ТОП 7. Якщо ж ви хочете конкретну пораду для початківця – під Windows спробуйте почати розробляти із Visual Studio у безкоштовній версії Community. У якості безкоштовного середовища розробки C++ під Linux спробуйте Code::Blocks і NetBeans. Згадуючи вибір найкращого платного середовища розробки C++ для Linux і macOS, ми рекомендуємо спробувати тріальну версію платної IDE – CLion. У будь-якому випадку, якщо ви плануєте розробляти на C++ протягом тривалого часу, вибір головного інструменту навряд чи буде для вас остаточним. Пробуйте різні варіанти та стежте за нововведеннями і змінами. Розробникам-початківцям на C++ ми рекомендуємо ознайомитися з відео курсами ITVDN: C++ для початківців. C++ Essential. C++ Advanced.
Тренди веб-розробки на 2019 рік

Автор: Софія Меренич

Готовы ли вы к внедрению инноваций в ваши веб-приложения в 2019 году? Представляем вам последние тренды веб-разработки, которым, безусловно, стоит следовать! Стандарты веб-разработки часто меняются быстрее, чем их успевают внедрять. Чтобы всегда быть на шаг впереди, важно сосредоточиться на тенденциях, методах и подходах, которые только набирают популярность. Мы проанализировали тренды в разных отраслях, чтобы сформировать этот окончательный список тенденций в веб-разработке на 2019 год. В качестве бонуса, вам также представлен топ лучших стеков веб-технологий, достойных вашего внимания в следующем году. Не будем тратить время на долгие вступления. Все тренды здесь:   Голосовой поиск В настоящее время мы наблюдаем начало эры голосового поиска. Каждый смартфон уже оснащен цифровым голосовым помощником (Siri для iPhone, Google Assistant для телефонов на базе Android). Более того, набирают популярность умные колонки с искусственным интеллектом. В чем причина такого внимания к голосовым интерфейсам? Простота использования. Голосовое общение - это то, что нам не нужно изучать. Таким образом, дети и пожилые могут взаимодействовать с голосовыми интерфейсами без каких-либо сложностей в  обучении. Доступность. Цифровые голосовые помощники уже стали привычной функцией смартфона. Интеллектуальные колонки пока не так распространены, но цена от 50 долларов - отличная предпосылка для экспансии. К 2020 году ожидается, что 50% всех поисковых запросов будут осуществляться посредством голоса. Внедрение голосового поиска сейчас является одной из основных тенденций в e-commerce. Тем не менее, это также применимо к любому другому бизнесу в Интернете. Если вы хотите, чтобы ваше веб-приложение было найдено, оптимизируйте его для работы с голосовым поиском как можно скорее. Также мы рекомендуем рассмотреть возможность разработки собственного приложения для умных колонок. Это даст вам еще один канал для формирования лояльной аудитории и увеличения продаж.   WebAssembly   При создании веб-приложения производительность приложения обычно является компромиссом с кроссплатформенностью. Ограничения JavaScript делают тяжелые вычисления медленными, и это существенно влияет на производительность для пользователя. Именно поэтому большинство популярных игр и мощных приложений доступны только в качестве десктопного приложения. Формат WebAssembly может быть применен, чтобы изменить эту ситуацию. Этот новый формат ориентирован на нативную производительность среди веб-приложений. С помощью WebAssembly, код на любом языке программирования может быть скомпилирован в байт-код, который запускается в браузере. Код WebAssembly выполняется быстрее, чем код на JavaScript. В результате использования WebAssembly, вы сможете писать критически важные для приложения части на наиболее подходящем языке (C / C ++ / C # / Rust / Kotlin и т. Д.). WebAssembly сам позаботится о выполнении кода в браузере. Нативные приложения теперь можно запускать сразу в браузере. Это означает доступ к большему количеству пользователей, благодаря предложенной им сопоставимой с десктопной производительностью в сети без дополнительных затрат на разработку! Основная проблема с WebAssembly заключается в том, что еще не все браузеры поддерживают его. Однако скоро это изменится. Веб-приложения становятся более мощными с WebAssembly. Эту технологию определенно стоит попробовать. Машинное обучение в веб-разработке Технологии искусственного интеллекта, включая машинное обучение, уже давно влияют на наше поведение в Интернете, хотя, зачастую, это происходит незаметно для нас. Это основной момент применения машинного обучения – улучшение взаимодействия пользователя с приложением. Машинное обучение - это способность программного обеспечения повышать производительность без непосредственного участия разработчиков. По сути, программное обеспечение анализирует входящие данные, выявляет закономерности, принимает решения и улучшает свою работу. К примеру, компания Airbnb применила машинное обучение для настройки результатов поиска потенциальными гостями мест поселения. С помощью специфического алгоритма, компания хотела повысить вероятность того, что владелец жилья примет запрос от потенциального гостя. Алгоритмы машинного обучения должны были анализировать решения о принятии запросов каждого владельца. Пользуясь итогами такого анализа, компания смогла предоставить клиентам результаты поиска, которые стали полезными им с большей вероятностью. A / B-тестирование показало увеличение конверсии на 3,75%. В результате все запросы от пользователей Airbnb теперь обрабатываются в соответствии с этим алгоритмом, который повышает удовлетворенность клиентов и увеличивает доход. Отличный пример внедрения, не правда ли? Но это еще не всё! Применение естественного языка и распознавания изображений могут улучшить общие впечатления пользователя от использования сервиса. Машинное обучение позволяет компьютеру правильно интерпретировать данные и принимать обоснованные решения. Машинное обучение уже используется в веб-приложениях в различных отраслях, таких как здравоохранение, финансы, образование, сельское хозяйство и т. д. Эта технология предлагает существенные усовершенствования, которые было бы трудно достичь без технологий ИИ. Машинное обучение становится важной частью любого веб-сервиса. Важно, чтобы и вы попробовали найти применение для этой технологии в своих сервисах! Анализируйте поведение посетителей вашего веб-сайта и настраивайте под них отображаемый контент. Они никогда не узнают, что вы применяете к ним некий алгоритм, но их возросшая удовлетворенность контентом приведет к увеличению их вовлеченности и к увеличению конверсии! Машинное обучение может стать вашим секретным оружием, чтобы переиграть ваших конкурентов!   Безопасность данных Чем больше данных обрабатывает ваше веб-приложение, тем больше оно привлекает внимание киберпреступников. Они стремятся нарушить работу ваших сервисов и украсть данные ваших пользователей или внутреннюю информацию компании. Это может дорого обойтись и вам, и вашей репутации. Безопасность вашего веб-сервиса должна стать вашим главным приоритетом. Итак, чтобы сохранить пользовательские данные в 2019 году, следуйте этим советам: Никогда не пренебрегайте тестированием безопасности. Тестирование безопасности должно проводиться уже на этапе разработки, благодаря чему оно может предотвратить утечку данных. Каждое изменение в вашем веб-приложении должно быть явно протестировано. Используйте инструменты мониторинга сайта. Алгоритмы анализа поведенческих факторов помогут вам постоянно отслеживать все запросы, а также выявлять и квалифицировать подозрительные действия. Своевременное выявление угрозы позволит вашей команде вовремя среагировать и защитить веб-приложение от преступников. Тщательно выбирайте сторонние сервисы. Программное обеспечение SaaS (англ. software as a service — программное обеспечение как услуга, прим. переводчика) становится все более популярным, поскольку делает разработку приложений проще и быстрее. Однако вы должны убедиться, что поставщик услуг, с которым вы работаете, заслуживает доверия. Шифрование конфиденциальных данных. Даже если преступник сможет получить доступ к вашей базе данных, он не сможет извлечь какую-либо пользу из конфиденциальных данных, хранящихся там в зашифрованном виде.     Блокчейн в веб-разработке Несмотря на то, что блокчейн утратил часть доверия к себе из-за нестабильности обменных курсов криптовалют, мы должны признать - эта технология уже бесповоротно вошла в нашу жизнь. И хотя эта технология впервые была применена в сфере настольных компьютеров - блокчейн уже уверенно проникает и в WEB. Blockchain кошельки переместились с нативных настольных приложений в веб-приложения. Они идеально подходят для хранения небольших сумм криптовалют и предлагают улучшение удобства использования. Поскольку популярность веб-кошельков продолжает расти, вам следует рассмотреть и применение этой сферы технологий. Другая реализация технологии блокчейна называется dapps или децентрализованные приложения. Уникальная особенность таких приложений - хранение логики сервера и базы данных в блокчейне. В результате ни одна организация не может контролировать приложение (например, Facebook, Google и т. д.). Dapps изначально работали как настольные приложения. Но в настоящее время они тоже переходят в WEB. Во всем мире сеть стремится к децентрализации, поэтому популярность dapps, скорее всего, возрастет. Ethereum, самая популярная платформа с открытым исходным кодом для блокчейн-проектов, выпустила библиотеку JavaScript web3.js. Эта библиотека позволяет легко разрабатывать клиентов, которые взаимодействуют с блокчейном Ethereum различными способами, такими как: создание интеллектуальных контрактов, запись и чтение данных из смарт-контрактов, передача криптовалюты между двумя учетными записями и многое другое. Библиотека Web3 также доступна для других языков программирования, включая Python, Java, PHP, Swift, Scala и т. д. Таки образом создание децентрализованных приложений с удобными веб-интерфейсами становится проще. Очевидно, что пик ажиотажа вокруг технологии блокчейна уже прошел. Но это значит только, что пришло время приступить к серьезной разработке мощных решений, которые смогут использовать большинство преимуществ этой технологии. Может быть, именно ваш проект станет следующим ньюсмейкером?     Прогрессивные веб-приложения (PWA) и ускоренные мобильные страницы (AMP) Google отдает приоритет тем веб-приложениям, которые быстро загружаются на мобильных устройствах. Именно поэтому вам следует рассмотреть возможность внедрения PWA или AMP, которые являются уникальными технологиями, сокращающими время загрузки веб-страницы. Прогрессивное веб-приложение (PWA) - это веб-страница, которая воспроизводит привычный мобильный интерфейс. Это технология работает быстро, может работать как постоянно онлайн, так и с плохим подключением к интернету, и является относительно дешевой. PWA поддерживает взаимодействие, позволяя пользователям наслаждаться высококачественными возможностями приложений, даже не осознавая, что они используют их через браузер. Приложения E-commerce являются частым примером использования этой технологии. Ускоренная мобильная страница (AMP) работает только для статического контента, но загружается быстрее, чем обычный HTML. AMP пропускает все модные элементы и отображает только важную информацию - текст, изображения и т. д. Этот подход отлично подходит для блогов и новостных изданий. Нужно ли вам применять PWA или AMP, зависит от вашего конкретного случая. Тем не менее, вам следует начать рассматривать эти технологии прямо сейчас. Наряду с улучшением качества предоставляемой услуги, у вас есть шанс значительно поднять свой рейтинг в результатах поиска.     Интернет вещей Какие устройства вы в основном используете для доступа в интернет? Скорее всего, это ноутбук и смартфон. Тем не менее, сегодня подключаться к Интернету может гораздо большее количество устройств. Да, мы имеем в виду Интернет вещей или IoT, для краткости. В настоящее время многие устройства оснащаются экраном. Благодаря такой тенденции, веб-приложения, оптимизированные для отображения данных на смарт-часах, холодильниках, интеллектуальных колонках и т. д., станут более востребованными. Адаптированность к мобильным интерфейсам больше не является трендом, уже являясь обязательным элементом работы приложения. Тенденция 2019 года - адаптация веб-приложений для маленьких экранов. Motion UI Motion Design - один из главных трендов веб-дизайна будущего года. Минималистичный дизайн, в сочетании со сложными взаимодействиями, выглядит стильно и привлекает внимание пользователя. Переходы в хедере страницы, удобные подсказки, анимированные диаграммы, фоновая анимация и модульная прокрутка. Эти, и многие другие элементы, помогут вам отобразить свой уникальный стиль и завлечь пользователя, улучшая поведенческие факторы и помогая вашему веб-приложению занять более высокое место в результатах поиска.     Стэк технологий для разработки веб-приложений   Крайне важно работать с последними проверенными технологиями. Таким способом вы сможете гарантировать, что разработанное программное обеспечение соответствует требованиям рынка и остается актуальным в течение нескольких лет. А вот и самые популярные технологии 2019 года:   Технологии front-end   Ангуляр Впервые мы услышали об AngularJS в 2010 году. Уже через 6 лет, в 2016 году, фреймворк был полностью переписан и вышел под названием Angular 2. На конец 2018 года последней стабильной версией является Angular 7. Angular - это фреймворк Model-View-Controller (MVC). Три отдельных компонента позволяют писать хорошо структурированный и простой в поддержке код. Двунаправленная привязка данных удобна для простых приложений - любые изменения в модели будут немедленно внедрены в представление и наоборот. Однако если вы работаете над сложным проектом, однонаправленная привязка данных сэкономит ваше время и ресурсы. Чтобы использовать Angular максимально эффективно, вам придется использовать Typescript. Вам также следует помнить, что фреймворк работает только с обычным DOM, что создает некоторые ограничения. Стек MEAN – является одним из самых популярных. Он включает в себя: MongoDB - база данных; Express.js - веб-фреймворк; Angular – фронтэнд фреймворк; Node.js – бэкенд. Очевидным преимуществом этого стека является то, что все его компоненты используют JavaScript. В результате собрать команду разработчиков (или нанять одного разработчика full-stack JavaScript) не будет проблемой.   React.js В описанном стеке Angular часто заменяется на React - библиотеку Javascript. Стек MERN является относительно молодым, но растущая популярность React поспособствовала быстрому росту его популярности. React превосходит по своим возможностям Angular благодаря виртуальному DOM, который позволяет быстрее и проще вносить изменения. Однако, поскольку React является библиотекой, а не фреймворком, что ограничивает основные функциональные возможности, разработчикам приходится работать со сторонними сервисами. Также стоит упомянуть, что React использует JSX - модификацию JavaScript, которая обеспечивает бесшовную совместимость компонентов. Таким образом, знание JSX является предпочтительным, если вы хотите максимально использовать стек MERN и особенно React.   Vue.js Vue.js является более молодым JS фреймворком, но за последние несколько лет он продемонстрировал невероятный рост популярности. Частично это связано с тем, что это облегченное решение. По сравнению с монолитом, подобным Angular, он предлагает только базовую функциональность «из коробки». Используя сторонние сервисы, эта функциональность расширяется. В результате нет необходимости обрабатывать избыточный код, как в случае с Angular. Как вы, вероятно, догадались, Vue.js также используется вместе с MongoDB, Express.js и Node.js как часть стека MEVN.     Технологии Back-end: Как правило, сложно выбрать между пользовательской конфигурацией бэкенд разработки и backend-as-a-service. Оба варианта имеют свои плюсы и минусы, и выбор зависит от деталей проекта. Мы не будем сейчас вдаваться в подробности, так как существуют отдельные статьи, сравнивающие mBaaS и пользовательский бэкенд - ознакомьтесь с ними, чтобы узнать больше по этой теме. Здесь мы рассмотрим самые популярные решения для пользовательского бэкенда.   Node.js Node.js является важным компонентом всех вышеописанных стеков веб-разработки. Это среда выполнения приложений, которая используется для создания приложений на стороне сервера. Работа с Node.js требует знания JavaScript. По этой причине он часто используется в стеках вместе с инфраструктурой внешнего интерфейса JS.   Django Django - это веб-фреймворк Python. Он может использоваться в основном с любым фронтенд фреймворком (включая описанные выше). Он также является хорошим решением для любых типов веб-сайтов из-за множества доступных сторонних пакетов. С ростом популярности Python стоит рассмотреть Django для серверной части вашего веб-приложения.   Laravel PHP -  широко используемый язык программирования бэкенда, а Laravel - один из самых популярных PHP фреймворков. Laravel отлично работает с Vue.js. Тем не менее, Angular и React также хорошо подходят для разработки веб-приложений с Laravel.   Заключение Попытки угнаться за последними трендами могут показаться излишне сложными, так как тренды меняются очень быстро. Но почему бы не попробовать? Следуя последним тенденциям в веб-разработке, вы сможете порадовать своих пользователей контентом мирового уровня, повысить рейтинг ваших веб-приложений и открыть для своих услуг новые рынки! В течение следующих нескольких лет голосовой поиск укрепит свои позиции и заставит поставщиков услуг адаптироваться к новой реальности. Подходя к этому с умом, вы можете оказаться в числе первых компаний, которые обращаются к вашим клиентам с помощью голосового поиска. Звучит заманчиво, не правда ли? Безопасность пользовательских данных уже давно вызывает сомнения. Это проблема, которой нельзя пренебрегать, если вы хотите быть лидером рынка. Блокчейн - это технология со многими приложениями в веб-разработке, так почему бы не исследовать ее возможности на ранней стадии ее появления? Говоря в общем, каждый тренд 2019 года заслуживает вашего внимания. Некоторые из них будут актуальными в течение нескольких лет, а некоторые станут обыденностью уже через несколько месяцев. Так что не стесняйтесь начинать реализовывать их как можно скорее. Автор: София Меренич, технический и бизнес писатель. Источник
Асинхронне програмування на JavaScript

Автор: Дмитро Охріменко

План: 1. Різниця між синхронним та асинхронним кодом 2. Багатозадачність процеси й потоки, у чому різниця 3. Особливості багатозадачності в JavaScript 4. Асинхронні операції на практиці HTTP-запит як найпоширеніший кейс 5. Підходи до написання асинхронного коду: Promise    Async/Await Observable 6. Практичні поради Різниця між синхронним та асинхронним кодом Для початку давайте визначимо ці два терміни: Синхронний код - це код, який виконується послідовно, функція за функцією. Асинхронний код - код, який може виконуватися паралельно: наступна функція запускається, не чекаючи завершення попередньої. Щоб провести аналогію з реального життя, уявімо кухаря. Якщо кухар працює синхронно, то поки він не завершить приготування однієї страви, не переходить до наступної. Але це неефективно й призводить до втрати часу. Якщо ж кухар діє асинхронно, то поки м’ясо запікається в духовці, а на плиті закипає вода, він нарізає овочі. Тобто він один, але не стоїть без діла - виконує інші задачі, поки щось готується саме. Уявімо, що кухар - це процесор. А запікання м’яса в духовці - це завантаження файлу з мережі. Кухар може просто стояти й дивитись, як м’ясо готується. А може нарізати овочі, перевіряти, чи не з’явились нові замовлення, або скролити стрічку в соцмережі. Так само і з програмами: поки мережева карта завантажує файл, процесор не мусить чекати - він може малювати інтерфейс, оновлювати прогрес-бар чи виконувати обчислення у фоні. Але для цього потрібно правильно написати код - так, щоб він міг працювати асинхронно. Код який виконується синхронно ```js console.log("Початок"); console.log("Дія"); сonsole.log("Кінець"); ``` Результат: Початок Дія Кінець   Код який виконується асинхронно. і ``js console.log("Початок"); setTimeout(() => { // за допомогою setTimeout ми відкладаємо запуск коду на певний час   console.log("Дія через 2 секунди"); }, 2000); сonsole.log("Кінець"); ``` Результат: Початок Кінець Дія через 2 секунди Це не та багатозадачність, як у деяких інших мовах програмування. Тут не використовуються додаткові потоки, а все працює завдяки механізму подій. Але про це детальніше дал Багатозадачність: процеси й потоки, у чому різниця Багатозадачність в операційній системі - це можливість запускати та керувати кількома задачами одночасно. Наприклад, працювати в браузері, слухати музику, завантажувати файл і паралельно редагувати код у Visual Studio. На практиці процесор дуже швидко перемикається між усіма цими задачами, створюючи ілюзію одночасного виконання. Якщо процесор багатоядерний - деякі задачі справді можуть виконуватись паралельно. Багатозадачність тісно пов'язана з двома важливими поняттями - процесами та потоками. Процес (process) - це окремий екземпляр програми у пам'яті, який має власні ресурси: виділену область оперативної пам'яті, дескриптори файлів, змінні оточення тощо.  Потік (thread) - це одиниця виконання всередині процесу. Потоки одного процесу працюють незалежно, але мають спільний доступ до пам'яті та ресурсів процесу. Процеси дозволяють запускати різні програми одночасно - наприклад, Google Chrome, Visual Studio Code і т.д.  Потоки дають змогу виконувати кілька задач усередині однієї програми. Наприклад, у Visual Studio Code один потік відповідає за оновлення інтерфейсу, інший перевіряє помилки в коді, ще один формує підказки під час написання. Це, звісно, спрощений приклад - у реальності VS Code використовує ще й окремі процеси для розширень і мовних серверів. Операційна система керує як процесами, так і потоками. Вона розподіляє процесорний час між ними, ставить у чергу, може призупиняти виконання або відновлювати його за потреби. Давайте трохи адаптуємо наш приклад з кухарем із попереднього посту. Уявімо, що процес - це ресторан, а потік - це кухар. Ресторан має все необхідне для приготування їжі: кухонне приладдя, продукти, рецепти (це можна розглядати як пам’ять і доступ до інших ресурсів). Кухар читає рецепт і, використовуючи ресурси ресторану, готує страву - так само, як потік виконує інструкції нашої програми, використовуючи ресурси процесу. Якщо ресторан хоче готувати кілька страв одночасно, йому потрібно більше кухарів, які працюють паралельно на одній кухні. Аналогічно, якщо програма повинна виконувати кілька задач одночасно - завантажувати файли, обробляти введення, оновлювати інтерфейс - вона може використовувати кілька потоків. Коли ми створюємо програму і хочемо зробити її зручною для користувача, а також ефективною з точки зору використання ресурсів, які виділяє операційна система на процес, ми іноді починаємо використовувати потоки та прийоми багатопотокового програмування. Це велика окрема тема, і ми її зараз чіпати не будемо. Одна з причин - у JavaScript немає прямого доступу до потоків. Уточнення. Якщо ви хочете використовувати JavaScript і все ж таки працювати з потоками - у вас є Web Workers:  https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers  А якщо JavaScript виконується не в браузері (наприклад, у Node.js), тоді можна використовувати модуль `worker_threads`. Але варто розуміти, що це не частина стандарту мови, а можливість середовища виконання. Додаткові корисні ресурси по цій темі: https://www.youtube.com/@CoreDumpped - канал з короткими відео про те як працює комп'ютер. Modern Operating System by Andrew Tanenbaum - принцип побудови та роботи операційних систем (може бути викликом для новачка, але нормально як для технічної книжки) Особливості багатозадачності в JavaScript JavaScript працює в одному потоці - це означає, що в будь-який момент часу виконується лише один фрагмент коду. Увесь код, який ми пишемо, виконується у call stack: це структура, в яку потрапляють усі функції, що викликаються. Якщо одна з функцій виконується довго (наприклад, важке обчислення), усі інші задачі - включно з обробкою кліків, рендерингом чи відповідями від сервера - будуть чекати, поки call stack не звільниться. Щоб не блокувати цей єдиний потік, браузер надає асинхронні API (setTimeout, fetch, Web API). Коли ми викликаємо, скажімо, fetch(), у стек додається лише короткий виклик цієї функції. Власне мережевий запит виконується в окремому потоці, який створює браузер. Тобто, один потік виконує задачі які є у call stack, а інший потік чекає поки відповідь поверне сервер. Але асинхронна операція колись завершиться і треба механізм який віддасть нашому головному потоку результат роботи іншого потоку. Коли це стається колбек або проміс‑резолвер не додається одразу у call stack. Спершу він потрапляє до черги подій (task queue). За роботою черги стежить event loop. Його правило просте - поки стек порожній дістати першу задачу із черги і покласти у стек. Так ми досягаємо псевдобагатозадачності: основний потік виконує короткі шматки коду послідовно, а довгі операції «живуть» поза стеком. Коли довгі операції завершуються вони формують чергу задач, які треба виконати а event loop ці задачі закидає до стеку, коли call stack стає порожнім. Це максимально спрощене пояснення, і без візуалізації може здатися складним. Якщо хочете краще зрозуміти, дуже раджу подивитись відео Jake Archibald — "In The Loop" на YouTube (англійською).  https://www.youtube.com/watch?v=8aGhZQkoFbQ Або приходьте на мій курс JavaScript Поглиблений, де ми розбираємо це на практиці.  Також корисна стаття на MDN, де ці процеси описані докладніше. Асинхронні операції на практиці: HTTP-запит як найпоширеніший кейс Один з прикладів асинхронної операції - це запит на сервер через HTTP-протокол. Якщо організовувати запит через JavaScript у браузері без використання React, Angular або Vue.js, то це можна зробити за допомогою: fetch XMLHttpRequest Спеціалізована бібліотека, наприклад, Axios Ось так буде виглядати простий код написаний на fetch ```js fetch('https://jsonplaceholder.typicode.com/users')   .then(res => res.json())   .then(data => console.log(data)); ``` А так на axios (axios одразу повертає розпарсений JSON як response.data, на відміну від fetch, де потрібно викликати .json() вручну) ```js axios.get('https://jsonplaceholder.typicode.com/users')   .then(response => console.log(response.data)); ``` Якщо розглянути саме fetch то ось що відбулося під капотом: fetch створює HTTP запит вказавши HTTP метод, заголовки, тіло тощо Цей запит передається у вбудовану систему Web API - окрему від JavaScript середу, яка працює в іншому потоці. JavaScript не чекає відповіді - основний потік продовжує виконувати інший код fetch повертає Promise - об'єкт, що представляє асинхронну операцію, результат якої з’явиться пізніше Коли відповідь від сервера приходить, Web API кладе callback в чергу. Event Loop перевіряє, чи call stack порожній, і виконує цю мікрозадачу. Така поведінка дозволяє браузеру одночасно виконувати інші задачі, не чекаючи завершення запиту. Про використання асинхронного коду в JavaScript є [безкоштовний урок на YouTube](https://www.youtube.com/watch?v=cvR1EQ1R0EQ) Також більше про синтаксис Promise можна дізнатися в уроці [Асинхронний код. Promise](https://itvdn.com/ua/video/javascript-essential-ua/js-promise-ua) на ITVDN, а детальніше про варіанти організації такого коду буде написано далі. Підходи до написання асинхронного коду Складність роботи з асинхронним кодом полягає в тому, що обробка результату операції відбувається не відразу, а через певний час після її запуску. Ми ініціюємо асинхронну операцію й можемо виконувати інші завдання, але все одно маємо якось дізнатися про її завершення та обробити результат. Проблема в тому, що в цей момент програма вже виконує інші дії. Тому для обробки асинхронних операцій використовується push-модель взаємодії: отримувача даних (наш код) викликає провайдер даних - окремий механізм, який керує асинхронною операцією. По суті, розробнику потрібно відреагувати на подію завершення асинхронної операції. Для цього існує кілька підходів: callback-функція Promise async/await (синтаксичний цукор над Promise) Observables Використання функцій зворотнього виклику (callback) Почнемо з callback-функцій. Це найпростіший підхід, але він може призвести до заплутаного коду, особливо коли одна асинхронна операція запускає іншу, і так утворюється ланцюг. Уявімо, що маємо функцію downloadImage(url, callback), яка завантажує зображення асинхронно, не блокуючи основний потік. Перший параметр - це адреса зображення, яке потрібно завантажити, а другий - функція, яку буде викликано після завершення завантаження. При цьому саме зображення буде передане як параметр у callback. Приклад використання: ```js downloadImage(url1, image => document.body.append(image)) ``` На перший погляд усе просто. Але якщо потрібно завантажити кілька зображень послідовно, код стає менш зрозумілим: ```js downloadImage(url1, image => {             document.body.append(image);             downloadImage(url2, image => {                         document.body.append(image);                         downloadImage(url3, image => {                                     document.body.append(image);                         })             }) }); ``` Така вкладена структура швидко ускладнюється, особливо якщо замість одного рядка з DOM-змінами з’являється додаткова логіка. Подібний стиль називають "Pyramid of Doom", і його краще уникати. Один зі способів спростити обробку асинхронних викликів - це використання Promise. Використання Promise Promise - це об’єкт, який представляє асинхронну операцію. У перекладі з англійської promise означає «обіцянка». Можна уявити, що це обіцянка від браузера надати в майбутньому або результат операції, або помилку, пов’язану з її виконанням. Приклад використання: перепишемо попередню функцію downloadImage, щоб вона повертала Promise. ```js let promise = downloadImage(url1); promise.then(image => document.body.append(image)); ``` Тут ми все одно використовуємо callback-функцію, але передаємо її вже в метод .then() об’єкта promise. Це важливий момент: тепер асинхронна операція має об’єктне представлення, яке можна передавати як параметр у різні частини коду; можна будувати ланцюжки промісів, позбуваючись вкладеності, яка виникала з callback. Приклад: ```js downloadImage(url1)                          // отримуємо проміс .then(image => {                             // вказуємо що робити коли promise перейде в стан resolved             document.body.append(image);             return downloadImage(url2);                // виконуємо метод, який повертає promise }) .then(image => {                             // результат роботи попереднього промісу передається як значення             document.body.append(image);             return downloadImage(url3); }) .then(image => {             document.body.append(image); }); ``` Тепер код виглядає лінійним і набагато зручнішим для супроводу. У прикладах вище ми не розглядали, як саме створюється Promise, адже важливо зрозуміти мотивацію використання цих об’єктів. Тим більше, що більшість API браузера вже повертають готові проміси. Наприклад: ```js fetch('<https://jsonplaceholder.typicode.com/users>')   .then(res => res.json()); ``` Якщо хочете детальніше розібратися зі створенням Promise вручну - перегляньте документацію на MDN або мій відео урок на ITVDN. Async/await Супроводжувати синхронний код завжди простіше, ніж асинхронний. У 2012 році в мові C# з’явився синтаксичний цукор, який значно спростив роботу з асинхронними операціями: замість вкладених callback можна було використовувати послідовний синтаксис з новими ключовими словами async та await. Згодом цю концепцію перейняли й інші мови програмування, зокрема Python та JavaScript. В JavaScript підтримку async/await додали у 2017 році. Призначення ключових слів async - додається до функції та вказує, що вона завжди повертає Promise. await - використовується перед об’єктом-промісом, щоб "дочекатися" результату перед виконанням наступних рядків коду. Перепишемо попередній приклад із завантаженням зображень, використовуючи async/await: ```js let image = null;   image = await downloadImage(url1); document.body.append(image);   image = await downloadImage(url2); document.body.append(image);   image = await downloadImage(url3); document.body.append(image); ``` Тепер код виглядає як звичайний синхронний: немає вкладених callback, усе читається рядок за рядком. Можна подумати, що await "зупиняє" виконання, очікуючи на результат промісу. Насправді ж код не блокує основний потік - під капотом він перетворюється на машину станів, де кожен стан описує дію до або після await. Ще одна перевага async/await - знайомий синтаксис для обробки помилок: ```js try {             let image = null;               image = await downloadImage(url1);             document.body.append(image);               image = await downloadImage(url2);             document.body.append(image);               image = await downloadImage(url3);             document.body.append(image); } catch (ex) { // обробка помилки } ``` У результаті асинхронний код виглядає так само зрозуміло, як і синхронний, що значно спрощує його супровід. Observable Observable - це ще один підхід до організації асинхронного коду. Назва походить від однойменного патерна проєктування (Observer pattern), який описує створення об’єктів, за якими можна «спостерігати», отримуючи від них сповіщення. Тобто це реалізація подієвої моделі за допомогою ООП. У сучасному JavaScript ця ідея пішла далі й стала основою реактивного програмування та бібліотеки RxJS. Якщо Promise представляє одне майбутнє значення (успішне або помилкове), то Observable - це потік значень, які можуть з’являтися з часом. Можна уявити: Promise - це одна посилка, яку ви отримаєте в майбутньому; Observable - це підписка на журнал, нові випуски якого надходитимуть регулярно. Щоб створити Observable, використовують конструктор або готові оператори RxJS. Наприклад, функція downloadImages(urls) може завантажувати кілька картинок і відправляти їх «у потік» по мірі завантаження: ```js import { Observable } from 'rxjs';   function downloadImages(urls) {   return new Observable(subscriber => {     urls.forEach(url => {       downloadImage(url, image => {         subscriber.next(image); // надсилаємо картинку у потік       });     });     subscriber.complete(); // повідомляємо, що потік завершено   }); } ``` Щоб використати Observable, на нього треба підписатися за допомогою subscribe: ```js downloadImages([url1, url2, url3])   .subscribe({     next: image => document.body.append(image), // що робити з новим значенням     error: err => console.error(err),           // обробка помилок   }); ``` Переваги Observable працюють із потоком даних, а не з одним результатом; підтримують підключення операторів трансформації (фільтрація, мапінг, комбінування потоків); можна легко скасувати виконання (відписатися від потоку). Нижче приклад обробки даних через оператори. В RxJS оператори підключаються через метод pipe: ```js import { filter, map } from 'rxjs/operators'; downloadImages([url1, url2, url3])   .pipe(     filter(image => image.width > 100), // пропускаємо лише великі картинки     map(image => {       image.classList.add('highlight');       return image;     })   )   .subscribe({     next: image => document.body.append(image),     error: err => console.error(err),     complete: () => console.log('Готово')   }); ``` Таким чином, як і у випадку з Promise, можна будувати ланцюжки обробки. Але Observable значно гнучкіші: вони дозволяють працювати не лише з одним значенням, а з динамічною послідовністю даних у часі. Для глибшого занурення рекомендую офіційний гайд Observable на RxJS.dev. та відео уроки Observables. Частина 1, та Observables. Частина 2[1]  Практичні поради по работі за асинхроним кодом Не змішуйте підходи без потреби Якщо почали писати з async/await, не вставляйте всередину .then() без особливої причини. Це ускладнює читання. Обробляйте помилки Використовуйте try/catch для async/await або .catch() для Promise. У випадку Observable завжди додавайте обробку error у subscribe(). Скасовуйте непотрібні операції Для Observable використовуйте unsubscribe(), коли потік більше не потрібен. Для fetch можна застосувати AbortController, щоб зменшити навантаження й уникнути витоків пам’яті. Уникайте "Pyramid of Doom" Замість вкладених callback застосовуйте Promise, async/await або Observable. Використовуйте паралельне виконання Якщо операції незалежні, запускайте їх одночасно через Promise.all(). Ізолюйте логіку обробки Розділяйте завантаження даних та маніпуляції з DOM. Це спростить тестування й повторне використання коду. Логуйте стан і помилки Під час розробки виводьте у консоль ключові події асинхронних операцій, щоб відстежувати їх послідовність. Пам’ятайте про event loop Розуміння різниці між мікрозадачами й макрозадачами допоможе прогнозувати порядок виконання коду. Перевіряйте сумісність середовища Деякі API можуть бути відсутні у певних середовищах (наприклад, fetch у Node.js доступний лише починаючи з версії 18).
ТОП 6 популярних CMS

Автор: Армен Маїлян

Тип сайта и его тематика Функциональность сайта На сегодняшний день более половины всех сайтов в сети Интернет используют ту или иную систему управления контентом (Content Management System – CMS). Однако термин CMS не получил, к сожалению, четкого определения. Он может иметь несколько значений в зависимости от сценариев и целей человека или проекта. Некоммерческая международная организация AIIM (Association for Information and Image Management - Ассоциация по вопросам Управления Информацией и Изображениями) ввела в обиход понятия ECM (Enterprise Content Management) и WCM (система управления веб-контентом) как две составных части CMS.  В этом случае под ECM подразумевается программный комплекс, обеспечивающий документооборот, работу внутренней базы знаний и организующий в общем виде набор бизнес-процессов предприятия. Как одну из функций ECM может включать в себя и работу с веб контентом. Хорошим примером такого типа систем является платформа Microsoft SharePoint. В свою очередь WCM стало включать в себя набор инструментов в некотором комплексе, позволяющем управлять веб-сайтом и контентом на нем. Часто также CMS также называют «движком» сайта. В обиходе у разработчиков устоявшимся значением, подразумеваемым под CMS, является некоторая программная система, применяемая для создания, редактирования и управления контентом сайта и устанавливаемая на свой хостинг. В дальнейшем, в этой статье мы примем за основу именно это - последнее определение, более похожее на WCM. Стоит отметить и часто включаемые в число CMS так называемые SaaS решения (software as a service – услуга доступа к программному обеспечению). В случае такого типа услуг компании не предоставляют код, который вы можете скачать, установить и настроить под себя на своём хостинге. Провайдеры услуги SaaS предлагают для клиентов свои платформы, со своим хостингом, своими индивидуальными возможностями без предоставления CMS в обиходном понимании. При такой схеме вы фактически оплачиваете не владение вашим сайтом, а его аренду. В нашей статье мы не будем рассматривать такой тип услуг.   Рассмотрим подходы, которых следует придерживаться, решая вопрос как выбрать движок для сайта.   Критерии выбора CMS для вашего сайта Тип сайта и его тематика Большой выбор различных систем управления контентом на рынке объясняется различиями в типах сайтов, для которых лучше всего конкретная CMS подойдет. Будет это форум или интернет магазин, блог или корпоративный сайт, сайт-визитка или новостной портал – определенность с тематикой сайта это первое, от чего будет зависеть правильный выбор CMS. Функциональность сайта Не смотря на определенную специализацию каждой CMS под определенные задачи, на сегодняшний день для ТОП CMS существует огромное количество различных расширений (плагинов, модулей), существенно увеличивающих их функциональность и возможности «донастройки». К примеру существующими плагинами можно превратить «блоговый» движок в интернет-магазин, а на движке портала сделать форум. Однако нужно понимать, что большое количество дополнительных плагинов будут влиять и на быстродействие, и на безопасность, и на внутреннюю слаженность работы механизмов сайта, из-за возможных конфликтов этих расширений. Также определенный набор проблем может доставить и необходимость регулярных обновлений как самого движка, так и установленных плагинов. Без таких обновлений у вас будут открываться дыры в безопасности, а это вряд ли вам понравится. А обновление большого числа расширений может вызвать конфликты совместимости. Поэтому правильный выбор CMS это баланс между нужной готовой функциональностью движка «из коробки» и количеством (и качеством) установленных расширений. Исходя из задач и потребности в балансе, сложно однозначно ответить на вопрос «какая CMS лучше?». Требовательность к ресурсам Правильный выбор тематики сайта приводит к необходимости выбора условной «мощности» движка. «Мощнее», в нашем случае, вовсе не обязательно значит – «лучше». Если вы нуждаетесь, к примеру, в сайте-визитке, установка движка портала для вас будет избыточной. Значительная часть ресурсов мощной CMS останется не задействованной. При этом требования к хостингу такого сайта будут выше – вам понадобится больше оперативной памяти, больше ресурсов процессора, могут понадобиться некоторые специфические настройки сервера и предустановленное программное обеспечение. Также стоит понимать, что, к примеру, сайты администрации для поселка и для города миллионника хоть и имеют общую тематику, но будут иметь разный дизайн, функциональность, наполнение, разную посещаемость и, соответственно, разные требования. Поэтому, при выборе вам следует исходить и из масштабов вашего будущего сайта. Неправильный выбор выльется либо в необоснованное удорожание и хостинга, и администрирования вашего сайта, либо в нехватку ресурсов. Возможность кастомизации движка Многим владельцам сайтов не хватает возможностей «голой» CMS. Кроме того, из-за специфики каждого конкретно бизнеса и каждого конкретного сайта, возможности расширения с помощью дополнительных плагинов тоже может быть недостаточно. Может потребоваться индивидуальная доработка движка, тем оформления или доработка под заказчика тех плагинов, функциональности которых не вам хватает. В этом вопросе нам очень важно будет понимать следующие моменты: Количество разработчиков на рынке – специалистов по конкретной CMS; Количество и качество документации к CMS и плагинам; Развитость сообщества пользователей и разработчиков конкретной CMS. Можно с уверенностью сказать, что чем более распространён движок – тем больше доступных специалистов, тем проще внести нужные правки и тем дешевле эти правки обойдутся. Стоит уделить внимание и особенностям SEO-оптимизации конкретного движка. Если вы хотите, чтобы аудитория вашего сайта росла, вам придется соответствовать ряду правил, касающихся и скорости работы сайта на различных типах устройств, и внешнего дизайна сайта вообще и конкретных страниц в частности, и внутренней иерархии страниц, и правильной настройки индексации и т.п. Возможность проведения SEO оптимизации вашего сайта сложно переоценить.  Наличие уже встроенных в CMS SEO инструментов или доступных качественных плагинов, а также возможность доработки их под ваши нюансы проекта привлеченными разработчиками, будут очень важны на этапе продвижения вашего сайта. Стоимость CMS и доработки. На рынке сегодня присутствуют как качественные бесплатные, так и значительное количество различных платных CMS. Кроме того, выбирая бесплатные CMS, вам вероятно захочется добавить в них платные расширения.  Выбирая между платными и бесплатными вариантами вам стоит заранее определиться с несколькими моментами: Представить себе (хотя бы приблизительно) стратегию развития вашего сайта. От понимания дальнейших перспектив будет зависеть комбинация доступных расширений и необходимость их доработок. Может так сложиться, что выбор бесплатной CMS, с учетом плагинов и доработок для получения нужного функционала, окажется существенно дороже, чем купить платную CMS и платный плагин, получив при этом техническую поддержку разработчиков этой CMS. Также может оказаться, что нужный для вас плагин под конкретную CMS нужно будет разрабатывать с нуля, тогда как под другую CMS такой плагин есть уже готовый, давно выпущенный и протестированный в реальной работе.   Распространенность CMS и ее востребованность Если выбранный вами движок сайта окажется непопулярным и его разработчики решат перестать выпускать обновления, вы столкнетесь с рядом проблем. Это и падение уровня безопасности системы, и ухудшение внешней привлекательности на фоне новых сайтов-конкурентов, использующих новые технологические решения. Также существенно сложнее будет найти специалиста для внесения доработок в движок, использующий уже устаревшие и непопулярные технологии. В свою очередь выход новейшей версии движка может быть связан с кучей багов системы, наличия новых дыр безопасности, несовместимости со старыми плагинами и другими сложностями. Самописные движки Наличие такого числа сложностей при выборе системы управления для своего сайта может вызвать у вас желание заказать или написать свой сайт с нуля. Действительно, ряд проектов прямо потребует от вас такого подхода. Подключение к своим специфическим сервисам, интеграция с другими уникальными проектами, гибкость в дизайнерских и архитектурных решениях – в определенных обстоятельствах написание своего движка будет правильным решением. Однако стоит сразу учитывать набор проблем, с которыми вам предстоит столкнуться: Подсадка «на иглу» одного разработчика. Полноценно разбираться в куче кода, с слабо или вовсе недокументированными возможностями, сможет только сам автор кода. Новому разработчику может оказаться проще переписывать модули вашего сайта с нуля, чем тратить время на разбор чужого кода. Это с одной стороны существенно удорожит работу, а с другой жестко привяжет вас к конкретному разработчику. Даже сменив одного программиста на другого, вы оказываетесь в той же ситуации, только теперь с новым разработчиком. Сроки и цена разработки. Написание нужных модулей «с нуля» будет стоить значительно дороже и займет значительно больше времени, чем адаптация уже существующего движка и плагинов с хорошей документацией от авторов. Проблемы тестирования и ошибок. В движках, которые используют каждый день миллионы человек, есть значительный плюс – большинство багов выявляются мгновенно и быстро перекрываются обновлениями. Наличие багов в вашей самописной системе будет зависеть как от навыков вашего разработчика, так и от применяемых им технологий. Эта комбинация может нести большое количество скрытых проблем как работоспособности, так и безопасности, которые останутся не выловленными, пока не станет слишком поздно. В результате разработка своего движка оказывается выгодна, практически, только крупным компаниям со своими внутренними отделами разработки и тестирования, которые будут писать свой сайт и поддерживать его работоспособность независимо от сторонних разработчиков. Статистика использования CMS   По данным сайта w3techs.com более 55% всех Web-сайтов в Интернете управляются теми или иными CMS. Как видно из диаграммы более 33% всех сайтов в Интернете работают на движке WordPress. Фактически это более 60% от сайтов, управляемых теми или иными CMS. Следующие по популярности системы CMS: Joomla – 5.4%, Drupal – 3.5%, Magento – 1.8%, PrestaShop – 1.4%. Набравшие в этой диаграмме высокие места Shopify (2.7%), Squarespace (2.7%) и Wix (1.8%) предлагают услуги SaaS (которые мы здесь не рассматриваем). По данным портала WhatСms первое место по числу сайтов среди популярных CMS также принадлежит WordPress - 52.74%. Затем идут Joomla - 5.219%, Drupal - 3.953%, Magento - 2.840%, PrestaShop - 1.671%. Blogger, как и несколько компаний в предыдущей диаграмме, является SaaS платформой. По данным портала BuiltWith первые три места среди не SaaS CMS занимают: WordPress - 28.27%, Joomla – 26.93%, Drupal – 8.84%. По данным портала SimilarTech, предлагающего свой ТОП движков для сайтов, среди 9,5 млн сайтов на CMS также лидирует WordPress, заняв 68% рынка CMS. Слетом идет Drupal (версии 6 и ниже) – 4%, Joomla – 3%, Drupal 7 – 1%, Typo3 – 1%. В число других CMS вошли как SaaS решения, так и другие полноценные CMS, включая и Drupal 8. Проанализировав указанную статистику, мы выбрали следующий 6 ТОП CMS: WordPress, Joomla, Drupal, Magento, PrestaShop и Typo3. Проведем краткий обзор движков для сайтов, входящих в наш ТОП CMS.   1) WordPress Выпущенный впервые в 2003 году, CMS WordPress быстро завоевал популярность как у продвинутых разработчиков, так и простых пользователей. Благодаря простой настройке, не самой высокой требовательностью к ресурсам хостинга и огромному количеству расширений эта CMS уже многие годы занимает первое место. На сегодня именно WordPress называют лучшей CMS для блога. WordPress идеально подходит для довольно простых веб-сайтов, таких как ежедневные блоги и новостные сайты, и для тех, кто ищет для себя простую CMS. Дополнения позволяют легко расширять функциональность сайта. К примеру, благодаря плагину WooCommerce, из сайтов на движке WordPress получается удобный для управления интернет-магазин – один из самых распространенных вариантов интернет-магазинов в сети. Нужно отметить и большое количество SaaS решений, использующих на своей платформе этот движок. Часть успеха WordPress в представленных диаграммах без сомнения относится к SaaS решениям. Официальный сайт WordPress: https://wordpress.org/ Особенности WordPress: Последняя версия - 5.0.3 от 09.01.2019. Написан на PHP. Более старые версии чем 5.0 официально объявлены «небезопасными». Минимальные требования к хостингу, поддержку которых обещает разработчик: PHP 7.3 MySQL 5.6 или MariaDB 10.0; HTTPS; Apache или Nginx. Плюсы WordPress: Бесплатная CMS распространяется с открытым исходным кодом. Огромное количество как платных, так и бесплатных шаблонов, и плагинов. Удобная панель администратора. Простая CMS для пользователя. Отмечают простоту использования и легкость установки как движка, так и тем, и расширений. Большое сообщество. Достаточно высокая производительность. Доступные платные плагины с проверенным качеством. Минусы WordPress: Относительно не маленькая требовательность к ресурсам, особенно при установке значительного числа плагинов. Отсутствие технической поддержки в не SaaS вариантах. Многие плагины написаны некачественно, что создает проблемы в работе и дыры в безопасности. Сайты на WordPress взламывают чаще всего.   Для каких сайтов используют CMS WordPress: Популярность WordPress продолжает расти: При этом в Украине сейчас 34910 сайтов используют эту CMS, а в Российской Федерации - 297353.   2) Joomla CMS Joomla впервые увидела свет в 2005 году. Отражая философию этого движка, его назвали словом, звучащим на суахили как «всё вместе». Фактически разрабатываемая как CMS для порталов, Joomla позволяет создавать сайты с большей гибкостью контента и внутренней структуры, чем WordPress, но при этом с достаточно простым и интуитивно понятным интерфейсом. Эта CMS поддерживает электронную коммерцию, социальные сети и многое другое. Используя этот движок, разработчики создают сайты-визитки, интернет-магазины, фотогалереи, порталы (включая новостные), блоги и другие сайты. Рядом пользователей, Joomla признается лучшей CMS для сайта типа портал. Официальный сайт: https://www.joomla.org/ Особенности движка Joomla: Последняя версия – 3.9.3 от 12.02.2019. Написана на PHP и JavaScript. Минимальные системные требования: PHP 5.3.10; MySQL  5.1 или SQL Server 10.50.1600.1 или PostgreSQL 8.3.18; Apache 2.0 или Nginx 1.0 или Microsoft IIS 7. Плюсы Joomla: Бесплатное распространение с открытым исходным кодом по лицензии GNU GPL v2, включая обновления; Частое предоставление обновлений движка; Большое сообщество пользователей и разработчиков; Большое количество доступных платных и бесплатных тем и плагинов; Относительно не высокий уровень требований к разработчику и пользователю. Минусы Joomla: Отсутствие технической поддержки. Вторая CMS по числу взломов. Joomla применяется в следующих сферах: В Украине 907  сайтов используют эту CMS и 3800 сайтов - в Российской Федерации. Есть определенная тенденция по снижению популярности CMS Joomla: 3) Drupal Впервые вышедшая в 2000 году, CMS Drupal является мощным, удобным для разработчиков инструментом для создания сложных сайтов. Как и большинство мощных инструментов, Drupal требует определенных знаний и опыта для работы. На основе Drupal часто создают порталы, новостные сайты, форумы, интернет-магазины - одни из самых продвинутых сайтов. Тем не менее Drupal является самым сложным для пользователя движков из тройки лидеров. Хотя его использование с каждым выпуском и становится все проще, если вы не готовы погрузиться в изучение этого программного обеспечения или не можете нанять кого-то, кто его знает, возможно, это не лучшая система управления контентом для вас. Официальный сайт: https://www.drupal.org/   Особенности Drupal CMS: Последняя версия 8.6.10; Ядро предоставляет только минимальный функционал, нужный для работы CMS, остальной функционал добавляется за счет плагинов. Установка модулей происходит в связке. Если для реализации функционала какого-то модуля нужны другие модули – они установятся автоматически в связке с первым модулем. Минимальные требования к хостингу для CMS Drupal 8: PHP 5.x/7.x для x86 и PHP 5.x для x64; MySQL 5.5.3 или MariaDB 5.5.20, или Percona Server 5.5.8, или PostgreSQL 9.1.2, или SQLite 3.6.8; Microsoft SQL Server и MongoDB поддерживаются благодаря отдельным модулям; Apache 2.x (используется в качестве Web-сервера для Drupal чаще всего) или Nginx (0.7.x, 0.8.x, 1.0.x, 1.2.x), стабильная версия 1.8.x или 1.9.x. Плюсы Drupal: Бесплатная CMS с открытым исходным кодом GNU GPL 2+. Стабильная работа ядра движка. Большое количество бесплатных тем, и различных расширений. Достаточно развитое сообщество разработчиков. Для решения типовых задач есть готовые наборы плагинов. Drupal известен своей мощной таксономией и способностью отмечать, классифицировать и организовывать сложный контент. Минусы Drupal: Сложность использования для начинающих пользователей. Меньшее количество доступных бесплатных плагинов чем у предыдущих CMS. Отмечают большую требовательность к хостингу за счет более частых обращений движка к базе данных, чем у других движков. Сегодня эту CMS используют в 7110 сайтов в Украине и 45189 сайтов в Российской Федерации. Можно наблюдать определенное снижение интереса к этой CMS по сравнению с 2016 годом:   4) Magento CMS Magento — движок для интернет-магазинов и других вариантов электронной коммерции. В основном популярен в западных странах и слабо представлен в русскоязычной части Интернета из-за слабой интеграции с местными сервисами. В настоящий момент является собственностью Adobe Inc. В основном Magento используется для крупных проектов. Считается не рентабельным использовать его для магазинов с несколькими сотнями позиций в обороте из-за относительно высокой стоимости разработки. Официальный сайт: https://magento.com/. Особенности CMS Magento: Написан на PHP. Последняя версия 2.3.0 от 28.11.2018. Требования к хостингу: LAMP (Linux, Apache, MySQL, and PHP) или LNMP; Apache 2.x или Nginx 1.7.x; PHP 5.6 или 5.5 или 5.4; MySQL 5.6 (Oracle or Percona); HTTPS; Доступ к crontab и к записи в .htaccess. Плюсы Magento: Бесплатная система с открытым исходным кодом. Движок оптимизирован под требования поисковых систем «из коробки». Готовая функциональность движка в базовой версии. Являясь собственностью Adobe Inc., отлично поддерживает интеграцию с сервисами Adobe. Минусы Magento: Несмотря на открытый исходный код, многими разработчиками считается не удобным работать с этой CMS из-за особенности организации ее кода. В бесплатной версии нет технической поддержки, платная версия будет стоить несколько тысяч долларов в год. Отсутствует интеграция с платежными средствами и другими локальными сервисами на постсоветском пространстве. Низкая скорость загрузки страниц сайта «из коробки». Большая часть настроек сайта потребует специфических знаний и навыков.   В Украине на сегодня 1113 сайтов используют CMS Magento и 1774 используют ее в Российской Федерации. После 2016 года можно наблюдать некоторое снижение числа сайтов на этой CMS:    5) PrestaShop PrestaShop – это еще один пример простой CMS с открытым исходным кодом для создания интернет-магазина. Созданный в 2008 году, этот движок достаточно быстро обрел популярность и продолжает ее наращивать. Это достаточно простая бесплатная CMS создана для организации торговых площадок и интернет магазинов. Официальный сайт: https://www.prestashop.com Особенности PrestaShop: Текущая версия – 1.7.5.1 от 18.02.2019. Написан на PHP с применением фреймворка Symfony. Минимальные требования к хостингу: PHP 5.6; MySQL 5.0; Server RAM – чем больше, тем лучше; Unix, Linux или Windows; Apache 2.2 или Nginx 1.0 или Microsoft’s IIS Web server 6.0. Плюсы PrestaShop: Бесплатный движок с открытым исходным кодом. Большое количество доступных тем оформления и расширений. Достаточный для начала работы интернет-магазина стандартный набор базовой версии движка. Имеет отличную русскую локализацию. Богатый выбор модулей для развития интернет-магазина. Хорошая интеграция с различными сервисами на постсоветском пространстве. Простота установки и работы. Удобная интуитивно понятная панель администрирования. Базовая версия имеет хорошую SEO-оптимизацию. Активные сообщества разработчиков. Минусы PrestaShop: Качественные темы и расширения являются платными. Более требователен к ресурсам чем WordPress. Низкая безопасность у бесплатных тем и плагинов. Наблюдаются баги при проведении внутренней оптимизации. Можно видеть рост популярности CMS PrestaShop. Например, на сегодня уже 2461 сайт работает на этом движке в Украине, и 8423 сайтов - в Российской Федерации.    6) Typo3 Typo3 это CMS с открытым исходным кодом. Впервые этот относительно универсальный движок был представлен в 1998 году. Typo3 часто применяется для новостных порталов, интернет-магазинов, корпоративных сайтов и других вариантов сайтов.   Официальный сайт: https://typo3.org/.   Особенности Typo3: Написан на PHP. Последняя версия 9.5.4 от 22.01.2019. Особенностью Typo3 является то, что в проектах на этой CMS вся информация публикуется от администратора и сайты не работают с пользовательским контентом. Typo3 не приспособлена для создания блога, активно взаимодействующего с пользователем портала или социальной сети. Минимальные требования к хостингу: Linux, Windows или Mac; PHP> = 7.2; PostgreSQL / Microsoft SQL Server / MariaDB >= 10.2 / MySQL >= 5 <= 5.7 / SQLite; Apache httpd или Nginx или Microsoft IIS, Caddy Server. Плюсы Typo3: Простота администрирования сайта. Возможность управления несколькими проектами из одной панели администратора. Возможность создания отдельных разделов на сайте с раздельным доступом для разных типов пользователей. Минусы Typo3: Относительно высокая требовательность движка к ресурсам сервера. Сложность изучения документации. Основная часть материалов не переведена с английского. Также, как и у ряда предыдущих CMS, у Typo3 наблюдается снижение популярности с 2016 года. В свою очередь в Украине на этом движке зарегистрировано 399 сайтов, в Российской Федерации - 1327. Полезным будет рассмотреть и сравнение производительности среди ТОП CMS.   Популярные CMS. Сравнение производительности. Согласно опубликованным данным тестирования ряда CMS, можно сделать вывод о наиболее быстром движке (пусть и в искусственных  - «тепличных» условиях теста). Указанные данные в таблице – это количество обрабатываемых запросов в секунду. Наиболее быстрой в данном исследовании среди популярных CMS показала себя WordPress 5.0 с версией PHP 7.3.   Вывод В нашем кратком обзоре CMS мы рассмотрели ТОП 6 наиболее распространенных CMS в мире. Как мы видим, каждая из них имеет свою специфику и особенности. Из-за разных возможных сфер применения сложно выбрать лучшую систему управления сайтом. Как лучшая CMS для блогов многими пользователями отмечается WordPress, а PrestaShop многими определяется как лучшая CMS для сайта интернет-магазина. Стоит понимать, что большая часть представленных в нашем ТОП CMS движков являются относительно универсальными. Кроме PrestaShop и Magento, ориентированных на интернет-коммерцию, с помощью других движков можно делать разнотипные проекты. Однако многими разработчиками признается, что никакая универсальная CMS не будет работать в конкретной сфере также хорошо, как специально разработанная для этой цели CMS. Поэтому, полезно кроме данного обзора ТОП CMS, рассмотреть отдельно ТОП CMS для блогов, ТОП CMS для интернет-магазинов, ТОП CMS для форумов, и далее. Такие обзоры помогут лучше понять, как правильно выбрать движок для сайта с вашими уникальными потребностями. Как вы могли заметить, рассмотренные CMS из ТОП движков для сайтов написаны на PHP. Если вы определились с CMS для своего проекта и хотите его сами доработать, или просто хотите научиться работать с топовыми проектами сети Интернет - вам, вероятно, будет интересен наш набор курсов  и вебинаров на портале ITVDN: WordPress Starter и WordPress Essential WordPress: создаем блог за час Интеграция верстки лендинга на CMS WordPress PHP Starter How To PHP Starter PHP Essential 
400+ питань на співбесіді щодо С++

Автор: Влад Сверчков

Дорогие друзья! Предлагаем вашему вниманию перевод статьи, опубликованной на DOU.ua 5 апреля 2021 года. Оригинальная версия на украинском языке доступна по ссылке. Junior 1.1 Общие вопросы 1.2 Метапрограммирование 1.3 Препроцессор и компиляция 1.4 Язык C 1.5 Язык С++ и ООП 1.6 STL / Algorithms 1.7 Многопоточность 1.8 Networking 1.9 OS/Linux 1.10 SCM / CI / CD 1.11 Практические задания Middle 2.1 Общее 2.2 Препроцессор и компиляция 2.3 Язык С 2.4 Язык С++ 2.5 Паттерны проектирования 2.6 Метапрограммирование 2.7 OOP/OOD 2.8 STL / Algorithms 2.9 Многопоточность 2.10 Networking 2.11 SCM / CI / CD 2.12 Практические задания Senior 3.1 Общее 3.2 Препроцессор и компиляция 3.3 C/C++ 3.4 OOP/OOD 3.5 STL / Algorithms 3.6 Многопоточность 3.7 SCM / CI / CD 3.8 Практические задания Предлагаем список технических вопросов, которые, вероятно, вам поставят на собеседованиях по C++. Вопросы предоставили специалисты, принимающие участие в проведении технических интервью по этому языку. Учтите, что есть широкий спектр специализаций, поэтому выбирайте свое направление и готовьтесь.   Junior   Общие вопросы   1. В чем заключаются основные принципы ООП? 2. Что такое сложность алгоритма? 3. Код работает неправильно. Что делать? 4. Объясните такие структуры данных, как стек и очередь. 5. Какие книги, связанные с программированием, читали? Чему с них научились? 6. Что интересного нашли в новых стандартах С++17, С++20? 7. Что такое таблица ASCII? 8. Что такое Unicode? 9. Что такое паттерны проектирования и для чего их используют? 10. Патерны Singleton, Strategy, Template-Method, Decorator? 11. Для чего нужны модульные тесты? 12. Какая разница между модульными и интеграционными тестами? 13. Что такое TDD?   Метапрограммирование   14. Что такое шаблонный класс и шаблонная функция? 15. Что такое конструкторы? Какие типы знаете? 16. Может ли конструктор быть шаблонной функцией? 17. Может ли виртуальная функция быть шаблонной? 18. Что такое инстанциация шаблона? 19. Что такое специализация шаблона? Частичная специализация шаблона? 20. Расскажите об имплементации шаблонных классов в срр-файле?   Препроцессор и компиляция   21. Как проходит процесс компиляции срр-файлов в бинарный файл? 22. Что такое препроцессор? 23. Как работает препроцессор? 24. Какие знаете команды препроцессора? 25. Как работает директива include? 26. Как работает директива define? 27. Что именно линкует линкер? 28. Что такое оптимизация компилятора? 29. Что такое флажки компиляции? 30. Как защитить хедер от повторного включения? 31. Что делает директива include? 32. Как работают макросы?   Язык C   33. Как static влияет на глобальные/локальные переменные? 34. Как сonst влияет на переменную? 35. Какие варианты использования extern знаете? 36. Какие варианты использования volatile знаете? 37. Какие есть битовые операции? 38. Что такое булевая алгебра? 39. Расскажите об этапах разработки библиотеки или программы. 40. Что такое алгоритмы сортировки и какие вы знаете? 41. Какие алгоритмы работы со строками знаете? 42. Какие алгоритмы на графах знаете? 43. Где может храниться переменная? 44. Какая разница между calloc и malloc? 45. Для чего используют realloc? 46. Что такое указатель? 47. Каков размер указателя и от чего он зависит? 48. Какие есть операции с указателями? 49. Что такое struct? 50. Как определить размер структур? 51. Что такое выравнивание в структурах? 52. Что такое union? 53. Какой размер union?   C++/OOP   54. Что такое класс? 55. Какие есть основные типы данных в C++? 56. Что такое инкапсуляция? Как она реализуется в C++? 57. Какие есть встроенные типы в С++? 58. Что такое enum? 59. Как соотносится класс и объект? 60. Какая разница между структурой и классом? 61. Разница между private/protected/public и где они используются? 62. Какие методы класса являются стандартными для класса? 63. Что такое абстрактный класс и зачем он? 64. Сколько памяти занимает объект пустого класса class A {}; ? 65. Что случится с функцией, если к ней добавить ключевое слово static? В контексте члена класса? В контексте метода класса? 66. Какие особенности статических полей класса? 67. Какая особенность константных методов-членов класса? 68. Как изменить поле класса в константном методе класса? 69. Какие методы можно вызвать из константных объектов? 70. Что такое куча и стек? Различия, принцип работы. 71. В чем разница между указателем и ссылкой? 72. Для чего нужен указатель на функцию? Как его объявить? 73. Что будет, если забыть вызвать delete? Когда освободится эта память? 74. Что такое умный указатель? Какие умные указатели есть в стандартной библиотеке? 75. Как работает std::unique_ptr? 76. Как работает std::shared_ptr? 77. Расскажите о константности переменной, ссылки, указателя. Что такое константный указатель и указатель на константу? Размер указателя в памяти? 78. Расскажите о передаче аргументов по значению, по ссылке и по указателю. 79. Расскажите о порядке вычисления аргументов функции? 80. Что произойдет, если вернуть ссылку на временный объект? 81. Что такое перегрузки функции? Виды перегрузки. 82. Что такое явное и неявное приведение типов в С++? Расскажите о функциях явного приведения типов в C++. 83. Что такое инициализация переменной в if? 84. Что такое ленивые вычисления в С++? 85. Расскажите о циклах for и range-for. 86. Что делает ключевое слово auto? auto-определение return-типа, аргументов функции? 87. Чем отличаются delete и delete [ ] ? Что случится, если вызвать delete у объекта, созданного через new [ ] ? 88. Обработка ошибок в С++. Какие конструкции используют при обработке exception? 89. Можно ли выбрасывать exception из конструктора? Какие поля будут сконструированы, какие поля будут разрушены? 90. Что такое memory leak? 91. Можно ли выбрасывать exception из деструктора? 92. Как отловить деление на 0 в С++? 93. Как работают константные методы? 94. Что такое лямбда-функция в С++? Как получить доступ к переменным во внешней области видимости? 95. Для чего использовать namespace, anonymous namespace? 96. Как вызвать объект из nested namespace? 97. Как работают inline-функции? Может ли такая функция быть рекурсивной? 98. Что такое полиморфизм? 99. Для чего используется наследование? 100. Какие бывают типы наследования? 101. Для чего используют виртуальное наследование? 102. Как можно решить проблему ромбовидного наследования без использования виртуального наследования? 103. Что случится, если класс-наследник передать по значению в функцию, которая принимает базовый класс? 104. Что случится, если пронаследоваться от базового класса, который не имеет виртуального конструктора? 105. Что случится, если вызвать переопределенную virtual function из конструктора? Может ли конструктор быть виртуальным? 106. Может ли pure virtual function иметь имплементацию? Что случится, если вызвать pure virtual function из конструктора? 107. Какие методы генерируются для класса по умолчанию? В каком случае такие методы не будут генерироваться? Как заставить компилятор добавить/удалить эти методы? 108. Как запретить наследовать класс? 109. Какой порядок конструирования и разрушения классов в иерархии? Порядок инициализации полей класса? 110. Какие есть способы инициализации полей класса? 111. Может ли деструктор быть виртуальным? 112. Что делает ключевое слово virtual? 113. Для чего используют виртуальный деструктор? 114. Что такое глубокое копирование? 115. Что такое виртуальные функции и зачем они нужны? 116. Как защитить объект от копирования? 117. Что такое семантика перемещения?   STL / Algorithms   118. Из чего состоит STL? 119. Какие алгоритмы применяли с STL? В чем преимущество использования алгоритмов перед собственноручно написанными функциями? 120. Расскажите о контейнерах стандартной библиотеки vector, list, map, unordered_map. 121. Какие знаете типы итераторов? Чем они отличаются? В каких контейнерах используются? 122. Какая разница между std::set, std::map, std::unordered_multimap? 123. Что такое идиома remove-erase? 124. Как получить наименьшее значение типа? 125. Какая разница между std::map и std::hashmap? 126. Как подсчитать количество элементов в std::list? 127. Что такое сложность алгоритма и от чего она зависит? 128. В чем разница между vector и list и в каких случаях их лучше использовать?   Многопоточность   129. Что вам известно о многопоточности? 130. Что общего и различного в процессах и потоках? 131. Как синхронизировать передачи информации между потоками? 132. Какая разница между мьютексом и семафором? 133. Что такое deadlock? 134. Является ли С++ thread-safe? 135. Что такое race-condition? 136. Как избежать состояния гонки? 137. Что такое атомарная операция? 138. Как работать с std::mutex?   Networking   139. Что такое сокет? 140. Какие операции можно делать с сокетом? 141. Какая информация нужна, чтобы создать сокет? 142. Какие бывают модели сетей? 143. Расскажите об уровнях модели OSI. 144. Расскажите об уровнях модели TCP/IP. 145. Что такое IP-адрес? 146. Для чего используется маска подсети? 147. Какая разница между IPv4 и IPv6? 148. Сколько памяти необходимо для хранения IPv4? 149. Для чего нужен порт? 150. Сколько максимально может быть портов? 151. Какая разница между TCP и UDP? 152. Для чего такой ненадежный UDP-протокол?   OS/Linux   153. Что такое менеджер пакетов? 154. Какие бывают менеджеры пакетов? 155. Какие бывают дистрибутивы Linux? 156. Что такое PID? 157. Для чего используют файловые дескрипторы? 158. Расскажите о стандартных файловых дескрипторах процесса. 159. Что такое Pipe? 160. Что такое Named Pipe? 161. Что такое UID? 162. Расскажите о командах bash.   SCM / CI / CD   163. Какие есть виды SCM? 164. Для чего используют системы контроля версий? 165. Какие есть команды git? 166. Какие этапы во время комита изменений? 167. Разница между git fetch и git pull? 168. Какие есть этапы решения merge conflict?   Практические задания   169. Посчитайте количество единиц в произвольном числе. 170. Есть структура по типу «односвязный список». Напишите функцию, которая разворачивает список. То есть, первый элемент становится последним, а последний - первым. 171. Напишите реализацию функции int atoi (const char *str); преобразования строки в число. 172. Для структуры типа односвязный список напишите функцию вставки элемента. 173. Реализуйте класс vector. 174. Реализуйте бинарный поиск в массиве. 175. Реализуйте любую сортировку. 176. Реализуйте макрос для сравнения двух строк. 177. Реализуйте реверс строк. 178. Реализуйте перевода числа из строки в int. 179. Реализуйте подсчет слов в предложении. 180. Реализуйте подсчет чисел Фибоначчи. 181. Найдите такие элементы двух массивов, которые попадаются только в каждом из них. Желательно использовать STL. 182. Удалите из unordered_map элементы, которые делятся на 2 и выведите ключи этих элементов. 183. Напишите класс для логирования, который мог бы логировать к консоли или файлу. 184. Напишите функцию для определения, является ли определенный год високосным. 185. Напишите функцию для определения, является ли определенное слово палиндромом. 186. Напишите реализацию паттерна Singleton. 187. Напишите реализацию std::vector с операциями: push_back, push_front, pop_back, pop_front, size, clear. 188. Напишите рекурсивный поиск значения в дереве бинарного поиска. 189. Напишите функцию, которая проверяет, является ли дерево сбалансированным. 190. Напишить функцию для поиска уникального элемента в массиве.   Middle   Общее   1. Какие курсы прошли или книги прочитали за этот год? Чему научились? 2. Что нравится и не нравится в С++? Чего не хватает? 3. Что интересного нашли в новых стандартах С++17, С++20 (конкретные фичи)? 4. Расскажите о фичах, которые появились в разных версиях языка. 5. Расскажите о модели памяти, которая появилась в С++11 стандарте. 6. Что такое сериализация? Какие библиотеки знаете? 7. Какие знаете паттерны проектирования? 8. Что такое операционная система? Какие существуют типы по назначению? 9. Назвать основные составляющие и принципы работы ОС Linux в качестве примера системы общего назначения. 10. Что такое SFINAE и PIMPL? 11. Назовите порождающие, структурные и поведенческие паттерны программирования и приведите примеры их использования.   Препроцессор и компиляция   12. Расскажите о системах автоматизации билд-процесса. 13. Какая разница между статической и динамической библиотеками? 14. Какая разница между исполнительным файлом и динамической библиотекой? 15. Что такое DLL hell? 16. Что такое флажки компиляции (fPIC)? 17. В чем разница между дебаженной и релизной сборкой? 18. Что нужно для использования сторонней библиотеки? 19. Что такое internal linkage?   C   20. Что будет, если дважды вызвать free? 21. Как происходит вызов функции? 22. Как происходит передача параметров в функцию? 23. Как прорабатывается константа переменных? 24. Что означает ключевое слово inline? 25. Для чего используют выравнивания, можно ли его контролировать? 26. Расскажите о битовых полях. 27. Для чего нужен extern "C"? 28. Что будет, если в двух файлах сделать функцию с одинаковым именем и параметрами? На каком этапе возникнет ошибка? 29. Как экспортировать/импортировать функции из динамической библиотеки? 30. Какая разница между С-style приведением типов и C++ приведением?   C++   31. Что такое явное и неявное приведение типов в С++? Зачем делать explicit-конструктор? 32. Что такое Uniform initialization? Aggregate initialization? 33. Что такое Reference to temporary object? Как продлить время жизни временного объекта? 34. Что такое делегирующий конструктор? 35. Что такое список инициализации? 36. Какой порядок инициализации полей класса? Что случится, если конструктор инициализирует поля в другом порядке? 37. Что случится, если инициализировать поле другим полем? 38. Что такое copy elision? Сколько раз будет вызван конструктор/деструктор у объекта, которого возвращают по значению? 39. Что такое move-семантика? 40. В каких случаях не будет сгенерирован конструктор копирования? 41. Чем отличается конструктор копирования от оператора присваивания? 42. При каких условиях в конструкторе можно выбросить exception? 43. Что такое конструктор по умолчанию? Для чего нужны default и delete? 44. Чем отличается интерфейс от абстрактного класса? 45. Какие виды полиморфизма в С++? 46. Как реализовано наследование в большинстве компиляторов? 47. Множественное наследование: за и против? 48. Виртуальное наследование и порядок конструирования? 49. Зачем использовать override? 50. Какие есть правила вывода типа при использовании auto? В каких случаях auto может привести к нежелательному копированию объекта? 51. Расскажите обо всех возможных способах использования ключевого слова static в С++. Что такое static initialization order fiasco? 52. Что делает вызов throw; в блоке catch? 53. Чем отличается constexpr от const? 54. Что такое const correctness? 55. В каком случае можно использовать const_cast? 56. Что такое ключевое слово mutable и когда его нужно использовать? 57. Что такое ключевое слово friend и когда его нужно использовать? 58. Расскажите о лямбда-выражениях в С++ и доступ к переменным во внешней области видимости, захват this в лямбду и время жизни лямбды и захваченных переменных? 59. Что такое функтор? Напишите пример. 60. Что такое специализация шаблона? 61. Что такое dynamic_cast и run-time type identification? 62. Что такое exception? Как бросить и поймать? 63. Что будет, если бросить exception из конструктора? А из деструктора? 64. Что будет, если не поймать exception? 65. Что произойдет, если exception выйдет за пределы блока noexcept функции? 66. Для чего можно использовать приватное наследование? 67. Что такое контракт функции? 68. Что такое vptr и vtable? 69. Где содержится vptr? 70. Где содержится vtable? 71. Какая разница между overload and override? 72. Как компилятор различает члены класса и обычные переменные в функциях? 73. Зачем используют exceptions? 74. Что такое блоки try-throw-catch? 75. Расскажите о логике catch-блоков. 76. Что такое move constructor? 77. В чем разница между константным методом и неконстантным? 78. Что такое В-нотация и как определить сложность любого алгоритма? 79. Что такое таблица виртуальных методов? 80. Какие функции класса автоматически генерирует компилятор, если их не определить? 81. Что такое выравнивание данных? 82. Что такое exception? 83. Какие есть стандартные контейнеры и на основе каких структур они построены? 84. Что такое Undefined behavior? Приведите примеры. 85. Как определить, что в программе есть memory leak? 86. Для чего нужен std::make_shared? Чем он лучше создания std::shared_ptr через конструктор? 87. Что будет, если выделить один объем памяти, а записать больше? 88. Что такое переполнение stack?   Паттерны проектирования   89. Зачем нужны паттерны? Какие типы паттернов различают? 90. Недостатки паттерна Singleton? Когда он уместен? 91. Преимущества и недостатки PIMPL? 92. В чем разница между паттерн-фабрикой и фабричным методом? Когда использовать какой из них? 93. Что такое паттерн Observer? 94. Як контролировать состояние программы? Машину состояний? Паттерн состояние? 95. Что такое паттерн Visitor?   Метапрограммирование   96. Какие есть правила вывода типа в шаблоне? 97. Чем отличается using от typedef? 98. Сколько памяти занимает произвольная структура? Что такое выравнивание объекта? 99. Почему пустая структура занимает 1 байт? Какая минимальная единица адресации в С++?   OOP/OOD   100. Что такое SOLID? Что означает каждый из этих принципов? 101. Расскажите о паттернах проектирования. 102. Что такое Dependency Injection? Приведите пример. 103. Какие преимущества и недостатки функционального подхода? 104. Что такое принцип RAII? 105. Что такое принцип DRY? 106. Что такое принцип KISS? 107. Какие преимущества композиции перед наследованием?   STL / Algorithms   108. Какие алгоритмы с STL использовали? Каких не хватает? 109. Какими особенностями должен обладать класс, чтобы он был итератором? 110. Какие бывают итераторы? 111. Расскажите об инвалидации итераторов. 112. Как оптимизировать удаление элемента со средины вектора? 113. Как реализован vector? 114. Как реализован list? 115. Как расширить STL-контейнеры? 116. Какие есть алгоритмы в STL? 117. В чем разница между vector, deque, list, set e STL? 118. Когда надо использовать map? Когда - unordered_map? Какая сложность поиска и вставки в этих контейнерах? 119. Как проверить, есть ли в контейнере элементы? Почему вызов container.size() является плохой практикой? 120. Что такое exception safety guarantee? Какую exception safety guarantee имеют STL-контейнеры? 121. Расскажите о типах умных указателей и о подсчете ссылок в них.   Многопоточность   122. Является ли С++ thread-safe? 123. В чем разница между многопоточностью и асинхронностью? 124. Что такое многопоточность? Какую функциональность предоставляет С++ для разработки многопоточных приложений? Какие основные проблемы многопоточных приложений? 125. Как передать информацию между несколькими процессами? 126. Как синхронизировать между собой несколько процессов? 127. Какие есть особенности работы с shared memory? 128. Как работает spinlock? 129. Какие вы знаете особенности использования recursive mutex? 130. Расскажите о read-write mutex. 131. Что такое race-condition? Взаимная блокировка? Что такое критическая секция? 132. Как избежать состояния гонки? 133. Чем отличается мьютекс от семафора? 134. Какие примитивы синхронизации реализованы в C++? Преимущества lock_guard? 135. Что случится, если exception выйдет за пределы потока? Какие инструменты есть для безопасной асинхронности в С++? 136. Чем отличается std::launch::async от std::launch::deferred? 137. Что такое атомарная операция? std::atomic? 138. Как работать с std::conditional_variable? 139. Как создать поток с помощью std::thread? 140. На сколько потоков лучше разбить задачу? От чего это зависит? 141. Как работать с std::async? 142. Thread-safe гарантии контейнеров в С++? В чем недостаток интерфейса front() + pop_front()?   Networking   143. Что такое TCP handshake? 144. Какая разница между TCP и UDP? 145. Расскажите о протоколах верхнего уровня. 146. Какая разница между HTTP и HTTPS? 147. Расскажите об SSL/TLS handshake.   SCM / CI / CD   148. Расскажите о процессах CI. 149. Как отредактировать комит? 150. Расскажите об интерактивном rebase. 151. Какие могут быть способы дебаггинга кода? 152. Для чего нужны Unit test? Чем отличается от Functional Test? 153. Как тестировать код? Какой используете фреймворк? 154. Какие библиотеки знаете для написания тестов? 155. Что такое mock? 156. Сколько тестов нужно написать на одну функцию? 157. Что такое побочный эффект, идемпотентность и чистые функции? 158. Что такое контейнеризация и в чем преимущества и недостатки? Что такое Docker или иной инструмент контейнеризации? 159. Что такое CI/CD и какие преимущества приносит для разработчика? 160. Какие принципы итеративных методологий? 161. Какие преимущества и недостатки code-convention?   Практические задания   162. Напишите максимально корректную реализацию класса string с конструктором копирования и оператором присваивания. 163. Напишите реализацию очереди. 164. Реализуйте функцию, которая за один проход найдет уникальный элемент в контейнере. 165. Напишите thread-safe пул потоков. 166. Напишите игру жизни в ООП стиле. 167. Напишите класс, который достает из базы список товаров по фильтру и показывает на консоли. Напишите тесты для него. 168. Любая задача на написание кода, чтобы проверить умение проектировать интерфейсы и придерживаться принципов SOLID, DRY, KISS. 169. Напишите свою реализацию std::atomic. 170. Напишите программу для анализа графов: нахождение циклов, deadlock-состояний, циклов, недоступных состояний. 171. Напишите программу, которая бы проверяла, что в системе запущен только один ее экземпляр. Решение должно быть cross-platform. 172. Проанализируйте C++ код с точки зрения качества: выявить потенциальные memory leak, нерациональное использование STL-контейнеров, алгоритмов, неоптимальные конструкции и тому подобное. 173. Напишите код для решения судоку. 174. Напишите код, который найдет зацикливание в односвязном списке.   Senior   Общее   1. Как вы понимаете SOLID? 2. Как разработать систему плагинов на С++? 3. Что такое RPC? Какие библиотеки знаете? 4. На что обращать внимание при проведении code review? 5. Какие есть проблемы при написании кроссплатформенного кода? На что обращать внимание? 6. Что делать, если код работает медленно? 7. Какие есть способы и методологии измерения быстродействия кода? Как можно устранить/уменьшить влияние замеров на быстродействие? 8. Что такое SFINAE? Для чего используется? 9. Что такое метапрограммирование? С помощью чего реализуется на С++? 10. Как использовать variadic templates? 11. Как тестировать закрытые методы? 12. Как считать покрытие тестами? Нужно ли это делать? 13. Что такое cache miss и как это выявить? 14. Что такое SIMD-инструкции? Какие необходимые условия и способы их использования? 15. Что такое покрытие кода и как обеспечивается? 16. Опишите принципы lock-free структур данных и свой опыт работы с ними.   Препроцессор и компиляция   17. Расскажите о построении билд-системы. 18. Как работать с билд-системами: Make, CMake. 19. Как интегрировать third-party в проект? 20. Что такое барьеры памяти? 21. Расскажите о работе с сырыми указателями и о ручном управлении памятью. 22. Что такое статический анализатор кода? Какие знаете? 23. Что такое динамический анализатор кода? Какие знаете? 24. Проект медленно собирается. Как можно ускорить?   C/C++   25. Расскажите об использовании realloc в контейнерах. 26. Как работают шаблоны? 27. Расскажите о специализации шаблонов. 28. Как работает RTTI? 29. Можно ли использовать exception в конструкторе/деструкторе? 30. Что такое rvalue и lvalue? 31. В чем особенности контейнеров std::set, std::map, std::unordered_map, std::hash? 32. Что такое placement new? Для чего используют? Как сделать placement delete? 33. Как размещается в памяти класс со множественным наследованием и виртуальными функциями? 34. Как работают точки остановки? 35. Что такое уязвимости? Каков механизм их работы? 36. Как написать собственный std::shared_ptr? 37. Что такое curiously recurring template pattern? 38. Опишите назначение и принцип работы std::shared_ptr, std::unique_ptr и std::weak_ptr. 39. Какое назначение и отличия использования std::variant и std::any? 40. Какие улучшения получил std::search в С++17 ? 41. Что такое copy elision и когда он становится возможным? Какие особенности для разных стандартов? 42. Что такое Return Value Optimization?   OOP/OOD   43. Объясните принципы SOLID. 44. Объясните принципы KISS. 45. Объясните принципы YAGNI. 46. Какие есть подходы к оптимизации кода? 47. На что стоит обращать внимание при code review? 48. Какие есть паттерны проектирования? Почему не советуют использовать Singleton? 49. Что такое статический полиморфизм?   STL / Algorithms   50. Когда std::vector может использовать std::move? 51. Расскажите о своем любимом алгоритме поиска. 52. Что такое lock-free и wait-free алгоритмы? В чем их отличия и способы реализации? 53. Опишите назначение execution policy для параллельных алгоритмов.   Многопоточность   54. Расскажите о построении API, рассчитанных на многопоточное использование. 55. В чем разница между kernel-level и user-level потоками? 56. Что такое coroutine? 57. Что делает спецификатор thread_local? 58. Как реализовать синхронизацию в задаче producer-consumer? 59. Як синхронизироваться между различными процессами?   SCM / CI / CD   60. Расскажите о настройке процесса менеджмента ветвей репозитория. 61. Расскажите о стратегии разветвления (branching).   Практические задания   62. Напишите базовую реализацию std::shared_ptr. 63. Реализуйте алгоритм сортировки. 64. Реализуйте алгоритм хеширования. 65. Реализуйте shared_ptr с расширением для weak_ptr. 66. Реализуйте простейший producer-consumer, используя условные переменные. 67. Опишите как можно подробнее, что происходит в системе, когда приложение делает сетевой запрос. 68. Детально описать дизайн программного компонента, например, системы голосования; учесть при этом высокую нагрузку и сделать ее расширяемой и отказоустойчивой.   Выражаем благодарность за участие в статье Александру Жакуну, Ярославу Пушко, Назару Семенишину, Сергею Подоброму, Владимиру Кочуну, Владимиру Новикову, Сергею Кривоносу, Марку Цирульнику, Кириллу Пшеничному, Виктору Шуму, Сергею Братусю.    
ТОП 20 тестових завдань на інтерв'ю для Java розробника

Автор: Армен Маїлян

Напишіть програму на Java для перевертання рядка, змінивши розташування символів у рядку задом наперед без використання вбудованих в String функцій Напишіть програму на Java для перевороту послідовності символів у рядку без використання вбудованої в String функції reverse() Напишіть програму на Java для того, щоб поміняти місцями значення, що зберігаються у двох змінних за допомогою третьої змінної Напишіть програму на Java, щоб поміняти місцями значення, що зберігаються у двох змінних, без використання третьої змінної Напишіть програму Java для підрахунку кількості конкретних слів у рядку, використовуючи HashMap Напишіть Java-програму для ітерації об'єкта типу HashMap з використанням циклу while та покращеного циклу for Напишіть програму на Java, щоб дізнатися, чи є число простим, чи ні Напишіть Java-програму, щоб визначити, чи є рядок або число паліндромом, чи ні Написати програму на Java для обчислення серії чисел Фібоначчі Напишіть Java-програму для обходу ArrayList з використанням циклу for, while та покращеного циклу for Напишіть програму на Java, щоб продемонструвати явну перевірку умов очікування Напишіть Java-програму для демонстрації прокручування вгору / вниз Напишіть програму на Java, щоб відкрити усі посилання на gmail.com Напишіть код для Selenium, щоб перейти до попередньої вкладки Напишіть програму на Java, щоб знайти повторювані символи в рядку Напишіть Java-програму, щоб знайти друге за величиною число в масиві Напишіть Java-програму для перевірки, чи є введене число числом Армстронга Напишіть Java-програму для видалення всіх пробілів з рядка за допомогою replace() Напишіть Java-програму для видалення всіх пробілів з рядка без використання replace() Напишіть Java-програму для читання даних із таблиці Excel У цій статті ми наведемо досить багато прикладів програм з тих, що просять написати претендентів під час проходження інтерв'ю на вакансію Java розробника. Вказані тестові завдання ми наводимо з реальними прикладами коду, заданими в інтерв'ю як початківцям, так і досвідченим кандидатам. Сьогодні серед інтерв'юерів стало звичайною практикою давати тестові практичні завдання під час інтерв'ю, не фокусуючись лише на теоретичних питаннях. Такі завдання зазвичай задають на технічному етапі інтерв'ю Java розробника. Для того, щоб допомогти претендентам на відповідні вакансії пройти такі інтерв'ю, ми хочемо перерахувати кілька дуже важливих прикладів програм на Java разом з належним описом кожного. Крім того, ми також додаємо відповідні пояснення коду. Ці пояснення дадуть вам чітке уявлення, як працює кожна програма.   Найпопулярніші питання інтерв’ю Java-програмування. Q # 1) Напишіть програму на Java для перевертання рядка, змінивши розташування символів у рядку задом наперед без використання вбудованих в String функцій.   Відповідь: Для початку ініціалізуємо рядкову змінну st і використовуємо клас StringBuilder. Об'єкт класу StringBuilder strB буде надалі використовуватися для додавання значення, що зберігається в рядковій змінній st. Після цього ми використовуємо вбудовану в StringBuilder функцію reverse() і зберігаємо нову – обернений рядок в stB. Нарешті ми виводимо на екран stB. public class FirstTask{             public static void main(String[] args) {                         // ITVDN.com 1 із ТОП 20 тестових завдань на інтерв’ю для Java розробника                         String st = "Задача1";                         StringBuilder stB = new StringBuilder();                         stB.append(st);                         stB = stB.reverse();     // використовуємо StringBuilder для перевороту рядку                         System.out.println(stB);             } } На екрані отримаємо: 1ачадаЗ   Q # 2) Напишіть програму на Java для перевороту послідовності символів у рядку без використання вбудованої в String функції reverse().   Відповідь Спосіб 1: Є кілька способів, за допомогою яких ви можете перевернути ваш рядок, якщо вам дозволено використовувати інші вбудовані функції рядка. У цьому способі ми ініціалізуємо рядкову змінну з ім'ям st значенням заданого рядка. Потім ми конвертуємо цей рядок у масив символів за допомогою функції toCharArray(). Після цього ми використовуємо цикл for, щоб взяти всі символи у зворотному порядку і вивести їх так на екран по черзі. public class SecondTask {             public static void main(String[] args) {            //ITVDN.com 2 з ТОП 20 тестових завдань на інтерв’ю для Java розробника            String st = "Вчимося програмувати";                char symbols[] = st.toCharArray();  // конвертуємо рядок у масив символів, потім виводимо символи на екран у зворотному порядку            for(int x= symbols.length-1; x>=0; x--) {                         System.out.print(symbols [x]);            }       } } На екрані отримаємо: итавумаргорп ясомичВ Спосіб 2: Це ще один спосіб виконати завдання з переворотом послідовності символів у рядку. У цьому способі ви оголошуєте рядкову змінну st, а потім використовуєте клас Scanner, оголошуючи об'єкт scannerQ для роботи зі стандартним потоком введення даних. У цьому випадку програма набуде рядкового значення через командний рядок (при його виконанні). Далі ми використовували метод nextLine(), який прочитав наш рядок під час введення його через консоль з пробілами між словами рядка. Після цього ми використовували метод split() для поділу рядка на його підрядки (тут не вказується роздільник). Потім ми виводимо рядок у зворотному порядку, використовуючи цикл for. import java.util.Scanner; public class SecondTask {             public static void main(String[] args) {            // ITVDN.com 2 з ТОП 20 тестових завдань на інтерв’ю для Java розробника            String st;            Scanner scannerQ = new Scanner(System.in);            System.out.println("Введіть ваш рядок:");            st = scannerQ.nextLine();            String[] temp = st.split("");       //використовуємо метод split для виведення рядку в зворотньому порядку            for(int x= temp.length-1; x>=0; x--)            {                         System.out.print(temp [x] + "");            }                     } } На екрані отримаємо: Введіть ваш рядок: asfasdf aasdfasdfadsf fsdafdsafdsaa fdsafsa Спосіб 3: Це спосіб майже такий, як спосіб 2, але тут ми не використовуємо метод split(). Ми використовуємо клас Scanner та метод nextLine() для читання вхідного рядка. Потім ми оголосили цілочисельну змінну stringLength, присвоюючи їй значення довжини вхідного рядка. Після цього ми вивели рядок у зворотному порядку, використовуючи цикл for. Однак ми використовували метод charAt(index), який повертатиме символ за конкретним індексом. Після кожної ітерації символ буде додано до нового рядка для отримання перевернутого значення рядкової змінної. Потім ми виводимо змінну перевернутого рядка. import java.util.Scanner; public class SecondTask {             public static void main(String[] args) {            // ITVDN.com 2 з ТОП 20 тестових завдань на інтерв’ю для Java розробника            String mainString, reverseString = "";            System.out.println("Введіть рядок, щоб отримати перевернутий:");            Scanner scannerQ = new Scanner(System.in);            mainString = scannerQ.nextLine();            int stringLength = mainString.length();            for(int x= stringLength -1; x>=0; x--) {                        reverseString = reverseString + mainString.charAt(x);   //використовуємо вбудований метод charAt(), щоб перевернути рядок            }            System.out.println(reverseString);             } } На екрані отримаємо: Введіть рядок, щоб отримати перевернутий: Введений рядок кодяр йинедевВ   Q # 3) Напишіть програму на Java для того, щоб поміняти місцями значення, що зберігаються у двох змінних за допомогою третьої змінної   Відповідь: У цьому прикладі ми створюємо об'єкт класу Scanner для роботи зі стандартним потоком даних System.in. Ця програма прийматиме значення a та b через командний рядок. Ми використали nextInt(), який буде поміщати введені користувачем значення цілочисельних змінних в a і b. Також оголошуємо тимчасову змінну. Тепер логіка програми виглядає наступним чином: ми створюємо тимчасову або третю змінну з ім'ям temp, присвоюємо їй значення, що зберігається в змінній a, а потім присвоюємо значення b, і знову присвоюємо b значення temp. Таким чином, після виконання всіх операцій temp буде зберігати в собі значення a, a отримає значення b, а b матиме значення temp (яке дорівнює a).   import java.util.Scanner; public class ThirdTask {             public static void main(String[] args) {            // ITVDN.com 3 з ТОП 20 тестових задач на інтерв’ю для Java розробника            int a, b, temp;            System.out.println("Введіть значення a та b");            Scanner scannerQ = new Scanner(System.in);            a = scannerQ.nextInt();            b = scannerQ.nextInt();            System.out.println("До обміну значеннями " + a + b);            temp = a;            a = b;            b = temp;            System.out.println("Після обміну значеннями " + a + b);                          } }   На екрані отримаємо: Введіть значення a і b 23 45 До обміну значеннями 2345 Після обміну значеннями 4523   Q # 4) Напишіть програму на Java, щоб змінити місцями значення, що зберігаються у двох змінних, без використання третьої змінної.   Відповідь: Спочатку все буде так само, як і в наведеному вище прикладі. Лише подальша логіка зміниться. Тут ми спочатку присвоюємо змінній a значення a + b, что означає, що a буде тепер мати в собі значення як a, так і b. Потім ми присвоюємо змінній b значення a - b, що означає, що ми віднімаємо значення b із суми (a + b). Досі a все ще зберігає у собі суму початкових a і b. Але b має тепер значення первісного a. Нарешті, на третьому кроці ми присвоюємо a значення a - b, що означає, що ми віднімаємо значення змінної b (яка зараз вже має в собі значення a) із суми (a + b). В результаті цих дій ми змінили місцями значення, які зберігаються у змінних.   import java.util.Scanner; public class FourthTask {    public static void main(String args[])    {             int a, b;             System.out.println("Введіть потрібні значення a та b");             Scanner scannerQ = new Scanner(System.in);             a = scannerQ.nextInt();             b = scannerQ.nextInt();             System.out.println("До обміну значеннями\na = "+a+"\nb = "+b);             a = a + b;             b = a - b;             a = a - b;             System.out.println("Після обміну значеннями без проміжної змінної\na = "+a+"\nb = "+b);    } }   На екрані отримаємо: Введіть потрібні значення a та b 23 45 До обміну значеннями a = 23 b = 45 Після обміну значеннями без проміжної змінної a = 45 b = 23   Q # 5) Напишіть програму Java для підрахунку кількості конкретних слів у рядку, використовуючи HashMap.   Відповідь: Ця програма працює з класом-колекцією, в якій ми використовували HashMap для зберігання рядка. Насамперед, ми оголосили нашу рядкову змінну з іменем st. Потім ми використовували функцію split() з одиночним пробілом, щоб можна було розбити рядок на масив з декількох слів. Після цього ми створили екземпляр HashMap та цикл for. Всередині циклу for ми використовуємо оператор if else. Ми заходимо до кожного елементу масиву split та додаємо елементи цього масиву. Слова ми додаємо як ключі екземпляру HashMap. У якості значень HashMap ми будемо додавати те число, скільки разів при обході масиву слів нам це слово зустрілося. Якщо в наш екземпляр HashMap ми вже додали дане слово – при обході ми збільшимо значення, записане в HashMap відповідно до даного слова-ключа. Щоразу, коли слово буде зустрічатися повторно (ми бачимо, що слово в екземпляр HashMap ми вже додавали) – значення-лічильник збільшується на 1. Якщо таке слово раніше не зустрічалося – значення-лічильник встановлюється на 1. Зрештою, ми виводимо на екран HashMap. Зверніть увагу: ту ж програму можна використовувати і для підрахунку кількості символів у рядку. Все, що вам потрібно зробити, це видалити один пробіл (видалити пробіл, вказаний в методі split) і прописати String [] words = st.split (“”); import java.util.HashMap; public class FifthTask{             public static void main(String[] args) {            // ITVDN.com 5 з ТОП 20 тестових завдань на інтерв’ю для Java розробника            String st = "Current task posted for Java developers developers";            String[] words = st.split(" ");            HashMap<String,Integer> keyValue = new HashMap<String,Integer>();            for (int i=0; i<= words.length-1; i++) {                         if (keyValue.containsKey(words[i])) {                                     int counter = keyValue.get(words[i]);                                     keyValue.put(words[i], counter+1);                         }                         else {                                     keyValue.put(words[i], 1);                         }            }            System.out.println(keyValue);             } } На екрані отримаємо: {Java=1, task=1, developers=2, for=1, Current=1, posted=1}   Q # 6) Напишіть Java-програму для ітерації об'єкта типу HashMap з використанням циклу while та покращеного циклу for.   Відповідь: Тут ми спочатку вставили три елементи в змінну типу HashMap з ім'ям keyValue, використовуючи функцію put(). Розмір змінної keyValue можна одержати за допомогою методу size(). Після цього ми використовували цикл While для обходу keyValue, яка містить по одній парі ключ-значення для кожного елемента. Ключі та значення можуть бути отримані за допомогою методів getKey() та getValue(). Аналогічно ми використовуємо розширений цикл for, на елементах «qurentMe2» у HashMap. import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class SixthTask{             public static void main(String[] args) {            // ITVDN.com ТОП 20 тестових завдань на інтерв’ю для Java розробника            HashMap<Integer,String> keyValue = new HashMap<Integer,String>();            keyValue.put(1, "Hello");            keyValue.put(2, "World");            keyValue.put(3, "Have a nice day!");            System.out.println(keyValue.size());            System.out.println("Цикл While:");            Iterator iter = keyValue.entrySet().iterator();            while(iter.hasNext()) {                         Map.Entry qurentMe = (Map.Entry) iter.next();                         System.out.println("Ключ это " + qurentMe.getKey() + " Значення це " + qurentMe.getValue());            }            System.out.println("Цикл For:");            for(Map.Entry qurentMe2: keyValue.entrySet()) {                         System.out.println("Ключ це: " + qurentMe2.getKey() + " Значення це: " + qurentMe2.getValue());            }             } } На екрані отримаємо: 3 Цикл While: Ключ це 1 Значення це Hello Ключ це 2 Значення це World Ключ це 3 Значення це Have a nice day! Цикл For: Ключ це: 1 Значення це: Hello Ключ це: 2 Значення це: World Ключ це: 3 Значення це: Have a nice day!    Q # 7) Напишіть програму на Java, щоб дізнатися, чи є число простим, чи ні.   Відповідь: Ми оголосили дві цілочисельні змінні temp та number і використали клас Scanner з nextInt (оскільки у нас може бути на розгляді тільки ціле число). Оголошуємо логічну змінну numberIsPrime і встановлюємо її значення – true. Після цього ми використовуємо цикл for зі значенням змінної ітератора, що починається з 2. Кількість ітерацій, необхідне нам, дорівнюватиме половині введеного числа. Лічильник ітерацій збільшується на 1 після кожної ітерації. У змінну tempNumber ми поміщуватимемо залишок від поділу значення введеного числа на значення лічильника. Якщо залишок від поділу в одній з ітерацій дорівнюватиме 0, тоді numberIsPrime буде встановлений у false, введене число не буде простим, і ми виходимо з циклу. Якщо у всіх ітераціях ми отримуватимемо в temp деякі залишки від розподілу, відмінні від нуля – число буде простим. Ґрунтуючись на значенні numberIsPrime, ми приходимо до висновку, чи є наше число простим, чи ні. import java.util.Scanner; public class SeventhTask {             public static void main(String[] args) {            // ITVDN.com ТОП 20 тестових завдань на інтерв’ю для Java розробника            int temp, number;            boolean numberIsPrime = true;            Scanner scannerQ = new Scanner(System.in);            number = scannerQ.nextInt();            scannerQ.close();            for (int x = 2; x<= number /2; x++) {                         tempNumber = number %x;                                     if (tempNumber == 0) {                                     numberIsPrime = false;                                     break;                         }            }            if(numberIsPrime)                         System.out.println(number + " число є простим");                         else                                     System.out.println(number + " число не є простим");                      } } На екрані отримаємо: 27 27 число не є простим   Q # 8) Напишіть Java-програму, щоб визначити, чи є рядок або число паліндромом, чи ні.   Відповідь: Щоб перевірити, чи є число або рядок паліндромом, чи ні, ви можете використовувати будь-яку програму, що перевертає рядки, з описаних вище. Що вам потрібно зробити, то це додати один оператор if-else. Якщо вихідний рядок дорівнює перевернутому рядку, то число є паліндромом, інакше – ні. import java.util.Scanner; public class EighthTask{             public static void main (String[] args) {            // ITVDN.com ТОП 20 тестових завдань на інтерв’ю для Java розробника            String inputString, reversedString = "";            Scanner scannerQ = new Scanner(System.in);            int stringLength;            System.out.println("Введіть число або рядок");             inputString = scannerQ.nextLine();            stringLength = inputString.length();            for (int x = stringLength -1; x>=0; x--) {                         reversedString = reversedString + inputString.charAt(x);            }            System.out.println("перевернутое значение: " + reversedString);                         if(inputString.equals(reversedString))                         System.out.println("Введене значення є паліндромом");            else                         System.out.println("Введене значення не є паліндромом");                          } } На екрані отримаємо: Для рядка- Введіть число або рядок dfggg перевернуте значення: gggfd Введене значення не є паліндромом Для числа- Введіть число або рядок 777 перевернуте значення: 777 Введене значення є паліндромом   Q # 9) Написати програму Java для обчислення серії чисел Фібоначчі.   Відповідь: Ряд Фібоначчі - це така серія чисел, де після перших двох чисел кожне число, яке зустрічається, є сумою двох попередніх чисел. Приклад: 0,1,1,2,3,5,8,13,21 ……… У цій програмі ми знову використали клас Scanner з nextInt (описувалося вище). Спочатку ми вводимо (через командний рядок) деяке число, яку кількість чисел Фібоначчі ми повинні отримати. Ми оголосили цілочисленні змінні number, x, y та z, ініціалізували x та y нулем, а z – одиницею. Потім ми використовували цикл for для ітерації. Процес рішення в циклі виглядає так – ми присвоюємо x значення, рівне y (яке в першій ітерації дорівнює 0), потім y присвоюємо значення змінної z (рівне у першій ітерації 1). Потім змінної z привласнюємо значення, що дорівнює сумі значень x та y. import java.util.Scanner; public class NinthTask{             public static void main(String[] args) {            // ITVDN.com 9 з ТОП 20 тестових завдань на інтерв’ю для Java розробника            int number, x = 0, y=0, z =1;            Scanner scannerQ = new Scanner(System.in);            System.out.println("Введіть кількість значень");            number = scannerQ.nextInt();            System.out.println("Серія чисел Фібоначчі: ");            for (int i=0; i<= number; i++) {                         x = y;                         y = z;                         z = x+y;                         System.out.println(x + "");       // якщо ви хочете вивести в поточному рядку – використовуйте print()            }                          } } На екрані отримаємо: Введіть кількість значень 10 Серія чисел Фібоначчі: 0 1 1 2 3 5 8 13 21 34 55   Q # 10) Напишіть Java-програму для обходу ArrayList з використанням циклу for, while та покращеного циклу for.   Відповідь: У цій програмі ми додали три елементи до ArrayList і вивели його розмір. Потім ми використовуємо цикл While з ітератором. Щоразу, коли ітератор отримує наступний елемент, він буде відображати цей елемент, доки ми не досягнемо кінця списку. У нашому випадку це повторюватиметься тричі. Аналогічно ми зробили для покращеного циклу for, де ми створили об'єкт o для ArrayList з ім'ям testList. Потім вивели на екран значення об'єкта. Після цього ми створили цикл for, де ітератор i встановлено спочатку на індекс 0, а потім збільшується на 1 при кожній ітерації, поки не буде досягнута межа ArrayList. Нарешті, ми виводимо на екран кожен елемент, використовуючи метод get(index) для кожної ітерації циклу for. import java.util.*; public class arrayList {             public static void main(String[] args) {            // ITVDN.com 10 з ТОП 20 тестових завдань на інтерв’ю для Java розробника            ArrayList testList = new ArrayList();            testList.add("50");            testList.add("60");            testList.add("70");            System.out.println(testList.size());            System.out.println("Цикл While:");            Iterator iter = testList.iterator();            while(iter.hasNext()) {                         System.out.println(iter.next());            }            System.out.println("Покращений цикл For:");            for(Object o : testList) {                         System.out.println(o);             }            System.out.println("Цикл For:");            for(int i=0; i< testList.size(); i++) {                         System.out.println(testList.get(i));            } } } На екрані отримаємо: 3 Цикл While: 50 60 70 Покращений цикл For: 50 60 70 Цикл For: 50 60 70   Q # 11) Напишіть програму Java, щоб продемонструвати явну перевірку умов очікування.   Відповідь: У Selenium є два основні типи очікування – неявне (Implicit Wait) і явне (Explicit Wait). (Ми не розглядаємо явне (вільне) очікування у цьому прикладі). Неявне очікування – оголошується один раз у коді поза операцією пошуку та діє до зміни. Це очікування виконується незалежно від будь-якої умови і застосовується до всіх наступних операцій пошуку неявно. У наведеній нижче програмі ви можете бачити застосування такого очікування для Google Chrome. Ми використовували кілька вбудованих методів для встановлення властивості, максимізації вікна, навігації по URL та пошуку веб-елементів. WebDriverWait waitWD = new WebDriverWait(curentDriver, 20); WebElement secondElement = waitWD.until(ExpectedConditions.visibilityOfElementLocated(By.partialLinkText("Тестування програмного забезпечення - Вікіпедія"))); secondElement.click(); У наведеному вище фрагменті коду можна побачити, що ми створили об'єкт waitWD для WebDriverWait, а потім ми здійснили пошук WebElement з ім'ям secondElement. Умову встановлено таким чином, що веб-драйверу доведеться чекати, поки ми не побачимо посилання «Тестування програмного забезпечення – Вікіпедія» на веб-сторінці. Команда не виконається, якщо не знайде це посилання. Якщо посилання буде знайдено, веб-драйвер виконає клацання мишею за цим посиланням. package Codes; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class EleventhTask{             public static void main(String[] args) {                         // ITVDN.com 11 з ТОП 20 тестових завдань на інтерв’ю для Java розробника                         System.setProperty("webdriver.chrome.driver", "C:\\driver\\chromedriver.exe");                         ChromeOptions cOptions = new ChromeOptions();                         cOptions.addArguments("--disable-arguments");                         WebDriver curentDriver = new ChromeDriver();                         curentDriver.manage().window().maximize();                         curentDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);                         curentDriver.navigate().to("https://www.google.com.ua");                         WebElement curentElement = curentDriver.findElement(By.name("q"));                         curentElement.sendKeys("Testing");                         curentElement.submit();                         WebDriverWait waitWD = new WebDriverWait(curentDriver, 20);                      WebElement secondElement = waitWD.until(ExpectedConditions.visibilityOfElementLocated(By.partialLinkText("Тестування програмного забезпечення – Вікіпедія"))); secondElement.click(); } }   Q # 12) Напишіть програму на Java для демонстрації прокручування вгору/вниз.   Відповідь: Усі рядки кодів легко співвідносяться з кодом попереднього прикладу. У код цієї програми ми включили JavascriptExecutor jscript, який виконуватиме прокручування. На останньому рядку коду ми передаємо window.scrollBy(argument1, argument2). Якщо нам потрібно виконати прокручування вгору, тоді передаємо деяке значення в argument1, якщо нам потрібно прокрутити вниз – передаємо деяке значення в argument2.   package Codes; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; public class TwelfthTask{             public static void main(String[] args) {                         // ITVDN.com 12 з ТОП 20 тестових завдань на інтерв’ю для Java розробника                         System.setProperty("webdriver.chrome.driver", "C:\\driver\\chromedriver.exe");                         WebDriver qurentDriver = new ChromeDriver();                         JavascriptExecutor jscript = (JavascriptExecutor) qurentDriver;                         qurentDriver.manage().window().maximize();                         qurentDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);                         qurentDriver.get("https://www.google.com.ua");                         WebElement qurentElement = qurentDriver.findElement(By.name("q"));                         qurentElement.sendKeys("SoftwareTestingHelp");                         qurentElement.sendKeys(Keys.ENTER);                         jscript.executeScript("window.scrollBy(0,900)"); } }   Q # 13) Напишіть програму на Java, щоб відкрити всі посилання на gmail.com.   Відповідь: Це типовий приклад застосування покращеного циклу for, який ми бачили у наших попередніх прикладах. Після того, як ви відкрили веб-сайт, такий як Gmail, використовуючи get() або navigate().to(), ви можете використовувати локатор tagName, щоб отримати всі посилання на веб-сайті, які мають однакові теги. У нас є покращений цикл for, в якому ми обходимо всі знайдені посилання за нашим тегом. Для кожного посилання типу WebElement у нашому листі посилань ми отримуємо самі посилання через getAttribute(«href») і тексти через getText(). package Codes; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class ThirteenthTask{             public static void main(String[] args) {             // ITVDN.com 13 з ТОП 20 тестових завдань на інтерв’ю для Java розробника             System.setProperty("webdriver.chrome.drive", "C:\\driver\\chromedriver.exe");             WebDriver curentDriver = new ChromeDriver();             curentDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);             curentDriver.manage().window().maximize();             curentDriver.get("https://www.gmail.com/");             java.util.List<WebElement> linkList = curentDriver.findElements(By.tagName("a"));             System.out.println(linkList.size());             for (WebElement thisLink: linkList) {             //виводимо на екран посилання http://google.com або https://www.gmail.com             System.out.println(qurentLink.getAttribute("href"));             //виводимо на екран текст посилання             System.out.println(qurentLink.getText()); } } } На екрані отримаємо: Starting ChromeDriver 2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed) on port 16163 Only local connections are allowed. 3 https://support.google.com/accounts?hl=ru Довідка https://policies.google.com/privacy?gl=IN&hl=ru Політика конфіденційності https://policies.google.com/terms?gl=IN&hl=ru Умови використання   Q # 14) Напишіть код для Selenium, щоб перейти на попередню вкладку.   Відповідь: Ми використовуємо клас Robot. Цей приклад досить важливий, тому що, якщо ви знаєте поєднання клавіш, ви можете використовувати різну навігацію в браузері та його вкладках. Наприклад, якщо у вас у Chrome відкрито три вкладки, і ви хочете перейти на середню вкладку, то вам потрібно натиснути + 2 на клавіатурі. Те саме можна досягти за допомогою коду. Використовуйте наступний код (відразу після того, як ми побачимо створення екземпляру класу Robot). Ми використовували об'єкт qurentRobot класу Robot, з двома вбудованими методами keyPress(KeyEvent.VK_*) та keyRelease(KeyEvent.VK_*). package Codes; import java.awt.AWTException; import java.awt.Robot; import java.awt.event.KeyEvent; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class FourteenthTask{             public static void main(String[] args) throws AWTException {            // ITVDN.com 14 з ТОП 20 тестових завдань на інтерв’ю для Java розробника             System.setProperty("webdriver.chrome.driver", "C:\\driver\\chromedriver.exe");             WebDriver curentDriver = new ChromeDriver();             curentDriver.manage().window().maximize();             curentDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);             curentDriver.get("https://www.google.com");             WebElement firstElement = curentDriver.findElement(By.name("q"));             firstElement.sendKeys("software testing help");             firstElement.sendKeys(Keys.ENTER);             String str = Keys.chord(Keys.CONTROL,Keys.RETURN);              curentDriver.findElement(By.partialLinkText("Software Testing Help - A Must Visit Software Testing Portal")).sendKeys(str);             Robot qurentRobot = new Robot(); // Ініціалізуємо екземпляр класу Robot              qurentRobot.keyPress(KeyEvent.VK_CONTROL); // застосовуючи клас Robot ви легко можете отримати необхідний результат, якщо ви знаєте потрібні комбінації кнопок             qurentRobot.keyPress(KeyEvent.VK_2); // тут ми натискаємо ctrl+2              qurentRobot.keyRelease(KeyEvent.VK_CONTROL); // як тільки ми натиснемо та відпустимо ctrl+2, ми перейдемо на другу вкладку.             qurentRobot.keyRelease(KeyEvent.VK_2); //якщо ви хочете знову повернутися до першої вкладки, натисніть і відпустіть vk_1             } }   Q # 15) Напишіть програму на Java, щоб знайти повторювані символи в рядку.   Відповідь: У цій програмі ми створюємо рядкову змінну st та ініціалізуємо цілочисельний лічильник, починаючи з нуля. Потім ми створили масив символів для перетворення нашої рядкової змінної на цей масив. За допомогою двох циклів for ми проводимо порівняння символів із різними індексами. Якщо два символи послідовного індексу збігаються, цей символ буде виведений на екран і лічильник кількості символів, що збігаються, збільшиться на 1.  public class FifteenTask{             public static void main(String[] args) {                         // ITVDN.com 15 з ТОП 20 тестових завдань на інтерв’ю для Java розробника                         String st = new String("Hello");                         int counter = 0;                         char[] charsArray = st.toCharArray();                         System.out.println("Повторювані символи тут:");                         for (int i=0; i<st.length();i++) {                                     for(int j=i+1; j<st.length();j++) {                                                 if (charsArray [i] == charsArray [j]) {                                                            System.out.println(charsArray [j]);                                                            counter ++;                                                      break;                                                }                                     }                         }             } } На екрані отримаємо: Повторювані символи тут: l   Q # 16) Напишіть Java-програму, щоб знайти друге за величиною число в масиві.   Відповідь: У цій програмі ми ініціалізували масив із 10 випадковими елементами, з яких ми збираємося знайти друге за величиною число. Далі ми створили дві цілочисельні змінні, яким присвоюватимемо значення двох цілих чисел з масиву – найбільшого і другого за величиною. Обидві змінні спочатку набувають значення першого за індексом елемента масиву. Потім ми виводимо на екран усі елементи, використовуючи цикл for. Подальша логіка роботи програми полягає в тому, щоб використовувати цикл for для обходу масиву. При обході, якщо елемент масива з поточним індексом більше, ніж значення, що зберігається в змінній biggest, тоді змінній secondBiggest присвоюємо значення, що зберігається в biggest, а змінній biggest – нове найбільше значення відповідно до значення поточного елемента масиву. Знову ж таки, якщо елемент за поточним індексом більше, ніж secondBiggest, то привласність secondBiggest значення цього елементу. Це буде повторюватися для кожної ітерації і, зрештою, після завершення обходу масиву в циклі ви отримаєте елементи – найбільший і другий за величиною елементи масиву в змінних biggest і secondBiggest відповідно.   public class SixteenthTask { public static void main(String[] args)             {             // ITVDN.com 16 з ТОП 20 тестових завдань на інтерв’ю для Java розробника             int numbersArray[] = { 10, 15, 32, 100, 16, 11, 98, 36, 95, 33 };             int biggest= numbersArray[0];             int secondBiggest = numbersArray[0];             System.out.println("Отриманий масив: ");             for (int i = 0; i < numbersArray.length; i++)             {             System.out.print(numbersArray[i] + "\t");             }             for (int i = 0; i < numbersArray.length; i++)             {             if (numbersArray[i] > biggest)             {                         secondBiggest = biggest;                         biggest = numbersArray[i];             }             else if (numbersArray[i] > secondBiggest && numbersArray[i] != biggest)             {                         secondBiggest = numbersArray[i];             }             }             System.out.println("\nДруге за величиною число:" + secondBiggest);             } }   На екрані отримаємо: Отриманий масив: 10        15        32        100      16        11        98        36        95        33        Друге за величиною число: 98   Q # 17) Напишіть Java-програму для перевірки, чи введене число є числом Армстронга.   Відповідь: Насамперед, нам потрібно зрозуміти, що таке число Армстронга. Число Армстронга – це число, значення якого дорівнює сумі цифр, з яких воно складається, зведених у ступінь, що дорівнює кількості цифр у цьому числі. Як приклад – число 371: 371 = 3 * 3 * 3 + 7 * 7 * 7 + 1 * 1 * 1 = 27 + 343 + 1 = 371 Якщо у вас число чотиризначне: 8208 = 8 * 8 * 8 * 8 + 2 * 2 * 2 * 2 + 0 * 0 * 0 * 0 + 8 * 8 * 8 * 8 = 4096 + 16 + 0 + 4096 = 8208 Виконуючи рішення, спочатку ми оголошуємо цілочисленні змінні tempNumber, x і y. Ми ініціалізували змінну y значенням 0. Потім ми створюємо змінну qurentNumber і присвоюємо їй ціле значення, яке ми збираємося перевірити, чи є воно числом Армстронга (у нашому випадку це 371). Потім ми надали нашій змінній tempNumber те значення, яке зберігається в перевіреній змінній qurentNumber. Далі в циклі while ми змінній a привласнюємо залишок від ділення числа qurentNumber на 10 – і отримаємо число одиниць у початковому числі qurentNumber. Потім ми замінюємо значення змінної qurentNumber на результат діленого введеного числа на 10. Нашій змінній y, значення якої спочатку було встановлено як 0, присвоюється результат y + (x * x * x). Таким чином під час першої ітерації до y потрапить результат зведення в потрібний ступінь значення числа одиниць у початковому числі, при наступній ітерації до y до ступеня числа одиниць додасться результат зведення в ступінь числа десятків, і так далі по всіх розрядах до кінця числа qurentNumber з права на ліво. Нарешті, ми використовуємо оператор if-else для перевірки, чи буде отримане значення змінної y дорівнювати значення змінної tempNumber (у якій зберігається вихідне число). Якщо y = tempNumber, то загадане число є числом Армстронга, інакше – ні.   public class SeventeenthTask{  public static void main(String[] args)  {             // ITVDN.com 17 з ТОП 20 тестових завдань на інтерв’ю для Java розробника             int y=0, x, tempNumber;             int qurentNumber=371; //Дане число ми перевірятимемо на те, чи є воно числом Армстронга             tempNumber = qurentNumber;             while(qurentNumber >0)             {             x= qurentNumber %10;             qurentNumber = qurentNumber /10;              y=y+(x*x*x);                         }                         if(tempNumber ==y)                         System.out.println("Дане число є числом Армстронга");                          else                         System.out.println("Дане число не є числом Армстронга");     } } На екрані отримаємо: Дане число є числом Армстронга   Q # 18) Напишіть Java-програму для видалення всіх пробілів з рядка за допомогою replace().   Відповідь: Це проста програма, в якій ми маємо рядкову змінну st1. Інша рядкова змінна st2 ініціалізується за допомогою методу replaceAll, який є вбудованим методом для видалення n числа пробілів. У результаті ми виводимо на екран st2, яка вже не містить пробілів. public class EighteenthTask {             public static void main(String[] args)             {             // ITVDN.com 18 з ТОП 20 тестових завдань на інтерв’ю для Java розробника             String st1 = "Ми готуємось   до інтерв’ю   на вакансію     Java розробника";             //Використовуємо метод replaceAll()             String st2 = st1.replaceAll("\\s", "");             System.out.println(st2);             } } На екрані отримаємо: Миготуємосядоінтерв'юнавакансіюJavaрозробника   Q # 19) Напишіть Java-програму для видалення всіх пробілів з рядка без використання replace().   Відповідь: Це ще один підхід до видалення всіх пробілів. Знову ж таки, для початку у нас є одна рядкова змінна st1 з деяким значенням. Ми перетворюємо цей рядок на масив символів, використовуючи toCharArray(). Потім ми маємо один об'єкт StringBuffer strB, який буде використовуватися для додавання значення, що зберігається за індексом chars [i] після того, як ми додали цикл і одну умову if. Умову встановлено так, що елемент з індексом i масиву символів не повинен дорівнювати символу пробілу або табуляції. Зрештою, ми виводимо на екран наш об'єкт StringBuffer strB. public class NineteenthTask {             public static void main(String[] args)             {                         // ITVDN.com 19 з ТОП 20 тестових завдань на інтерв’ю для Java розробника             String st1 = " Ми готуємось  до інтерв’ю   на вакансію     Java розробника";             char[] charsArray = st1.toCharArray();             StringBuffer strB = new StringBuffer();             for (int i = 0; i < charsArray.length; i++)             {             if( (charsArray[i] != ' ') && (charsArray [i] != '\t') )             {                         strB.append(charsArray [i]);             }             }             System.out.println(strB);                      } } На екрані отримаємо: Миготуємосядоінтерв'юнавакансіюJavaрозробника   Q # 20) Напишіть Java-програму для читання даних із таблиці Excel.   Відповідь: Ці типи програм зазвичай використовують у рамках Selenium framework. Ми додали докладні коментарі для кожного кроку, щоб зробити програму більш зрозумілою. Логіка починається з того моменту, як ми завантажили лист, на якому зберігаються дані. Ми намагаємося імпортувати електронну пошту та пароль. Для цього ми виймаємо комірку за допомогою методів getRow() та getCell(). Припустимо, у нас є електронна пошта та паролі в 1-й та 2-й комірці. Далі ми встановлюємо тип комірки – рядкова. Після цього ми виконуємо звичайну операцію локатора веб-елемента (By.id), куди ми передали унікальні значення локатора, такі як "email" та "пароль", які ідентифікуватимуть ці елементи. Нарешті, ми надсилаємо ключі, використовуючи element.sendKeys, де cell.getStringCellValue() – це ключ. Ця операція поверне вам значення, збережене в комірках № 1 і 2 відповідно. @Test  public void ReadData() throws IOException  {            // Імпортуйте лист Excel з директорії web диску c.              //QurentSourceFile – це ім’я потрібного файлу excel              File sourceFile=new File("C:\\web\\QurentSourceFile.xls");              // На цьому кроці ми завантажуємо файл. Ми використовуємо FileInputStream для читання з // файлу Excel. Якщо ви хочете проводити запис у файл – // ви повинні використовувати FileOutputStream. Шлях до файлу передається // в якості аргументу FileInputStream              FileInputStream fileInput = new FileInputStream(sourceFile);                          // На цьому кроці ми завантажуємо робочу книгу Excel             // за допомогою HSSFWorkbook,             // в який ми передаємо fileInput в якості аргументу             HSSFWorkbook book = HSSFWorkbook(fileInput);             // На цьому кроці ми завантажуємо конкретний лист excel,             // на якому зберігаються дані.             qurentSheet= book.getSheetAt(0);              for(int i=1; i<= qurentSheet.getLastRowNum(); i++)              {             // Import data for Email.             qurentCell = qurentSheet.getRow(i).getCell(1);             qurentCell.setCellType(Cell.CELL_TYPE_STRING);                          driver.findElement(By.id("email")).sendKeys(qurenrCell.getStringCellValue());             // Імпортуємо дані з комірок з паролями             qurentCell = qurentSheet.getRow(i).getCell(2);             qurentCell.setCellType(Cell.CELL_TYPE_STRING);             driver.findElement(By.id("password")).sendKeys(qurenrCell.getStringCellValue());             }   } Резюме У цій статті ми розглянули найпоширеніші тестові завдання для розробників Java з прикладами коду. Ці завдання застосовуються на більшості технічних інтерв'ю Java розробників. Ми розглянули такі прийоми роботи з даними за допомогою Java, як базові маніпуляції з рядками, цілими числами та символами, використання Selenium, читання даних із файлу. Теперь у вас є достатньо інформації про те, як проходити технічний етап інтерв'ю на вакансію Java розробника. Звичайно, вам потрібні будуть інші навички. Вивчення напам'ять рішень 20 завдань може бути головним способом підготуватися до інтерв'ю. Вам слід мати гарний набір теоретичних знань та практичних навичок. З нашого боку портал ITVDN.com готовий запропонувати програму підготовки Java розробника, що включає відео курси як із Java, так і за супутніми технологіями. Також рекомендуємо вам ознайомитись із серією відео «Підготовка до співбесіди в IT компанії. Питання та відповіді. Хитрощі. Трюки» За матеріалами статті.
Notification success