Объектно-ориентированное программирование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.
Основные принципы структурирования в случае ООП связаны с различными аспектами базового понимания предметной задачи, которое требуется для оптимального управления соответствующей моделью:
- абстракция для выделения в моделируемом предмете важного для решения конкретной задачи по предмету, в конечном счёте — контекстное понимание предмета, формализуемое в виде класса;
- инкапсуляция для быстрой и безопасной организации собственно иерархической управляемости: чтобы было достаточно простой команды «что делать», без одновременного уточнения как именно делать, так как это уже другой уровень управления;
- наследование для быстрой и безопасной организации родственных понятий: чтобы было достаточно на каждом иерархическом шаге учитывать только изменения, не дублируя всё остальное, учтённое на предыдущих шагах;
- полиморфизм для определения точки, в которой единое управление лучше распараллелить или наоборот — собрать воедино.

Основная идея ФП - это выделение кода в функции, в рамках который предвыделены все необходимые для её работы переменные (области памяти).

Основной задачей аспектно-ориентированного программирования (АОП) является модуляризация сквозной функциональности, выделение её в аспекты. Для этого языки, поддерживающие концепцию АОП, реализуют следующие средства для выделения сквозной функциональности:
- аспект (aspect) – модуль или класс, реализующий сквозную функциональность. Аспект изменяет поведение остального кода, применяя совет в точках соединения, определённых некоторым срезом. Так же аспект может использоваться для внедрения функциональности;
- совет (advice) – дополнительная логика — код, который должен быть вызван из точки соединения. Совет может быть выполнен до, после или вместо точки соединения;
- точка соединения (join point) — точка в выполняемой программе (вызов метода, создание объекта, обращение к переменной), где следует применить совет ;
- срез (pointcut) — набор точек соединения. Срез определяет, подходит ли данная точка соединения к заданному совету;
- внедрение (introduction) — изменение структуры класса и/или изменение иерархии наследования для добавления функциональности аспекта в инородный код;
- цель (target) – объект, к которому будут применяться советы;
- переплетение (weaving) – связывание объектов с соответствующими аспектами (возможно на этапе компиляции, загрузки или выполнения программы).

S: Single Responsibility Principle (Принцип единственной ответственности).
Класс должен быть ответственен лишь за что-то одно

O: Open-Closed Principle (Принцип открытости-закрытости).
Программные сущности (классы, модули, функции) должны быть открыты для расширения, но не для модификации.

L: Liskov Substitution Principle (Принцип подстановки Барбары Лисков).
Необходимо, чтобы подклассы могли бы служить заменой для своих суперклассов.
Цель этого принципа заключаются в том, чтобы классы-наследники могли бы использоваться вместо родительских классов, от которых они образованы, не нарушая работу программы. Если оказывается, что в коде проверяется тип класса, значит принцип подстановки нарушается.

I: Interface Segregation Principle (Принцип разделения интерфейса).
Создавайте узкоспециализированные интерфейсы, предназначенные для конкретного клиента. Клиенты не должны зависеть от интерфейсов, которые они не используют.
Этот принцип направлен на устранение недостатков, связанных с реализацией больших интерфейсов.

D: Dependency Inversion Principle (Принцип инверсии зависимостей).
Объектом зависимости должна быть абстракция, а не что-то конкретное.
Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Порождающие
Простая фабрика - просто генерирует экземпляр для клиента без предоставления какой-либо логики экземпляра.
Фабричный метод - Это способ делегирования логики создания объектов (instantiation logic) дочерним классам.
Абстрактная фабрика - Это фабрика фабрик. То есть фабрика, группирующая индивидуальные, но взаимосвязанные/взаимозависимые фабрики без указания для них конкретных классов.
Строитель - Шаблон позволяет создавать разные свойства объекта, избегая загрязнения конструктора (constructor pollution). Это полезно, когда у объекта может быть несколько свойств. Или когда создание объекта состоит из большого количества этапов.
Прототип - Объект создаётся посредством клонирования существующего объекта. Т.е. объект можно легко создать, клонировать и изменить.
Одиночка - Шаблон позволяет удостовериться, что создаваемый объект — единственный в своём классе. Плох тем что вносит глобальное состояние.

Структурные
Адаптер - Шаблон «Адаптер» позволяет помещать несовместимый объект в обёртку, чтобы он оказался совместимым с другим классом.
Мост - Шаблон «Мост» — это предпочтение компоновки наследованию. Подробности реализации передаются из одной иерархии другому объекту с отдельной иерархией.
Компоновщик - Шаблон «Компоновщик» позволяет клиентам обрабатывать отдельные объекты в едином порядке.
Декоратор - Шаблон «Декоратор» позволяет во время выполнения динамически изменять поведение объекта, обёртывая его в объект класса «декоратора».
Фасад - Шаблон «Фасад» предоставляет упрощённый интерфейс для сложной подсистемы.
Приспособленец - Шаблон применяется для минимизирования использования памяти или вычислительной стоимости за счёт общего использования как можно большего количества одинаковых объектов.
Заместитель - С помощью шаблона «Заместитель» класс представляет функциональность другого класса.

Поведенческие
Команда - Шаблон «Команда» позволяет инкапсулировать действия в объекты. Ключевая идея — предоставить средства отделения клиента от получателя.
Итератор - Шаблон — это способ доступа к элементам объекта без раскрытия базового представления.
Посредник - Шаблон «Посредник» подразумевает добавление стороннего объекта («посредника») для управления взаимодействием между двумя объектами («коллегами»). Шаблон помогает уменьшить связанность (coupling) классов, общающихся друг с другом, ведь теперь они не должны знать о реализациях своих собеседников.
Хранитель - Шаблон «Хранитель» фиксирует и хранит текущее состояние объекта, чтобы оно легко восстанавливалось.
Наблюдатель - Шаблон определяет зависимость между объектами, чтобы при изменении состояния одного из них его «подчинённые» узнавали об этом.
Стратегия - Шаблон «Стратегия» позволяет переключаться между алгоритмами или стратегиями в зависимости от ситуации.
Состояние - Шаблон позволяет менять поведение класса при изменении состояния.

Больше паттернов

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

Подход, который нацелен на изучение предметной области предприятия в целом или каких-то отдельных бизнес-процессов.
- Область (англ. domain, домен) — предметная область, к которой применяется разрабатываемое программное обеспечение.
- Модель (англ. model) — описывает отдельные аспекты области и может быть использована для решения проблемы.
- Язык описания — используется для единого стиля описания домена и модели.

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

Сложность поиска в массиве - O(n)
Сложность поиска в отсортированном массиве - Бинарный поиск – O(log n)
Сложность поиска в Map - O(1) Быстрая сортировка (по-умолчанию в php) - в среднем O(n * log n)

Фреймворк от Google для удалённого вызова процедур
Из коробки мы имеем:
Protobuf в качестве инструмента описания типов данных и сериализации.
HTTP/2 в качестве транспорта.
Статические пути — используется путь к сервису, а что внутри — описывайте в терминах модели и её событий.
SSL/TLS, OAuth 2.0, аутентификация через сервисы Google, плюс можно прикрутить свою (например, двухфакторную)
Поддержка 9-ти языков: C, C++, Java, Go, Node.js, Python, Ruby, Objective-C, PHP, C#