Блог Максима Федорова

PHP разработчик. Пишу про инструменты в работе, о своих наблюдениях, хобби и проектах.

Портфолио   •   Github    •    Почта    •    Помогаю на Тостере

Разработка через TDD

Андрей Солнцев пишет браузерную игру через Unit тесты и UI тесты.
Делает на языке Java, но абсолютно понятно каждому.

15 апреля   TDD   разработка

Абстракции и как они текут

Статья будет полезна начинающим разработчикам и менеджерам.

В одном из проектов дважды столкнулся с утечкой абстракций. Расскажу о том, что это такое, какие проблемы из-за этого возникают.

Абстракция

По определению Википедии, абстракции — это «придание объекту характеристик, которые чётко определяют его концептуальные границы, отличая от всех других объектов».

Вообще абстракции окружают нас повсюду, примеры: город, государство, или коммерческая компания. Операционная система в компьютере — абстракция над драйверами, драйвера — абстракция над самим устройством компьютера. Да и сам компьютер — абстракция, по сути это полупроводники, провода, катушки и прочие железяки, но мы все это концептуально объединили и работаем как с единым целым — значит абстракция.

Каталог в интернет-магазине конечно же тоже абстракция, о нем дальше и поговорим.

Абстракции текут

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

Реальный пример. У нас в компании приходит много товаров из Китая и Турции разных брендов. Исторически сложилось, что в 1С карточки товаров объединяются в группы по брендам (это, к слову, абстракция — менеджер выделил товары по определенным границам, которые совпадают с брендом).

Это хорошо работает — менеджеру удобно работать с клиентом и показывать целые линейки брендов. Но возникает как всегда НО — часто приходит товар неизвестного бренда в количестве 1-2 вещей и таких товаров много. Проблема — под одну вещь заводить группу с брендом — неудобный и лишний труд. Тогда менеджер решает создать помимо группы брендов одну отдельную группу — группу «Китай», в которую накидывает единичные товары произвольных брендов.

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

Проблемы утечек

Проблема на первый взгляд невинная — менеджеру удобно работать, в случае чего новый менеджер разберется, хотя если товаровы больше десятка тысяч — поиск какого-то товара по бренду (когда сам товар в группе «Китай») может попить ему крови.

Но 1С в 21 веке почти всегда работает бок о бок с веб-системами — выгрузка в интернет-магазин, выгрузка партнерам, отчеты и статистика.

Рассмотрим интернет-магазин. В интернет-магазине есть куча абстракций и самые явные — меню категорий и фильтр товаров. Исторически сложилось, что категории в первую очередь строятся по виду товара (джинсы, куртки) или полу (М и Ж), но не по брендам. Тогда бренд нам нужно сделать одним из свойств фильтра и тут мы получаем первые проблемы — пользователь сайта среди возможных брендов видит бренд с названием «Китай», так как мы взяли утекшую абстракцию за значение свойства.


Избегайте утечек абстракций по возможности — это чревато проблемами.



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

Текут в любом месте

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



Каково было мое удивление, когда спустя некоторое время в меню для сайта я увидел данные для  продавцов розничного магазина :) Да-да, это чистой воды утечка абстракции.

Чем это чревато? Меню может быть несколько для нескольких сайтов, к какому из них прикреплять данные для розничного магазина? :) Или будет путаница в отчетах, ведь в некоторых меню нет этих значений.

17 марта   Абстракции

Домены .dev в Хроме принудительно переадресуются на https (это нормально)

Google Chrome насильно перенаправляет все домены вида example.dev начиная с версии браузера 63 от 7 декабря 2017, даже если их используете локально и они прописаны в файле hosts.
Не помогает даже настройка браузера в HSTS.
Потому у некоторых программистов могут вылезти баги... сегодня вот не мог понять, что за Х**** приключилась.

Дело в том, что этот домен принадлежит Гуглу и они решили насильно всех пользователей своего браузера кидать на https. Это также скорее всего будет и на производных Хрома — например в Яндекс-браузере.

Что делать в этом случае?

Пара вариантов на самом деле:

  • Свои локальные проекты прописывайте с доменами .localhost, .invalid, .test, or .example и др неконфликтные синонимы
  • Используйте Firefox (или Safari) для разработки
2017   chrome

Почему массив начинается с нуля?

UPD: читаем комментарии — мое объяснение не совсем верное, но будет понятно каждому.

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

Попробую наглядно объяснить, почему так принято в этом самом программировании и зачем это нужно.

Точка отсчета

Чтобы обозначить проблему при использовании отсчета массива не с нуля, а с единицы, приведу пример:

Вам нужно вывести набор значений — например динамику посещений кафе и эффективность той или иной рекламы... нужно вывести количество людей за месяц.

Когда вы будете выводить на графике или в таблице данные, вы сразу столкнетесь с тем, что 1 — будет результат за январь, а 12 — результат за декабрь. А где же будет исходно значение? Относительно чего будет прирост в январе?

Правильно! К моменту подсчета у вас должно быть какое-то значение, оно может быть равно нулю или иметь какое-то численное значение. И в массиве значений оно будет первым:

{
0 => 2 тыс // столько было например в прошлом месяце, если кафе открылось, то оно будет равно 0
1 => 1.7 тыс // посещения в январе
2 => 2.1 тыс // посещения в феврале
3 => 1.9 тыс // посещения в марте
...
12 => n тыс  // посещения в декабре
}

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

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

Когда нужно вывести первый элемент массива уже на автомате пишешь

$array[0]

где 0 — индекс первого элемента :)




Вроде как даже создатель языка Python (по-нашему Питон) хотел ввести индексацию массивов с единицы, но сообщество восприняло это в штыки...

Поиск товаров в интернет-магазине от Яндекса

У Яндекса в бета-тестировании появился крутой сервис, который помогает искать товары в интернет-магазине.

Это именно полнотекстовый поиск по характеристикам, названиям, брендам и описанию товаров. Чтобы он заработал — нужно добавить свой магазин в поиск и добавить YML-фид, который подходит для Яндекс.Маркета.

Пример формата подходящего файла




YML-фид для поиска

Это основной момент в работе поиска. Для индексации Яндексу нужны данные в формате Яндекс.Маркета. В этом файле нужно указать все актуальные данные для каждого товара. Чем подробней будет расписан товар, тем точнее будет искать поиск — указать пол, цвет, мощность и при наборе этих значений поиск будет выдавать максимально подходящие варианты.

Пример работы с параметром «Цвет»




Лингвистическая мощь Яндекса

Обычный поиск на обычном сайте имеет недостаток — он ищет точное совпадение символов. С поиском Яндекса можно позволить себе писать с ошибками или забыть поменять раскладку.

Вводим: «l;bycs gfynfvj xthy», по-русски это «джинсы пантамо черн»

Отчасти такое могут делать поисковые решения Sphinx или ElasticSearch, но для магазина без штата программистов — это решение лучшее.




Койот — это шакал

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

В чем фишка. Можно воспользоваться этим лайфхаком и  добавить у товара в своем магазине поле «Синонимы» и в него складывать через запятую все синонимы к товару, или это можно делать программно или через Эксель, как угодно... и останется только вывести в YML-файл и поиск должен подхватить эти значения.




Далее будут статьи:

  • Вывод поиска через виджет от самого Яндекса
  • Вывод результатов поиска через Яндекс.АПИ в формате JSON (как на скринах)



Если хотите себе такой — пишите на hello@maksfedorov.ru

Фильтрация задач по спискам или доскам в Trello

При работе с Trello иногда появляется задача — вывести сразу с нескольких досок актуальные задачи. или вывести по исполнителю и активности. Например есть 3-4 доски с разными проектами (разные сайты, или по отделам — дизайн и разработка) и нужно например вывести со всех досок одновременно все задачи из списка «Задачи» или из списка «ToDo».

Оказывается есть команды, которыми можно выводить тикеты как в фильтре — по названию списков, по активности, по людям и особенностям (с вложениями или описанием).

Например вывожу тикеты с разных досок, в каждой из которых есть список Задачи:

Доступные операторы

-operator — если добавить минус, то задачи с последующей отборкой не выведутся, например -has:members выведет все тикеты, никому не назначенные
@name — выведет тикеты, назначенные данному пользователю, @me выведет ваши картчоки
label: — выведет тикеты по точному названию, например label:«fix header»
board:id — выведет тикеты с определенной доски
list:name — выведет тикеты по названию списка
has:attachments, has:description, has:cover, has:members — выведут тикеты, которые содержат вложения, описания, обложку или участников соответственно
created:day — выведет тикеты, созданные за сутки, сожно вывести за неделю (week) или месяц (month)
edited:day — выведет тикеты, отредактированные за сутки
is:open, is: archived — выведут открытые и закрытые тикеты


Можно перейти отдельно на страницу поиска и фильтровать свои тикеты:

2017   trello   Советы

Тестовые задания для junior программиста на PHP

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

Тестовые задания Yii2

Создание REST API
Реализовать CRUD с регистрацией для авторов и книг. Подробнее

Парсер видео
Создать парсер видео с Youtube, Rutube, Vimeo — парсинг данных по ссылке или iframe и занесение их в БД. Подробнее

Агрегатор логов Apache
Собрать логи сервера и записать их в БД, также вывести с возможностью фильтрации. Подробнее




Тестовые задания на Symfony

Приложение для управления резюме
Приложение, в котором можно отследить эффективность каждого резюме и каждой версии резюме. Подробнее

Игра «Электрик»
Усложненная версия игры — переключение лампочек по клику с эффектом неожиданного погасания лампочки. Подробнее

Система пользователей для заказа запчастей
Реализовать раздел, в котором пользователи смогут создавать запросы на запчасти, а магазины, у которых есть запчасти, соответствующие запросам пользователей, смогут получать эти запросы. Подробнее




Тестовые задания на фреймворках

Форма обратной связи (Laravel)
Форма обратной связи с фиксацией заявок и возможностью их обработки менеджером. Подробнее

Парсер новостей из RSS изданий (CodeIgniter)
Нужно брать статьи из 5 источников RSS и сохранять их в БД. Подробнее

Минисправочник (задание в 2ГИС)
Реализовать справочник с адресами, компаниями и зданиями. Нужно реализовать REST и возможность выборки по радиусу/квадрату от заданного положения. Подробнее




Тестовые задания строго без фреймворка

Тестовое задание для web-разработчика (дискретка)
Реализовать структуру БД и класс(-ы) для работы с ориентированным нецикличным графом. Подробнее

Расписание поездок курьеров в регионы
Вывод занятых и свободных курьеров с возможностью фильтрации и данными по поездкам. Подробнее

Создание REST без фреймворков под высокие нагрузки
Новостной каталог с рубриками, авторами и новостями для 100 тыс записей. Реализация REST. Подробнее

Менеджер задач
Обычный менеджер задач. Подробнее

Сократитель ссылок без фреймворка
Генерация короткого url с записью в БД и проверкой уникальности. Должна работать переадресация. Подробнее

Напишите REST API для генерации рандомного числа
Каждой генерации присваивать уникальный id по которому можно получить результат генерации. Должны быть доступны 2 публичных API метода generate() и retrieve(id)




Куда без блокчейна в 2017 году? :)

Список дел на Solidity
Реализовать, используя язык Solidity смарт-контракт для добавления записей... Подробнее



Также читайте статью на vc.ru Как джуниор-разработчику найти работу

На Хекслете опубликовали список тестовых заданий, но для разных языков.

Отвечаю на вопросы по php

Готов помочь с проблемным кодом на php. Присылайте вопросы, примеры кода и описание задач, которые вы пытаетесь решить. Мне будет полезно отрабатывать навыки, вам возможно найдется решение. Ну сайт делать вам не расскажу как, а вот как настроить сервер, починить отправку писем или как работать с циклом, массивом или классом— велкам!


Присылайте вопросы в Вконтакте или на почту

Помогаю на Тостере

2017   Помощь

Верные друзья джуниора

Неделю назад устроился младшим программистом в крутую команду разработчиков — буду участвовать в разработке двух сервисов. Хочу поделиться своими недельными выводами.

Уметь в контроль версий (GIT)

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

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

И еще:

Следуйте GIT WORKFLOW

Ссылки:
https://habrahabr.ru/post/60030/
https://habrahabr.ru/post/106912/

Любить следующего парня

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

В итоге на одном проекте не было нужных для php модулей языка. На двух сыпались миграции — пришлось качать с тестового сервера копию базы (что тоже нужно догадаться — где и как взять доступы к ним?), на этих же проектах нужно было узнать — какой доступ к админ-панелям. На третьем все было хорошо, но чтобы создать администратора — нужно было пользоваться консольным приложением, команды которого (как и сам факт его наличия) знает только его разработчик — так себе зависимость ¯\_(ツ)_/¯

По итогу дня я вхреначил в README у каждого проекта инструкцию с установкой, а также вставил описание проблем и прямо захреначил коммиты в prod-ветку — с ветками в гите на тот момент я еще не разобрался ¯\_(ツ)_/¯

Делай инструкции для следующего парня!

Это сбережет новичку нервы, а опытному сотруднику время.

Уметь в  Linux

Очень важно знать консоль и работу с Линуксом. Хорошее знание SSH, настройки хостов в nginx, да и много чего — пригодилось практически с первого дня. Даже чуток помог другому новичку. Кстати почти вся команда разработчиков работает либо под Убунтой, либо под Мак-ОС.

Уметь в автоматические тесты

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

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

Тесты нужны, тесты важны, тесты сложны!

Ctrl + ↓ Ранее