Ты молодой программист, а в университетах преподают только фундаментальные знания? Как же быть таким молодым специалистом, и в итоге стать востребованным на IT рынке? Вот уже 2 года как мы, объединенная компания “Колёса Крыша Маркет”, проводим Колёса Академию для этой цели. В данном посте я постараюсь ответить на частые вопросы о том, к чему нужно готовиться, чтобы пройти отбор в нашу академию, в частности по направлению Android разработки.

Фундаментальные знания

Возможно, вы уже разрабатываете базовые Android приложения, это хорошо, но без фундаментальных знаний вы со временем уткнётесь в то, что будете писать плохой код и не знать как правильно организовывать код. Чтобы решить этот вопрос, вам нужно изучить больше про концепцию Object-Oriented Programming и базовые принципы программирования, которые как раз преподаются на университетсих курсах по Computer Science.

Принципы OOP

OOP состоит из четырёх принципов: Encapsulation, Abstraction, Inheritance и Polymorphism. Эти принципы, для начинающих разработчиков, возможно покажутся страшными словами. Поэтому попробуем разобраться с каждым из них.

Encapsulation (Инкапсуляция)

Когда вы водите машину, вы нажимаете на газ чтобы ускориться, управляете рулем чтобы повернуть, отпускаете газ и нажимаете на тормоза чтобы остановиться. Все эти детали кроются под капотом машины, которые разработали инженеры. Вам как водителю предоставлен только интерфейс для того, чтобы вы могли комфорно водить. Эти публичные части машины можно рассмотреть как публичные части объекта, доступные нам как объекту “Водитель”.

Инкапсуляция - возможность объекта скрывать детали реализации от других объектов, давая при этом публичный, либо частично скрытый доступ к нему. В случае с языком Java предоставляется возможность объявлять переменные или методы как public - для доступа любому объекту, private - для доступа только внутри класса или protected - для доступа подклассам и внутри класса.

Если вы закрываете(private) состояние объекта, предоставляя при этом возможность менять состояние через публичные(public) методы, то вы успешно применяете принцип инкапсуляции.

Abstraction (Абстракция)

Когда вы разрабатываете программу, со временем проект становится очень большим и сложным. Различные объекты общаются друг с другом часто. Поэтому поддерживать такие проекты с годами становится сложнее - требования постоянно меняются. Концепт “абстракция” как раз нацелен на то, чтобы упростить эту задачу.

Абстракция - это модель некоего объекта из реального мира либо некое назначение в проекте. Данная модель должна предоставить другим объектам только механизм взаимодействия связанный с данной моделью.

Абстракцию можно рассматривать как расширение инкапсуляции. Кстати, поэтому абстракцию зачастую не включают в общий список принципов OOP.

Представьте себе что вам нужно создать объект машины. Водительно должен заполнить бак бензином и нажать на газ чтобы машина начала ездить. Водитель не должен знать как будет сгорать бензин, он только взаимодействует с публичными методами машинами. Желательно чтобы этот абстрактный объект (машина) был просто для пользования и интерфейс обращения к нему не менялся.

Inheritance (Наследование)

Часто когда пишите программу, некоторые объекты имеют общую логику, но они не совсем одинаковые сущности.

Например, легковые машины и мотоцикл являются транспортами. Хорошо бы выделить общую логику свойства транспорта, как, например, способность ездить. Мы бы могли создать родительский класс Vehicle для Car и Motorbike - это и есть Наследование.

Но важно отметить, что не все транспорты имеют колеса как легковые машины или мотоциклы. Добавим колёсо для лодок, чтобы он тоже умел ездить на автодорогах?

boat with wheels

Такие свойства, как умение ездить или плыть можно выделить в interface. Но при этом класс JamesBondCar имеет способность плыть по воде. Язык программирования Java позволяет наследоваться только от одного класса, но есть возможность реализовать множество interface.

interface Automobile {
  public void run(Point destination);
}
interface Marine {
  public void swim(Point destination);
}
class JamesBondCar extends Vehicle implements Automobile, Marine {
  ...
}

Polymorphism (Полиморфизм)

В принципе наследования мы рассмотрели, что машины умеют ездить. Но каждый из них может ездить по разному.

Принцип Полиформизм описывает возможность наследников реализовывать общие операции по своему. Так, например, мы можем реализовать метод run() немного по разному, в зависимости от типа машины.

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

private void runAll(List<Automobile> automobiles, Point point) {
  for (Automobile automobile : automobiles) {
    automobile.run(point);
  }
}

Design Pattern (Паттерны проектирования)

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

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

Зачем же изучать паттерны

В чем отличие, например, профессионального ремесленника от новичков? Профессионал знает как применить те или иные инструменты в различных условиях.

В разработке Android приложений то же самое.

  1. Зачастую многие проблемы можно решить, применив готовые решения, которые как раз описываются в концепциях паттерна. Вы можете сами додуматься до такого решения, но зачем изобретать велосипед?
  2. Структура классов паттерна унифицирована, поэтому сложнее ошибиться при проектировании программ. Вы действуете по шаблонам, которые описаны в паттернах.
  3. Как объяснить другому разработчику, как вы подошли к решению проблемы в проекте - “Я создал класс X, Y, Z и применил немного магии”? Проще будет если вы скажете, что применили паттерн под названием X.

Классификация паттернов

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

  1. Creational patterns (Порождающие паттерны) - они имеют дело с механизмами создания объектов, подходящие в разных ситуациях. В этот тип включаются: Abstract Factory, Builder, Factory Method, Object Pool, Prototype и Singleton. С некоторыми из них вы наверняка уже сталкивались.
  2. Structural patterns (Структурные паттерны) - данный тип предназначен для упрощения реализации связи между объектами. Мы каждый день применяем такие паттерны, как Adapter, Decorator, Facade в рабочих проектах. Так же есть Bridge, Composite, Flyweight, Private Data Class, Proxy.
  3. Behavioral patterns (Поведенческие паттерны) - эти паттерны увеличивают гибкость в осуществлении коммуникации между объектами. Например, многим известный Observer относится к данному классу паттернов.

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

Алгоритмы и структуры данных

Во время собеседования мы задаем вопросы связанные с алгоритмами и структурами данных. Некоторые кандидаты говорят нам, что они не знают как решить задачу, так как при разработке мобильных приложений, они не решают подобные задачи. Нужно ли знать разработчику о том, как выполняется сортировка данных при вызове функции Collections.sort или как лучше всего хранить данные, которые мы получаем от внешнего источника?

Можно взять реальные примеры из жизни разработчика. Например, мы получаем по API данные для отображения списка комментариев к объявлению. Нам приходит JSON Array без какой либо вложенности, есть только идентификатор комментария, на который пользователь отвечает. Как организовать структуру данных так, чтобы отобразить комментарии в виде дерева и при этом оптимальнее всего было искать нужный объект.

Хороший разработчик должен изучать их, чтобы решать задачи оптимально. Без знания алгоритмов, при решении задачи, вы попробуете решить своим путём, что зачастую окажется не эффективным при выполнении кода. Без знания структур данных, вы затруднитесь в выборе нужной структуры данных. Что использовать при создании объекта данных - банально через List или Map? Если вы не знаете как они работают при операциях записи и чтении, вы не сможете быстро решить, что оптимальнее всего для вашей задачи.

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

Опытным разработчикам тоже тяжело пройти интервью

Независимо от опыта разработчиков, приходится готовиться к вопросам по алгоритмам во время интервью. С годами теряется знание базовых алгоритмов, так как, естественно, мозг забывает об этом. Но если вы помните базовые принципы выполнения алгоритмов, то легче вспомнить их при повторении.

Возможно во время выполнения задачи по алгоритмам, вы столкнётесь с проблемами, которые не решали, но достаточно иметь базовые знания алгоритмов и структур данных. Тем более мы не спрашиваем задачи уровня Google. Мы даём достаточно простые задачи, которые можно встретить на начальных уровнях в сборниках задач.

Twitter/Rallat

Ресурсы для изучения алгоритмов и структуры данных

В интернете есть множество ресурсов для этого:

  1. Udemy.com/learn-algorithms
  2. Coursera.org/specializations/algorithms
  3. Leetcode.com/problemset/algorithms

Android SDK

Для разработки Android приложении требуется лишь Android SDK. В нем содержатся стандартные классы как, например: Activity, Fragment, View и т.д. Чтобы узнать предназначение каждых из этих классов, нужно читать официальную документацию. Но помимо чтения, важно еще применять их в проекте.

Попробуйте создать простое приложение, добавляя к нему новые функционалы. Например: авторизация, оффлайн режим, синхронизация данных раз в сутки. Таким образом вы сможете быстро освоить разработку Android приложения, применяя к каждому из этих функционалов необходимые компоненты из Android SDK.

Подача на Колёса Академию

Подача на Колёса Академию продлится до 8 Января 2019 года. Зайдите на сайт job.kolesa.kz/academy и оставьте ваши контактные данные со ссылкой на ваше резюме или портфолио.

Kolesa Academy Penguine

Не отчаивайтесь даже если не пройдёте отбор - мы стараемся проводить академию каждый год летом и зимой. Отмечу напоследок, что половина разработчиков в команде Android - бывшие академики, которые успешно прошли обучение и действительно стали хорошими разработчиками. Про опыт прохождения академии можно посмотреть в докладе “MobileTeam.Builder()” на конференции Kolesa.Mobile 2.0

Если есть вопросы, обращайтесь ко мне в Telegram или нашим Kolesa HR.

Список дополнительных ресурсов для изучения

  1. «Чистый код. Создание, анализ и рефакторинг» Р. Мартин
  2. «Приемы ООП. Паттерны проектирования» Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес
  3. «Алгоритмы. Построение и анализ» Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн
  4. «Программист-фанатик» Чад Фаулер
  5. «Java. Эффективное программирование» Джошуа Блох
  6. «Refactoring Guru»