Хабрахабр

Зачем учить Java и как делать это эффективно. Доклад Яндекса

Чем Java отличается от других популярных языков? Почему именно Java может быть первым языком для изучения? Давайте составим план, который поможет выучить Java как с нуля, так и с применением навыков программирования на других языках. Перечислим отличия между созданием продакшен-кода на Java и разработкой на других языках. Михаил Затепякин прочитал этот доклад на встрече для будущих участников стажировки Яндекса и других начинающих разработчиков — Java Junior meetup.

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

Разрабатывал бэкенд для «Беру», для самого Маркета, вы наверняка им пользовались. Год назад я попал на стажировку в Яндекс.Маркет. Мы делаем аналитическую платформу Яндекс.Маркета для бизнес-партнеров. Сейчас продолжаю там работать, в другой команде.

Зачем учить Java с практической точки зрения? Давайте приступим. У него очень большое комьюнити. Дело в том, что Java — это очень известный язык программирования.

Также на сайтах с вакансиями вы наверняка заметите, что большинство вакансий — как раз таки про Java, то есть разрабатывая на Java, вы всегда сможете найти себе работу. Например, есть такой TIOBE-индекс, популярный индекс популярности языков программирования, и Java там занимает первое место.

А еще, разрабатывая на Java, вы, на самом деле, пишете код по JVM, поэтому сможете легко пересесть на Kotlin, Scala и другие языки, использующие JVM. Поскольку комьюнити очень большое, на любой ваш вопрос найдется ответ на каком-нибудь Stack Overflow или других сайтах.

Есть разные языки программирования. Чем хороша Java с идеологической точки зрения? Например, на Python очень здорово писать однострочные скрипты для решения быстрых задач. Они решают разные задачи, вы это знаете.

Например, у нас ездят машинки, беспилотные автомобили Яндекса, их код написан на плюсах. На плюсах можно полностью контролировать исполняемый код. У Java есть такая штука — Garbage Collector. Почему? Эта штука запускается спонтанно и делает stop-the-world, то есть останавливает всю остальную программу и идет считать объекты, очищать память от объектов. Она очищает оперативную память от ненужных объектов. Ваш беспилотник будет ехать прямо, в этот момент очищать память и никак не смотреть на дорогу. Если такая штука будет работать в беспилотнике, это не круто. Поэтому беспилотник написан на плюсах.

Это в первую очередь язык для разработки больших программ, которые пишутся годами, десятками или сотнями людей. Какие задачи решает Java? У нас распределенная команда в нескольких городах, по десять человек в каждом. В частности, много бэкенда в Яндекс.Маркете написано на Java. И код легко поддерживать, он поддерживается уже десять и более лет, и при этом приходят новые люди, разбираются в этом коде.

Это в первую очередь должен быть читаемый код, и на нем должно быть легко реализовывать сложные архитектурные решения. Какими характеристиками должен обладать язык, чтобы код на нем был легко поддерживаемый и чтобы его легко было разрабатывать в больших командах. д. То есть на нем должно быть легко писать высокоуровневые абстракции и т. Это объектно-ориентированный язык. Все это как раз и предоставляет нам Java. На нем действительно просто реализовывать высокоуровневые абстракции и сложные архитектуры.

За это время на нем было написано все, что могло быть написано, поэтому есть куча библиотек для всего, что может вам пригодиться. Также существует очень много фреймворков и библиотек для Java, потому что языку уже больше 15 лет.

В первую очередь, это знание языка Java core. Какими основными скиллами, на мой взгляд, должен обладать начинающий джавист? Про это более полно будет рассказывать следующий докладчик Кирилл. Далее это какой-нибудь Dependency Injection фреймворк. Далее это архитектура и паттерны проектирования. Я особо углубляться не буду. И это какой-нибудь SQL или ORM для задач работы с базой. Нам нужно уметь писать архитектурно красивый код, чтобы писать большие приложения. И это больше касается бэкенда.

Java core. Поехали! На что стоит обратить внимание. Тут я особо Америку не открою — нужно знать сам язык. д. Во-первых, Java вышло очень много версий за последние годы, то есть в 2014-2015 году вышла седьмая, потом восьмая, девятая, десятая, очень много новых версий, и в них вводили очень много новых крутых штук, например, Java Stream API, лямбда и т. Поэтому не стоит брать книгу с полки в библиотеке Java-4 и идти ее учить. Очень клевые свежие крутые штуки, которые используются в production-коде, о чем спрашивают на собеседованиях и которые нужно знать. Такой себе план: учим Java-8 или выше.

д. Внимательно обращаем внимание на нововведения, такие как Stream API, var, и т. То есть в Stream API сильно круче циклов, вообще, очень крутая штука. Их спрашивают на собеседованиях, постоянно используют в production. Обратите внимание обязательно.

То, что кажется вам неважным, пока вы пишете какой-то маленький код сами. И есть еще всякие штуки вроде итераторов, Exceptions и так далее. Но их точно будут спрашивать на собеседованиях, они точно вам пригодятся в продакшене. Вам не нужны эти Exceptions, кому они вообще нужны? В общем, стоит обратить внимание на Exceptions, итераторы и прочие штуки.

Без структур никуда, при этом будет здорово, если вы будете не просто знать, что бывают set, dictionary, листы. Структуры данных. Например, у той же dictionary в Java много реализаций, в том числе HashMap и TreeMap. А еще разные реализации структур. Нужно знать, чем они отличаются, когда какую использовать. У них разные асимптотики, они по-разному устроены внутри.

То есть не просто знать их асимптотики — за сколько работает ставка, за сколько работает проход, а как работает структура внутри — например, что такое бакет в HashMap. Также очень здорово будет, если вы будет знать, как работают эти структуры данных внутри.

Это такие штуки, которых не очень много в продакшен-коде, но их любят на собеседованиях. Также стоит обратить внимание на деревья и графы. Это все простенькие алгоритмы. Соответственно, нужно уметь обходить деревья, графы в ширину, глубину.

Это, в первую очередь Maven и Gradle. Как только вы начнете писать сколь-нибудь большой код, сложный, с использованием библиотек, многоклассовый код, вы поймете, что вам тяжко без систем сборки и resolve-зависимости. То есть вы пишете однострочный xml и импортируете в проект библиотеки. Они позволяют вам импортировать библиотеки в ваш проект реально в одну строчку. Они примерно одинаковые, используйте любую — Maven или Gradle. Отличные системы.

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

Я рекомендую IntelliJ Idea. И — какая-нибудь среда разработки. Она очень сильно ускоряет процесс разработки, сильно вам помогает, пишет за вас всякий boilerplate-код, в общем, клевая.

Ссылки со слайда: SQLZOO, хабрапост

SQL. Чуть-чуть про бэкендеров. Здесь, на самом деле, был забавный кейс. Мне за два дня до моего второго собеседования на стажировку позвонила девушка-HR и сказала, что меня через два дня будут спрашивать SQL и HTTP, нужно выучить. А я не знал ни про SQL, ни про HTTP примерно ничего. И я нашел такой клевый сайт — SQLZOO. На нем я выучил SQL часов за 12, в смысле, синтаксис SQL, как писать SELECT-запросы, JOIN и т. д. Очень клевый сайт, очень рекомендую. Реально за 12 часов выучил 90% того, что я знаю сейчас.

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

Есть некий код. В Java, кроме SQL, есть всякие Object-relational mapping-системы типа JPA. Из базы данных users, из таблицы, получают их айдишники, имена. В первом методе некий SQL-код — SELECT id name FROM info.users WHERE id IN userIds.

И есть ниже третий метод, который, собственно, выполняет этот код. Далее есть некий маппер, который превращает объект из базы в джавовый объект. Она делает все то же самое, — find All ByIdIn. Все это с помощью JPA можно заменить на одну строчку, которая написана ниже. То есть по названию метода он генерирует вам SQL-запрос.

Я сам, когда не знал SQL, использовал JPA. Очень клевая штука. Если лень учить SQL, — огонь. В общем, обратите внимание. И, вообще, огонь!

Кто слышал про такую штуку, как фреймворк Spring? Spring. Неспроста. Видите, как вас много? Без него реально никуда в большой разработке. Spring есть в требованиях каждой второй вакансии по бэкенду на Java. В первую очередь это Dependency Injection-фреймворк. Что такое Spring? Но если вкратце, это штука, которая позволяет вам облегчить импортирование зависимостей одних классов на другие. Про это тоже будет рассказывать следующий докладчик. То есть упрощается знание зависимостей.

Вы заходите на THID, нажимаете пару кнопок, и вот у вас на localhost 8080 уже поднято ваше серверное приложение. Spring Boot — такой кусок Spring, который позволяет вам поднимать свое серверное приложение одной кнопкой. Очень клевая штука. То есть вы еще ни строчки кода не написали, а оно уже работает. Если пишете что-то свое, — огонь!

Он не только поднимает вам серверное приложение и резолвит Dependency Injection. Spring — очень большой фреймворк. То есть вы написали какой-то метод, повесили на него аннотацию Get mapping. Он позволяет делать кучу всего, в том числе создавать REST API-методы. Две строчки кода, и работает. И вот у вас на localhost уже есть какой-то метод, который пишет вам Hello world. Крутая штука.

Без тестирования в большой разработке никак. Также Spring упрощает написание тестов. Для этого в Java есть клевая библиотека JUnit 5. Код нужно тестировать. Там есть все для тестирования, всякие assertions и прочие штуки. И вообще JUnit, но последняя версия пятая.

Представьте, что у вас есть некая функциональность, которую вы хотите протестировать. И есть офигенный фреймворк Mockito. Наверное, вы не будете в тестах входить «ВКонтакте», это странно. Функциональность делает много чего, в том числе, где-то в серединке она входит во «ВКонтакте» с вашим, например, айдишником, и получает по айдишнику имя и фамилию юзера «ВКонтакте». Но функциональность протестировать вам нужно, поэтому вы этот класс, с помощью Mockito, сделали его mok, его имитацию.

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

Ссылка со слайда

Паттерны проектирования. Что это такое? Это шаблоны для решения типичных проблем, возникающих в разработке. В разработке частенько возникают одинаковые, или схожие какие-то задачи, которые было бы здорово как-то хорошо решать. Поэтому люди придумали best practices, некие шаблоны, как решать эти проблемы.

Проблема в том, что это практически бесполезно. Есть веб-сайт с большинством популярных паттернов — refactoring.guru, можно почитать, узнать, какие бывают паттерны, прочитать кучу теории. Фактически паттерны без практики особой пользы не несут.

Кто слышал эти слова? Вы услышите про какие-нибудь паттерны типа Singletone или Builder. Есть такие простые паттерны, которые вы можете реализовать сами. Очень много людей. Но большинство паттернов: стратегия, фабрика, фасад — не понятно, где их применять.

Поэтому с паттернами очень важна практика. И пока вы не увидите на практике в каком-то чужом коде место, к которому применен этот паттерн, применять его самим не получится. И просто прочитать о них на refactoring.guru не супер полезно, но это обязательно нужно сделать.

Пусть у вас есть некий класс User. Зачем нужны паттерны? У каждого User обязательно должен быть и Id, и Name. У него есть Id и Name. Слева сверху — класс.

Два варианта — либо конструктор, либо setter. Какие есть способы инициализировать User? Какие есть минусы у обоих подходов?

new User (7, «Bond»), окей. Конструктор. У вас будет конструктор, в котором семь подряд идущих чисел. Теперь допустим, что у нас не класс User, а некий другой, с семью числовыми полями. Конструктор — это не здорово. Непонятно, что это за числа, какое из них к какому property относится.

Вы четко пишете: setId(7), setName(«Bond»). Второй вариант — setter. Но у setter есть проблема. Вы понимаете, какая property к какому полю относится. Это не потокобезопасно и чуть-чуть понижает читаемость кода. Во-первых, вы можете забыть засетить что-то, а во-вторых, ваш объект получается изменяемым. Поэтому люди придумали клевый паттерн — Builder.

Постараемся собрать плюсы обоих подходов — и setter, и конструктора — в одном. Про что это? У нас получается неизменяемый объект и setter. Делаем некий объект, Builder, у которого тоже будут поля Id и Name, который сам будет строиться на основе setter, и у которого будет метод Build, который возвращает вам нового User со всеми параметрами. Клево!

Вот у нас есть классический Builder. Какие есть проблемы? И если мы забыли засетить айдишник, в данном случае в Builder он проинициализируется нулем, потому что тип int — не nullable. Проблема — мы все еще можем забыть засетить какое-то поле. Не клево. И если мы сделаем Name «Bond» и забудем посетить айдишник, у нас будет новый User с id «0» и именем «Bond».

В Builder поменяем int на int же, чтобы он был nullable. Попробуем с этим побороться. Теперь все здорово.

Если мы пытаемся сделать User с именем «Bond», забыв проставить ему айдишник, у нас упадет null pointer exception, потому что айдишник не nullable, а у Builder — null, конкретно pointer exception.

Теперь, когда мы строим из Builder наш объект, он проверяет, что поле не nullable. Но мы все еще можем забыть поставить имя, поэтому мы навешиваем object replay на null. И это еще не все.

В данном случае если мы в айдишном рантайме каким-то образом положили null, и было бы здорово сразу узнать, что ты это сделал и это не клево, что ты сейчас делаешь ошибку. Посмотрим на последний пример.

Поэтому мы в Builder поменяем в setter Integer на int, и он сразу здесь ругнется, что выкинули null. Нужно кинуть ошибку не в момент создания User, а когда ты сетишь в айдишник null.

Есть простейший паттерн Builder, но даже в его реализации есть какие-то тонкости, поэтому очень клево посмотреть на разные реализации паттернов. Короче, в чем суть? Это все очень интересно. У каждого паттерна есть десятки реализаций.

Вот наш User. Как мы пишем Builder в продакшен-коде? То есть мы не пишем кода, но Java уже считает, что у этого класса есть Builder, и мы его можем вот так вызвать. На него вешаем ротацию Builder из библиотеки Lombok, и она сама генерирует нам Builder.

Builder, GET. Я уже говорил, что в Java есть библиотеки практически для всего, в том числе Lombok, клевая библиотека, которая позволяет вам не писать boilerplate.

Есть такой клевый принцип в проектировании систем: Single Responsibility Principle. Паттерны бывают архитектурные — относящиеся не только к одному классу, а к системе в целом. О том, что каждый класс должен отвечать за какую-то свою функциональность. О чем он говорит? Есть Facade, который преобразует JSON-объекты в модели, с которыми далее будет работать Java приложение. В данном случае у нас есть Controller, который общается с пользователями, JSON-объектами. Есть Data Access Object, которая эти модели кладет в базу и достает из базы. Есть Service, в котором есть сложная логика, работающая с этими моделями. Другими словами, не все это находится в одном классе, а мы делаем пять разных классов, и это еще один паттерн. И есть сама база данных.

Такую штуку будет здорово вставить в резюме, это клевое окончание вашего обучения. Когда вы более-менее выучили Java, здорово написать какой-нибудь собственный проект, в котором будет база данных, работа с другими API, и который будет предоставлять REST API-клиентам ваше серверное приложение. С этим можно идти и устраиваться на работу.

На втором курсе я с ребятами писал курсовую работу. Вот пример моего серверного приложения. Там пользователи могли заходить через «ВКонтакте», ставить на карте точки, создавать мероприятия, звать на них своих друзей, сохранять изображение мероприятий и т. Они писали мобильное приложение для организации мероприятий. д.

Написал серверное приложение на Spring Boot, не используя SQL. Что сделал в проекте я? Что оно умело делать? Я его не знал, использовал JPA. Брать токен пользователя, идти с ним в VK, проверять, что это настоящий пользователь. Авторизоваться в VK через OAuth-2. Оно умело сохранять информацию в базе данных, также через JPA. Получать информацию о пользователях через «ВКонтакте». Я тогда еще не знал, что есть CLOB-объекты в базе, поэтому делал так. Умело сохранять картинки и прочие файлы в памяти компьютера, и сохранять ссылки на них в базе. И были юнит-тесты на основные функциональности. Там был REST API для пользователей, клиентских приложений.

На первом курсе в университете мне преподавали C# и дали понимание про ООП-программирование — что такое классы, интерфейсы, абстракция, зачем они нужны. [...] Небольшой пример моего успешного изучения Java. Без этого изучать Java довольно сложно, непонятно, зачем нужны классы. Мне это очень помогло.

И с этим всем я пошел на стажировку в Яндекс, прошел собеседование, попал в Яндекс.Маркет. На втором курсе в университете опять же давали Java core, но я на этом не остановился, пошел изучать Spring сам и написал курсовую работу, свой проект, о котором я говорил выше. Там я писал бэкенд для Беру, это наш маркетплейс, и для самого Яндекс.Маркета.

Мы делаем аналитику для бизнес-партнеров. После этого, полгода назад, я перевелся в другую команду внутри того же Маркета. Это очень интересно, на самом деле. Мы в аналитической платформе, нас на бэкенде трое, поэтому у меня очень большая доля влияния на проект. И нас всего трое, мы пишем этот код, и это очень прикольно. То есть, мы реально предоставляем данные по рынку — какие продажи, в каких категориях, в каких моделях, для бизнес-партнеров, больших известных компаний.

Полезные ссылки:
— «Java 8. Спасибо! Руководство для начинающих».
— Структуры данных.
— SQLZOO.
— Нормализация баз данных.
— Паттерны проектирования.
— Design Patterns.
— Clean Code.
— Effective Java.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»