Python — 100 дней от новичка до мастера> Author: Luo Hao
Recently, many enthusiasts eager to learn Python have joined our community. Currently, the number of participants in our community exceeds ten thousand people. Our goals are to create a high-quality community for discussing Python that helps beginners overcome difficulties when learning this language; provide opportunities for new developers to acquire necessary knowledge and become professionals; as well as enable experienced developers to share their skills both freely and for pay so that everyone can improve their professional skills and overall qualifications. Due to work commitments, our open lectures and experience-sharing events have been temporarily suspended, but our members remain active and supportive, so we would like to express our gratitude to all of you. In the near future, we will begin regular updates on the first 15 days and last 10 days of content. The first 15 days are dedicated to beginners, and I want to make the learning process even simpler by using more understandable program examples. The last 10 days will be devoted to practical application of Python in projects and preparation for job interviews, where I hope to present more detailed information, especially on day 100. Creating content requires time and effort, so your support through donations is very valuable.Эти деньги не будут использоваться для покупки кофе, а будут переданы нуждающимся людям через платформу Tencent Charity (Подробнее).
Анализ областей применения Python и ситуации на рынке труда
Кратко говоря, Python — это "elegantный", "ясный" и "простой" язык программирования.
- Низкая кривая обучения, доступен даже тем, кто не имеет специального образования
- Открытый исходный код с мощной экосистемой
- Интерпретируемый язык, обеспечивающий идеальную переносимость между платформами
- Поддерживает объектно-ориентированное и функциональное программирование
- Возможность расширения функциональности путём вызова кода на C/C++
- Высокий уровень стандартизации кода, что обеспечивает его читаемость
Сегодня Python широко используется во многих популярных областях:
- Облачные инфраструктуры — Python / Java / Go
- DevOps — Python / Shell / Ruby / Go
- Парсинг веб-страниц — Python / PHP / C++
- Анализ данных и машинное обучение — Python / R / Scala / Matlab
- Машинное обучение — Python / R / Java / Lisp
Как Python-разработчик, основные области занятости включают:
- Разработка серверных приложений на Python / игры / API
- Автоматизация операционной среды Python
- Анализ данных / визуализация данных / большие данные на Python
- Разработка парсеров Python
- Разработка чат-ботов / алгоритмы компьютерного зрения / глубокое обучение на Python
Ниже приведена таблица, отражающая спрос на работу с Python и уровень зарплат в основных городах (по состоянию на май 2018 года).


Несколько советов для начинающих:
- Используйте английский язык как рабочий.
- Практика — ключ к успеху.
- Опыт приходит через ошибки.
- Не будьте одними из паразитов.
- Либо выделяйтесь, либо покидайте проект.
- Введение в Python — история Python / преимущества и недостатки Python / области применения Python
- Установка среды программирования — окружение Windows / окружение Linux / окружение MacOS
- Выполнение программы Python из командной строки — привет, мир / функция
print
/ выполнение программы
- Использование IDLE — интерактивная среда (REPL) / запись многострочных кода / выполнение программы / выход из IDLE
- Комментарии — роль комментариев / однотабличные комментарии / многотабличные комментарии
День 02 - Элементы языка- Программы и системы счисления - инструкция и программа / машина фон Неймана / двоичная и десятичная система / восьмеричная и шестнадцатеричная система
-
Переменные и типы данных - названия переменных / использование переменных / функция input
/ проверка типа переменной / преобразование типов
-
Числа и строки - целое число / вещественное число / комплексное число / строка / базовые операции со строками / кодировка символов
-
Операторы - математические операторы / операторы присваивания / сравнительные операторы / логические операторы / операторы тождественности / приоритет операторов
-
Прикладные примеры - конвертация температур из Фаренгейта в Цельсий / расчет периметра и площади круга по радиусу / проверка на високосность года#### День 03 - Ветвление
-
Применение ветвления — условие / отступы / блок кода / схема потока
-
Инструкция if
— простое if
/ структура if-else
/ структура if-elif-else
/ вложенные if
-
Прикладные примеры — аутентификация пользователя / взаимное преобразование единиц измерения британской и метрической систем / случайное решение задачи / перевод оценок из процентного в буквенный формат / вычисление значения функции с несколькими участками / расчет периметра и площади треугольника по длинам сторон
- Применение циклов — условие / отступы / блок кода / схема потока
- Цикл
while
— базовая структура / инструкция break
/ инструкция continue
- Цикл
for
— базовая структура / тип range
/ ветвление внутри цикла / вложенные циклы / преждевременное завершение программы
- Прикладные примеры — суммирование чисел от 1 до 100 / проверка на простое число / игра "Угадай число" / вывод таблицы умножения / печать треугольников / задача про бананы / задача про курицу
- Классические примеры: число- narcissus / задача с сотней денег / игра в кости
- Упражнения: последовательность Фибоначчи / совершенное число / простое число
День 06 - Использование функций и модулей- Зачем нужны функции - плохие запахи кода / использование функций для группировки кода
- Определение функции - def / имя функции / список аргументов / return / вызов функции
- Вызов функции - встроенные функции Python / импорт модулей и функций
- Аргументы функции - значения по умолчанию / переменное количество аргументов / ключевые аргументы / именованные ключевые аргументы
- Возвращаемые значения функции - отсутствие возврата / возврат одного значения / возврат нескольких значений
- Проблемы области видимости - локальная область видимости / вложенная область видимости / глобальная область видимости / встроенная область видимости / связанные ключевые слова
- Управление функциями с помощью модулей - концепция модуля / управление функциями с помощью пользовательских модулей / что происходит при конфликте названий (в одном и разных модулях)
- Базовые операции со списками - создание списка / доступ к элементам через индекс / выход за границы индекса / добавление элементов / удаление элементов / изменение элементов / срезы / циклический проход
- Часто используемые операции со списками - объединение / копирование (копия элементов и массива) / длина / сортировка / обратная сортировка / поиск
- Создание списков - использование range для создания списков чисел / генераторное выражение / генератор
- Использование кортежей - создание кортежа / использование значений в кортеже / изменение переменной кортежа / преобразование между кортежами и списками
- Базовые операции со множествами - различия между множеством и списком / создание множества / добавление элементов / удаление элементов / очистка
- Часто используемые операции со множествами - пересечение / объединение / разность / симметричная разность / подмножество / надмножество
- Базовые операции со словарями - особенности словарей / создание словаря / добавление элементов / удаление элементов / получение значений / очистка
- Часто используемые операции со словарями - метод keys() / метод values() / метод items() / метод setdefault()- Основные упражнения - эффект "бегущей строки" / поиск максимального элемента в списке / расчет среднего значения экзаменационных оценок / последовательность Фибоначчи / треугольник Паскаля
- Интегрированные примеры - выбор номера лотереи Double Color Ball / игра в крестики-нолики#### Day08 - Основы объектно-ориентированного программирования - Классы и объекты - Что такое класс / Что такое объект / Другие концепции, связанные с объектно-ориентированным программированием
- Определение класса - Базовая структура / Атрибуты и методы / Конструктор / Деструктор / __str__ метод
- Использование объектов - Создание объекта / Отправка сообщений объекту
- Четыре столпа объектно-ориентированного программирования - Абстракция / Инкапсуляция / Наследование / Полиморфизм
- Основные упражнения - Определение класса студента / Определение класса часов / Определение класса фигур / Определение класса автомобиля
Day09 - [Объектно-ориентированное программирование на продвинутом уровне](./Day01- Yöntemleri.md)- Атрибуты - атрибуты класса / атрибуты экземпляра / геттеры / сеттеры / делетеры / использование __slots__
-
Методы в классах - методы экземпляров / методы класса / статические методы
-
Перегрузка операторов - __add__
/ __sub__
/ __or__
/ __getitem__
/ __setitem__
/ __len__
/ __repr__
/ __gt__
/ __lt__
/ __le__
/ __ge__
/ __eq__
/ __ne__
/ __contains__
-
Отношения между объектами классов - ассоциация / наследование / зависимость
-
Наследование и полиморфизм - что такое наследование / синтаксис наследования / вызов методов родительского класса / переопределение методов / проверка типа / множественное наследование / ромбовое наследование и алгоритм C3
-
Интегрированные примеры - система расчета зарплат / автоматическая система скидок на книги / пользовательский класс дробей#### Day10 - Графический пользовательский интерфейс и разработка игр
-
Разработка GUI приложений с использованием tkinter
-
Разработка игр с помощью сторонней библиотеки Pygame
-
Игра "Большие шарики едят маленькие"
- Чтение файлов — чтение всего файла / чтение построчно / пути к файлам
- Запись файлов — запись поверх существующего содержимого / добавление нового содержимого / текстовые файлы / двоичные файлы
- Обработка исключений — важность механизма исключений / блоки try-except / блоки else / блоки finally / встроенные типы исключений / стек исключений / ключевое слово raise
- Устойчивость данных — общие сведения о CSV-файлах / применение модуля csv / формат JSON / применение модуля json
Day12 - Строки и регулярные выражения- Продвинутые операции со строками - escape-символы / сырые строки / многострочные строки / операторы in и not in / методы начинающиеся с is / методы join и split / методы strip / модуль pyperclip / неизменяемые и изменяемые строки / использование модуля StringIO
-
Введение в регулярные выражения - роль регулярных выражений / метасимволы / escape / кванторы / группировка / нулевые утверждения / жадное и ленивое соответствие / использование модуля re для работы с регулярными выражениями (поиск, замена, захват)
-
Использование регулярных выражений - модуль re / функция compile / методы group и groups / метод match / метод search / методы findall и finditer / методы sub и subn / метод split
-
Прикладные примеры - использование регулярных выражений для проверки введенной строки#### День 13 - Процессы и потоки#### День 14 - Основы сетевой программирования и разработка сетевых приложений
-
Основы компьютерных сетей — история развития компьютерных сетей / модель "TCP/IP" / IP-адреса / порты / протоколы / другие связанные понятия
-
Модели сетевых приложений — клиент-серверная модель / браузер-серверная модель
-
Доступ к сетевым ресурсам с использованием HTTP-протокола — общие сведения о сетевых API / доступ к URL / модуль requests
/ парсинг данных в формате JSON
-
Сетевое программирование на Python — концепция сокетов / модуль socket
/ функция socket()
/ создание TCP-сервера / создание TCP-клиента / создание UDP-сервера / создание UDP-клиента / модуль SocketServer
-
Электронная почта — протокол SMTP / протокол POP3 / протокол IMAP / модуль smtplib
/ модуль poplib
/ модуль imaplib
-
SMS-услуги — вызов сервиса отправки SMS
-
Обработка изображений с помощью Pillow — чтение и запись изображений / объединение изображений / геометрические преобразования / преобразование цветовых пространств / эффекты фильтров
-
Чтение и запись Word-документов — работа с текстовым содержимым / абзацы / шапка и подвал страницы / обработка стилей
-
Чтение и запись Excel-файлов — модуль xlrd
/ модуль xlwt
-
Создание PDF-файлов — модуль PyPDF2
/ модуль ReportLab
### Дни 16-20 - Продвинутый Python
-
Часто используемые структуры данных
-
Продвинутые методы работы с функциями - "первый класс" / высшие порядки функций / lambda-функции / области видимости и замыкания / декораторы
-
Продвинутые знания объектно-ориентированного программирования - "три столпа" / отношения между классами / сборка мусора / магические атрибуты и методы / миксины / метаклассы / принципы объектно-ориентированного проектирования / паттерны проектирования GoF
-
Итераторы и генераторы - связанные магические методы / два способа создания генераторов
-
Параллельное и асинхронное программирование - многопоточность / многопроцессорность / асинхронный ввод-вывод / async и await
- Использование HTML-тегов для отображения контента страницы
- Использование CSS для рендеринга страницы
- Использование JavaScript для управления взаимодействием
- Введение в jQuery и повышение навыков
- Введение в Vue.js
- Использование Element UI
- Использование Bootstrap
- Основы отношений в базах данных
- Установка и использование MySQL
- Использование SQL
- DDL — язык определения данных — создание / удаление / изменение
- DML — язык управления данными — вставка / удаление / обновление / выбор
- DCL — язык контроля доступа — предоставление / отзыв
- Сопутствующие знания
- Теория нормализации — руководящее учение при проектировании двухмерных таблиц
- Интегрированность данных
- Консистентность данных
- Работа с MySQL в Python- Начало работы с NoSQL
- Основы NoSQL
- Основы Redis
- Основы MongoDB
- Принцип работы веб-приложений и протокол HTTP
- Обзор фреймворка Django
- Быстрый старт за пять минут
- Использование представлений и шаблонов
- Настройка отношений баз данных
- Использование административной панели
- Выполнение CRUD операций с помощью ORM
- Лучшие практики использования моделей Django
- Определение модели для примера
- Загрузка статических ресурсов
- Получение данных с использованием AJAX
- Формы и элементы управления формами
- Подделка запросов через сайт и токены CSRF
- Формы и ModelForms
- Валидация форм
- Отслеживание пользователя
- Соотношение cookies и sessions
- Поддержка session Django
- Чтение и запись cookies в представлениях
День 46 — Отчеты и журналы- Изменение заголовков ответа с HttpResponse
-
Обработка больших файлов с StreamingHttpResponse
-
Создание отчетов Excel с xlwt
-
Создание отчетов PDF с reportlab
-
Генерация графиков на стороне клиента с ECharts
-
Настройка журнала и Django-Debug-Toolbar
#### День 47 — Применение middleware
-
Что такое middleware
-
Встроенные middleware Django
-
Самостоятельное создание middleware и его применение
- Возврат данных в JSON формате
- Отображение страниц с помощью Vue.js
-
Первое правило оптимизации сайта
-
Использование Redis для предоставления кэшированных услуг в проектах Django
-
Чтение и запись кэша в представлениях
-
Реализация кэширования страниц с использованием декораторов
-
Предоставление кэшированных услуг для интерфейсов данных
- Контроллер формы для загрузки файлов и предварительного просмотра изображений
- Обработка загруженных файлов на серверной стороне
- Описание WYSIWYG редакторов
- Использование wangEditor
-
Введение в популярные платформы SMS-шлюзов
-
Отправка SMS с помощью башенного гвоздя
-
Поддержка отправки электронной почты в Django#### День 54 - Асинхронные задачи и планировщики задач
-
Второе правило оптимизации сайта
-
Настройка службы очередей сообщений
-
Использование Celery для реализации асинхронных задач в проекте
-
Использование Celery для реализации периодических задач в проекте
- Юнит тестирование в Python
- Поддержка юнит тестирования в Django
- Использование систем управления версиями
- Настройка и использование uWSGI
- Разделение статического и динамического содержимого и конфигурация Nginx
- Конфигурация HTTPS
- Конфигурация домена
- Параллельное программирование
- Модели I/O и событий
- Использование aiomysql и aioredis
- Введение в WebSocket
- Программирование серверной части WebSocket
- Программирование клиентской части WebSocket
- Проект: Web чат-комната
- Разделение фронтэнда и бэкэнда в процессе разработки и создание документации по API
- Реализация фронтального отображения с помощью Vue.js
- Создание отчетной функциональности с использованием ECharts
- Реализация сервиса push-уведомлений с использованием WebSocket
- Концепция веб-пауков и области их применения
- Обсуждение законности использования веб-пауков
- Инструменты для создания веб-пауков
- Структура программы паука
- Стандарты сбора данных и сторонние библиотеки
- Три способа анализа страниц: регулярные выражения / XPath / CSS-селекторы
-
Как хранить большие объемы данных
-
Реализация кэширования данных#### День69 - Параллельная загрузка
-
Многопоточность и многопроцессорность
-
Асинхронное I/O и корутины
-
Использование ключевых слов async
и await
-
Применение сторонней библиотеки aiohttp
- Инжиниринг обратного проектирования JavaScript
- Получение динамического контента с помощью Selenium
- Автоматическая отправка форм
- Применение пула cookies
- Обработка CAPTCHA
- Описание Scrapy как фреймворка для пауков
- Установка и использование Scrapy
- Использование пауков
- Применение промежуточных компонентов: промежуточные компоненты загрузки / промежуточные компоненты пауков
- Интеграция Scrapy с Selenium для получения динамического контента
- Развертывание Scrapy в Docker
- Принцип работы распределенного паука
- Распределенная реализация Scrapy
- Использование Scrapyd для распределенной установки
День75 - Практика проекта пауков- Сбор данных с сайтов по трудоустройству
- Сбор данных с рынка недвижимости
- Сбор данных с платформы вторичной торговли автомобилями
- Модели процесса разработки программного обеспечения
-
Классическая модель процесса (модель водопада)
- Анализ жизнеспособности (исследование того, стоит ли начинать или нет), выход — «Отчет о жизнеспособности».
- Анализ требований (исследование того, что именно следует сделать), выход — «Спецификация требований» и прототип продукта.
- Общее проектирование и детальное проектирование, выход — концептуальная модель (диаграмма ER), физическая модель, диаграммы классов, последовательностей и т.д.
- Программирование / тестирование.
- Ввод в эксплуатацию / обслуживание. Самым большим недостатком модели водопада является то, что она не способна адаптироваться к изменениям требований; только после завершения всего процесса можно получить готовый продукт, что приводит к снижению морали команды.
-
Агилное развитие (Scrum) - владелец продукта, Scrum-мастер, разработчики - спринты
- Бэклог продукта (истории пользователей, прототип продукта).
- Плановое совещание (оценка и бюджет).
- Ежедневное развитие (стандартное совещание, методика Pomodoro, парное программирование, тестирование до программирования, рефакторинг кода...).
- Устранение ошибок (описание проблемы, шаги воспроизведения, тестировщики, назначенные исполнители).
- Выпуск версии.
- Совещание по демонстрации (показатель, участие пользователей).
- Совещание по обратной связи (итоговый отчёт по текущему циклу). > Дополнительно: декларация агилного развития программного обеспечения
-
Личность и взаимодействие важнее процесса и инструментов
-
Работающее программное обеспечение важнее детального документирования
-
Коллаборация с клиентами важнее переговоров по контракту
-
Ответ на изменения важнее соблюдения плана

Описание проекта и понимание бизнеса
Выбор темы проекта
Область выбора темы
-
CMS (клиентская сторона): Новостной агрегатор, форум вопросов и ответов, сообщество для обмена опытом, сайты отзывов на фильмы и книги и т.д.
-
MIS (клиентская + административная стороны): Системы управления знаниями (Knowledge Management System), системы оценки производительности (Key Performance Indicators), системы управления человеческими ресурсами (Human Resource Systems), системы управления взаимоотношениями с клиентами (Customer Relationship Management), системы управления цепочками поставок, системы управления складом и т.д.
-
App-backend (административная сторона + API): Приложения для вторичной торговли, приложения для периодической печати, небольшие электронные магазины, новостные порталы, туристические сервисы, социальные сети, читалки книг и т.д.
-
Другие типы: Проекты, основанные на отраслевых знаниях и опыте работы, легко понимаемые и контролируемые бизнес-процессы.---
Подготовка команды
Участники команды и роли
Примечание: Благодарю госпожу Фу Шянин за создание этого красивого организационного графика компании.

-
Роли участников:
-
Продуктовый владелец: принимает решения относительно того, что делать и как реализовать требования.
-
Ответственный за команду: решает различные проблемы, сосредоточен на том, чтобы лучше работать, и защищает команду от внешних воздействий.
-
Разработчики: исполнители проекта, включая программистов и тестировщиков.
-
Подготовка команды:
-
Коммерческий случай и финансирование, контракты, надежды, начальные требования продукта, начальный план выпуска, инвестиции, сбор команды.
Оценка объема работы
Оценка объема работы заключается в количественной оценке задач разработки, включая дизайн прототипа, логотипа, UI, фронтенд-разработку и т.д., с целью разделения каждого задания на минимальные подзадачи. Минимальная подзадача должна занимать менее двух дней времени выполнения. После этого проводится общая оценка времени проекта. Каждое задание должно быть помещено на доску Kanban, которая состоит из трёх частей: "To Do" (не выполненные), "In Progress" (в процессе) и "Done" (выполненные).
Инструменты для команды разработчиков- Управление версиями: Git, Mercurial
Пожалуйста, обратитесь к "Проблемы и решения в командном проекте" для более подробной информации.
Понимание требований, разделение на модули и распределение задач
-
Понимание требований: мозговой штурм и анализ конкурентов.
-
Разделение на модули: создание схемы мышления (XMind), где каждый модуль представляет собой ветвь, а каждая конкретная функция — лист (описывается глаголами). Нужно убедиться, что каждый листовой узел не порождает новых узлов, определить важность, приоритет и объем работы каждого листового узла.
-
Распределение задач: руководитель проекта распределяет задачи каждому члену команды на основе вышеуказанных критериев.

-
Создание графика выполнения проекта (ежедневное обновление) | Модуль | Функционал | Человек | Статус | Выполнено | Часы | Плановая дата начала | Реальная дата начала | Плановая дата завершения | Реальная дата завершения | Примечания |
| --------------- | ---------------------- | ------------ | ----------------- | -------- | ---- | -------------------- | --------------------- | ------------------------ | ------------------------- | -------------------------- |
| Комментарий | Добавление комментария | Ван Дацай | В процессе | 50% | 4 | 2018/08/07 | | 2018/08/07 | | |
| | Удаление комментария | Ван Дацай | Ожидание | 0% | 2 | 2018/08/07 | | 2018/08/07 | | |
| | Просмотр комментария | Бай Юаньфана | В процессе | 20% | 4 | 2018/08/07 | | 2018/08/07 | | Необходима проверка кода |
| | Голосование за комментарий | Бай Юаньфана | Ожидание | 0% | 4 | 2018/08/08 | | 2018/08/08 | | |4. OOAD и проектирование баз данных
-
Диаграмма классов UML (Unified Modeling Language)

-
Создание таблиц на основе модели (Forward Engineering)
python manage.py makemigrations app
python manage.py migrate
-
Создание физической модели с помощью PowerDesigner.

-
Создание модели на основе таблиц (Backward Engineering)
python manage.py inspectdb > app/models.py
- Краткий обзор Docker
- Установка Docker
- Использование Docker для создания контейнеров (Nginx, MySQL, Redis, GitLab, Jenkins)
- Создание образов Docker (Создание файла Dockerfile и связанных команд)
- Координация контейнеров (Docker-compose)
- Управление кластерами
-
Настройка баз данных (несколько баз данных, репликация master-slave, маршрутизация запросов к базам данных)
-
Настройка кэша (распределение кэша, ключи, время жизни, репликация master-slave, восстановление после отказа (sentinel))
-
Настройка логирования
-
Анализ и отладка (Django-Debug-Toolbar)
-
Полезные модули Python (вычисление дат, работа с изображениями, шифрование данных, взаимодействие с внешними API)##### Проектирование REST API
-
Архитектура RESTful
-
Создание документации для API
-
Использование Django-REST-Framework
Аналитика сложностей в проектах
- Использование кэша для снижения нагрузки на базу данных — Redis
- Использование очередей сообщений для декомпозиции и ограничения пиковых нагрузок — Celery + RabbitMQ
Единичные тесты
- Виды тестов
- Написание единичных тестов (unittest, pytest, nose2, tox, ddt, ...)
- Охват тестами (coverage)
Развертывание проекта1. Подготовка перед развертыванием
- Ключевые настройки (SECRET_KEY / DEBUG / ALLOWED_HOSTS / кэш / база данных)
- HTTPS / CSRF_COOKIE_SECURE / SESSION_COOKIE_SECURE
- Настройки логирования
-
Обзор часто используемых команд Linux
-
Установка и конфигурирование основных сервисов Linux
-
Использование uWSGI/Gunicorn и Nginx
- Сравнение Gunicorn и uWSGI
- Для простых приложений, не требующих большого количества настроек, Gunicorn является хорошим выбором. UWsgi имеет более сложную кривую обучения по сравнению с Gunicorn. По умолчанию параметры Gunicorn подходят для большинства приложений.
- UWsgi поддерживает гетерогенную среду.
- Поскольку Nginx сам поддерживает uwsgi, его обычно используют вместе с uwsgi для онлайн-развертывания. UWsgi представляет собой полнофункциональное wsgi-соединение со множеством возможностей для настройки.
- В плане производительности Gunicorn и uwsgi примерно равны.
-
Использование технологии виртуализации (Docker) для развертывания тестовой и рабочей среды##### Тестирование производительности
-
Использование Apache Bench (AB)
-
Использование SQL Slammer (SQLslap)
-
Использование SysBench
Автоматизация тестирования
- Использование Shell и Python для автоматизации тестирования
- Использование Selenium для автоматизации тестирования
- Selenium IDE
- Selenium WebDriver
- Selenium Remote Control
- Введение в тестовый фреймворк Robot Framework
- Оптимизация базы данных MySQL
- Улучшение производительности веб-сервера
- Настройка балансировки нагрузки Nginx
- Реализация высокой доступности с помощью Keepalived
- Оптимизация производительности кода
- Использование многопоточности
- Асинхронизация
- Оптимизация доступа к статическим ресурсам
Комментарии ( 0 )