Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 17108 сообщений
Cообщения с меткой

программирование - Самое интересное в блогах

Следующие 30  »
rss_rss_hh_new

«Пока не село Солнце»: Как заставить программистов работать 80-часов в неделю

Среда, 27 Июля 2016 г. 10:21 (ссылка)





/ фото Joshua Blount CC



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



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



Поверхностный взгляд


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



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



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



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



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



А если копнуть глубже?


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



В основном люди заявляют, что программистам нет нужды работать по 60–80 часов в неделю для достижения оптимальной продуктивности. А все потому что продуктивность – не тождественна времени, проведенному в офисе. Программист может сидеть в офисе и 100 часов в неделю, но какой от этого толк, если больше половины времени он будет занят отвлеченной деятельностью, создавая иллюзию бурной деятельности?



Если менеджер оценивает работу разработчика отработанными часами – он неопытен, а значит, его можно обмануть. Ушлый разработчик не откажется от предложения повременной работы, если знает, что может закончить проект гораздо быстрее регламентированных сроков.



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



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



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



На эту тему есть бородатый анекдот, которым поделился один из разработчиков, отвечавших на вопрос:

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

– Это будет стоить 1000 долларов, – сказал механик.

– Вы шутите? Вы же работали всего три минуты! – возмутился мужчина.

На что автослесарь ответил:

– Мне достать гайку обратно?


Есть и другая вариация этой истории:

Одна женщина попросила Пикассо, тогда еще малоизвестного художника, нарисовать ее портрет. Мастер за 30 секунд набросал изображение. И сказал:

– Когда-нибудь этот шедевр будет стоить миллион долларов

– Шедевр? Вы потратили всего 30 секунд на написание, – удивилась женщина.

– Дорогая моя, я потратил 30 лет на то, чтобы научиться создавать шедевры за 30 секунд, – ответил Пикассо.
Чтобы набрать 80 часов, человеку придется работать по 12 часов практически каждый день. В неделе 168 часов. Из них 56 часов мы тратим на сон, 7 часов – на дорогу до работы, 80 – на работу, примерно 17 – на приготовление и потребление пищи, еще 7 часов уходит на домашние дела. Сколько времени остается на общение с семьей, занятия спортом, отдых, саморазвитие? 30 минут в неделю! 5 минут в день!



Технологический директор MD.com Брайан Фокс (Brian Fox) делится своим горьким опытом: «Я работал на таких людей, которым не было дела до моей личной жизни. Когда я захотел уйти, они не понимали, почему я хочу это сделать, заверяли, что любят меня и предлагали увеличение вознаграждения и улучшение условий труда».



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



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



40-часовая рабочая неделя считается эталоном, потому что за 8 часов в день человек успевает выйти на свою пиковую производительность, но не успевает «выдохнуться». Пиковая производительность достигается примерно через 2 часа после начала рабочего дня – это время на «разгон».



За 2 часа до конца рабочего дня производительность падает, человек начинает отвлекаться, разговаривать с коллегами, строить планы на вечер. Таким образом, в день мы работаем примерно 4 часа, а не официальные 8.



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







/ фото Nathan CC



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



Это приводит к появлению многочисленных ошибок в коде и багов в программе (разработчики заявляют, что количество багов увеличивается примерно в 2–3 раза, после продолжительного времени работы). Вряд ли работодателю будет выгодна такая ситуация, когда кроме оплаты сверхурочной работы придется оплатить и время на дебаггинг.



Так как можно поднять производительность, дабы закрывать проекты побыстрее, но не «сидеть на горбе» команды разработки? Выход есть – нанять больше разработчиков. Если вы хотите, чтобы программисты работали 80 часов в неделю, – увеличьте численность команды, работающей по 40 часов в неделю, вдвое.



Стоит присмотреться и к более опытным программистам, которые смогут сделать тот же объем работы, что и новички, но за меньшее время. В книге The mythical Man-Month, описывающей разработку IBM OS/360, рассказывается, как компания отбирала разработчиков с производительностью в десять раз большей, чем у самых непродуктивных кадров.



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



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



Существует парадокс: если разработчик общается с руководством – он не работает, если разработчик просиживает штаны на совещании – он не работает, но, если он обсуждает вопросы программирования с коллегами – он работает.



Заключение


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



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



P.S. Интересные материалы из нашего блога:







Как вы относитесь к сверхурочной работе?


























































Никто ещё не голосовал. Воздержавшихся нет.





Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/306216/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] Простой, универсальный и надёжный язык управления принтером IDOL

Вторник, 26 Июля 2016 г. 15:08 (ссылка)

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



Язык разметки страницы, он же язык разметки документа, он же PDL, что расшифровывается как Page Description Language и переводится дословно как язык, описывающий страницу. Понятие же «язык управления принтером» пришло из перевода выражения Printer Control Language или сокращенно PCL.



Разные определения и возможно в основе лежат разные принципы и первоначальные задачи, но призвание одно – наладить коммуникацию между вычислительной единицей и принтером. При чем наладить таким образом, чтобы получить на выходе отпечаток максимально приближенный к видимому на мониторе по форме и содержанию (не беря во внимание передачу цвета, что является отдельным поводом для статьи).



Со времен появления первых принтеров у разных производителей появились собственные разработки данных языков. Вот некоторые известные языки в матричной, лазерной, термотрансферной или струйной печати:



— IGP-10

— PGL (Printronix)

— ESC-P (Epson)

— ANSI (Genicom)

— уже известный вам PCL (HP)

— XES (Xerox)

— Prescribe (Kyocera)

— IPDS (IBM)

— Datamax (Datamax)

— TEC (TEC)

— ZPL II (Zebra)

— UBI (Intermec)



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



Рассмотрим историю возникновения и особенности IDOL — одного из языков управления принтерами.



IDOL (Information, Description and Organization Language) дословно переводится как информационный и организационный язык описания. Этот командный язык описания страниц был разработан специалистами производителя промышленных принтеров MICROPLEX еще в 1987 году и был одним из самых первых языков описания (или языком разметки документа, или языком управления принтера). В большинстве случаев функции данного языка одинаковы для всех систем печати оснащенных контроллером MPC (MicroPlex Controller) вне зависимости от режима работы и скорости печати принтера. Контроллер MPC был также разработан на базе научно исследовательского департамента компании Microplex и является отдельным предметом гордости. Использование языка управления IDOL обеспечивает полную совместимость принтерам линеек SOLID и LOGIJET хотя они относятся к разным технологиям печати (лазерная и термотрансферная, цветная или монохромная).



IDOL позволяет печатным решениям MICROPLEX эффективно работать при сверх нагрузках благодаря своей гибкости, скорости и безотказности. Одним из важных условий эффективной печати является минимизация объемов передачи данных. IDOL был разработан на основе этого принципа. Его синтаксическая конструкция двойных ESC-последовательностей сопровождающаяся идентификатором команд значительно уменьшает поток передачи данных. Благодаря IDOL трафик в портах, кабелях и сети остаётся низким, тем самым позволяя всем другим IT операциям проходить на максимальной скорости.



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



Использование языком IDOL так называемого «прозрачного кода» позволяет заменить «ESC» на пригодные для печати символы ASCII. Это удобно, так как зачастую сложно вводить ESCAPE команды непосредственно с клавиатуры. К тому же этот код можно отправить с любого вычислительного устройства.



Язык управления принтером IDOL можно разделить на несколько функциональных групп:



Печать


Команды, охватывающие задачу на печать в целом, таких как выбор необходимого лотка или устройство подачи, включение дуплекса (двусторонняя печать) или нумерации страниц. В отличие от многих принтеров, которые могут дуплицировать только одну страницу принтеры MICROPLEX способны сохранять в RAM многостраничные задачи на печать (обычный принтер под Windows: Стр1…Стр2…Стр1…Стр2…; принтер Microplex: Стр1…Стр1… Стр2…Стр2…). Это позволяет осуществлять многократную печать многостраничного задания. Таким образом информация отправляется в принтер только один раз без необходимости ручной сортировки.



Шрифты


Команды, влияющие на визуализацию текста, такие как выбор стиля шрифта (хранящиеся в EPROM или загруженные через интерфейс в RAM), установка полей, ориентации или интервала. Список возможных изменений: изменение шрифта по высоте и ширине, изменение расстояния между символами и строками, изменение ориентации текста (0

https://habrahabr.ru/post/306436/

Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

О том, как мы на PHP запускали настоящий MS Excel и что из этого вышло

Вторник, 26 Июля 2016 г. 14:54 (ссылка)

Не секрет, что зачастую PHP-программистам приходится решать задачи, весьма далёкие от бытового представления о «веб-разработке». Развитие языка в последние годы привело к тому, что PHP всё чаще считают языком общего назначения, пригодным не только для сайтов, но и для других задач.



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



Дано:


  • Многие наши партнёры (скажем прямо — это крупные банки) любят считать что-то в Excel. Причем «любят» — это очень нежно сказано. Сложнейшие скоринговые модели могут быть «запрограммированы» в Excel, в файле из сотни листов с десятками макросов

  • Перевести «программы», написанные в Excel на какой-либо язык программирования — практически нереально. Это займет уйму времени, а проблема постоянного обновления и проверки корректности делает такую задачу и вовсе нерешаемой





Требуется:


  • Основная информационная система нашей компании написана на PHP. Она содержит в себе как веб-интерфейсы, так и множество консольных сервисов и воркеров.

  • С этими «программами» в Excel нужно как-то взаимодействовать из консольных приложений на PHP — передавать в них данные, обсчитывать, получать результаты





Некоторое время нам хватало возможностей популярной библиотеки PHPExcel. Но когда от бизнеса поступило очередное требование «нужно, чтобы работали макросы, и еще бы хорошо всё это сохранять в PDF», стало понятно, что выбранный путь — тупиковый. Нужно не парсить файлы xlsx, не имитировать просчёт, и даже не использовать Open Office, а научиться взаимодействовать с «настоящим» Microsoft Excel.











В результате недолгих изысканий было решено создать внутренний микро-веб-сервис, который умел бы принять данные, открыть указанный файл Excel, вставить в него принятые данные, просчитать результат и выдать его в качестве ответа клиенту. Заинтересованность в таком веб-сервисе выразили несколько внутренних проектов и работа закипела.



Сервер под Windows? А почему бы нет!



Первым под удар попал отдел dev-ops. Им предстояло подготовить сервер для будущего сервиса. Дело было необычным, поскольку актуального опыта работы с Windows ни у кого нет…



В качестве серверной платформы был выбран Windows Server 2012 R2 standart. Нужно сразу отметить, что «из коробки» Windows совершенно не приспособлена к хостингу приложений на PHP. Требовалось доведение системы до нужного уровня.



Для начала был установлен PowerShellServer ( www.powershellserver.com ). Это позволило нам подключаться к windows-серверу по привычному всем протоколу ssh, не изобретая велосипедов. Поддерживается авторизация по ключам, работает rsync (это важно). Жаль, что в Personal Edition ограничение только на одно одновременное подключение, но для нас это некритично.



Nginx был установлен штатным образом. Взят со страницы nginx.org/ru/download.html Имейте в виду — под windows есть существенные ограничения: только один рабочий процесс, который держит не более 1024 соединений. Впрочем, это опять же было некритично для внутреннего микро-сервиса.



PHP 7.0.9 взят с windows.php.net/download, установлен штатным образом.



Для упрощения перезапуска всего этого «добра» был написан несложный cmd-файл:



cd C:\nginx
taskkill /f /IM nginx.exe
taskkill /f /IM php-cgi.exe

rm C:\nginx\logs\*
start nginx
start -WindowStyle Hidden php\php-cgi -A "-b 0.0.0.0:9000 -c C:\server\php\php.ini"




Первоначальная настройка сервера закончилась успешным выводом страницы с phpinfo(). Однако это было еще только самое начало…



Настраиваем сборку на Windows или Как наступить на все подводные камни?



Мы внутри компании используем Continuous Integration. Всегда. Для любого, сколь угодно малого проекта. Примерный план развертывания выглядит так:




  • Сервер Teamcity следит за изменениями в нужных ветках репозитория (в данном конкретном случае workflow был упрощен до предела и ветка была фактически одна — master)

  • Он же запускает сборку проекта при появлении изменений:


    • Содержимое репозитория с сервера TeamCity с помощью rsync доставляется на целевой сервер, во временную папку (это даёт нам возможность сэкономить на агентах TeamCity)

    • Там же, с помощью ssh, запускается билд-скрипт на phing, который и делает основную работу:


      • Переносит код в постоянное место

      • Устанавливает зависимости через composer

      • Раскладывает конфиги

      • Применяет миграции и так далее...

      • И, наконец, переключает симлинк current (это у нас wwwroot), на новую папку









Что потребовалось далее? ssh-сервер уже установлен, rsync выполняется корректно. Установим phing:





Git for Windows берем с git-scm.com, устанавливаем, проверяем корректную работу.



Точно по такой же схеме поступаем с composer, только bat-файл пишем сами и он будет значительно проще:

@echo off
if "%PHPBIN%" == "" set PHPBIN=C:\server\php\php.exe
"%PHPBIN%" "C:\nginx\php\composer.phar" %*




Вроде бы всё готово. Запускаем сборку… fail!



Причина 1. Нужно установить расширение php_openssl.dll, иначе Phing не сможет работать с репозиториями через SSL. Проблем не доставило.



Причина 2. Более серьезная. В нашем сценарии сборки используется техника переключения симлинка на папку со свежей сборкой на последнем шаге. Примерно так:




В результате получается что-то вроде

symlink: "c:\server\domains\this.service\master\current" => "c:\server\domains\this.service\master\2016-04-01-12-34-56"



Оказалось, что создать символическую ссылку на NTFS — не проблема. Проблема ее удалить… Отчего-то операция удаления симлинка требует прав администратора, которых у обычного PHP нет и быть не может.



Нам помогла утилита junction ( technet.microsoft.com/en-us/sysinternals/bb896768 ). С ней вышеуказанный кусок сценария стал выглядеть примерно так:







Итак, всё встало на свои места, сборка заработала, как ей и положено. Настала пора писать код!



COM-объекты в PHP



Надо отметить, что собственно код сервиса не доставил никаких проблем.



Как запустить приложение Microsoft Excel и загрузить в приложение существующий файл?

namespace App\Components;

class Excel
{

protected $xls;

public function __construct($filename = null)
{
$this->xls = new \COM("Excel.Application");
// @todo: выключить, если не требуется видеть работу приложения
$this->xls->Application->Visible = 1;
$this->xls->DisplayAlerts = 0;
if (empty($filename)) {
$this->xls->Workbooks->Add();
} else {
$this->xls->Workbooks->Open($filename);
}
$this->xls->Workbooks[1]->Activate();
}
}




Как закрыть приложение после окончания работы скрипта?

    public function __destruct()
{
$this->xls->Workbooks[1]->Close(false);
$this->xls->Quit();
}




Установить значение ячейки или диапазона?

    public function setValue($range, $value)
{
$this->xls->Range($range)->Value = iconv('UTF-8', 'Windows-1251', $value);
}




Прочесть значение из ячейки или диапазона?

    public function getValue($range)
{
return iconv('Windows-1251', 'UTF-8', $this->xls->Range($range)->Value);
}




Экспортировать книгу в PDF?

    const FORMATS = [
'PDF' => 0
];

public function saveAs($filename, $format = self::FORMATS['PDF'])
{
// Будь проклят тот день, когда разработчики MS-DOS придумали обратные слэши!
$this->xls->Workbooks[1]->ExportAsFixedFormat($format, str_replace('/', '\', $filename));
}




Что надо сделать, чтобы вся эта безумная магия заработала?

Добавить расширение php_com_dotnet.dll





Вместо заключения



Довольно феерично наблюдать за сервером: при приходе запроса мгновенно открывается Excel, запускается экспорт и потом также мгновенно всё это хозяйство закрывается :)



Удачи и не наступайте на те же грабли!



Литература:


  1. php.net/manual/en/book.com.php

  2. msdn.microsoft.com/ru-ru/library/wss56bz7.aspx

  3. geektimes.ru/post/50878


Original source: habrahabr.ru.

https://habrahabr.ru/post/306408/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[recovery mode] Бот-революция идет полным ходом

Вторник, 26 Июля 2016 г. 14:09 (ссылка)





Об этом свидетельствует подготовленный к запуску релиз платформы imperson.ai. Возможно, этот проект не вызовет среди мировой общественности такой же бурный ажиотаж, как Pokemon Go. Но польза для бизнеса может стать куда более ощутимой



На днях компания Imperson, название которой с английского языка означает “обезличенный”, выпустила в релиз корпоративный проект — платформу imperson.ai, суть которой — создание, тестирование, внедрение и управления диалоговыми ботами Facebook Messenger, Skype, Kik, Slack, Twitter, Amazon Echo, SMS и многими другими.



Что все это может означать?



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



По информации, предоставляемой компанией Imperson, диалоговые боты будут помогать в продвижении и продаже товаров и услуг широкой аудитории.



Запуск imperson.ai предоставит digital-агентствам доступ к самой передовой технологии для создания и управления несколькими разговорными персонализированными ботами. Они будут способны обучаться и подстраиваться под стилистику общения организации, которую они будут представлять.



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



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



Эрез Баум, соучредитель и генеральный директор Imperson, так прокомментировал грядущий запуск платформы:



“Мы видим огромный потенциал в быстрорастущем рынке ботов. Сегодняшнее представление о ботах достаточно примитивно. Они основаны на меню, боты не могут дифференцироваться друг от друга и представляют нечто обезличенное. Релиз нашей новой платформы позволит креативным людям, представляющим бренды и digital-агентства, создавать более полный и глубокий сценарий общения ботов, которые будут общаться с потребителями “один на один” и тем самым располагать их к компании”.



К чему приведет запуск этого проекта — нам только предстоит узнать.



Однако, уже сейчас прослеживается четкая тенденция замены человеческой коммуникации на искусственный интеллект.



Станет ли это решением проблем обратной связи и человеческого фактора? Смогут ли организации предоставлять клиентам более качественное обслуживание? Будем следить за новостями.







BYYD • Мобильная рекламная платформа

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/306424/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Даты среди цифр числа Пи: некоторые мысли с позиции статистики и нумерологии

Вторник, 26 Июля 2016 г. 13:41 (ссылка)



Перевод поста Майкла Тротта (Michael Trott) "Dates Everywhere in Pi(e)! Some Statistical and Numerological Musings about the Occurrences of Dates in the Digits of Pi".

Код, приведенный в статье, можно скачать здесь.

Выражаю огромную благодарность Кириллу Гузенко KirillGuzenko за помощь в переводе и подготовке публикации

Содержание

Получим все даты за последние 100 лет

Найдём все даты в цифрах числа пи

Статистика всех дат

Первые появления дат

Даты в других представлениях и других константах
В недавнем своём посте (см. перевод поста "3/14/15 9:26:53 Празднование «Дня числа Пи» века, а также рассказ о том, как получить свою очень личную частичку числа пи" на Хабре) Стивен Вольфрам писал об уникальном положении векового дня числа пи и представил разные примеры содержания дат в цифрах числа пи (здесь и далее — в десятичном представлении). В этом посте я рассмотрю статистику распределений всех возможных дат за последние 100 лет в первых 10 миллионах цифр числа пи. Мы увидим, что 99,998% цифр представляют собой какую-то дату, и что можно обнаружить миллионы дат в первых десяти миллионах цифр числа пи.



Я сосредоточусь на датах, которые могут быть заданы не более чем шестью цифрами. То есть я смогу одназначно задавать даты в промежутке длительностью в 36 525 дней, начиная с 15 марта 1915 года и заканчивая 14 марта 2015 года.



Начнём с графической визуализации нашей темы для задания настроения.







Получим все даты за последние 100 лет



Как и обычно, день числа пи в этом году выпал на 14 марта.







С векового дня пи 20 века прошло 36 525 дней.







Создадим список из всех 36 525 рассматриваемых дат.







Для дальнейшей работы определим функцию dateNumber, которая для заданной даты возвращает порядковый номер даты, начиная с первой (15 марта 1915 г. имеет номер 1).







Месяцам с сентября по январь я позволю задаваться лишь одной цифрой — то есть 9 для сентября вместо 09; аналогично и для дней. То есть некоторые даты могут быть заданы разными последовательностями цифр. Функция makeDateTuples генерирует все последовательности целых чисел, представляющих даты. Можно использовать несколько различных обозначений дат — всегда с нулями или всегда в короткой записи. С опциональным включением нулей в запись дней и месяцев получится больше возможных соответствий и больше результатов, так что я буду использовать их в дальнейшем. (А если вы предпочитаете обычный формат записи дат в виде день-месяц-год, то тогда нужно будет просто внести изменения в функцию makeDateTuples).







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







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







Для быстрого (за постоянное время) повторяющегося распознавания последовательности как даты я задам функции dateQ и datesOf. datesOf дает нормализованную форму последовательности цифр даты. Начнем с создания пары последовательностей и их интерпретации как дат.







Вот некоторые примеры.







Большинство (77 350) последовательностей могут быть однозначно истолкованы как даты; некоторые (2700) имеют две возможные интерпретации.







Вот некоторые из последовательностей цифр с двумя интерпретациями.







Последовательность {1,2,1,5,4} имеет две интерпретации — как 21 января 1954 или как 1 декабря 1954 — восстановленные с помощью функции datesOf.







Это количества четырех-, пяти-, и шестизначных представлений дат.







А это число определений каждого из типов, установленных для функции datesOf.







Найдём все даты в цифрах числа пи



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







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







Используя определенные выше функции dateQ и datesOf, я могу теперь быстро найти все последовательности цифр, которые могут быть интерпретированы как даты.







Вот некоторые найденные интерпретации дат. Каждый подсписок имеет вид:



{date, startingDigit, digitSequenceRepresentingTheDate}

(дата, начальная цифра, последовательность цифр представляющих дату).







Мы нашли около 8,1 млн. дат, представленных четырьмя цифрами; около 3,8 млн. дат — пятью; около 365 тыс. дат — шестью, итого в сумме более 12 млн. дат.







Обратите внимание, что я мог бы использовать строковые функции обработки (особенно StringPosition), для поиска позиций последовательностей дат. И, конечно, я бы получил тот же результат.







В то время как использование StringPosition хорошо подошло бы для поиска одной даты, работа же со всеми 35 000 последовательностей заняло бы гораздо больше времени.







Остановимся на секунду и посмотрим на счётчик найденных последовательностей из 4 цифр. Из 10 000 возможных четырёхзначных последовательностей используется 8 100, при этом каждая из них появляется в среднем (1/10)

https://habrahabr.ru/post/306420/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Elixir: начинаем работу с Plug

Понедельник, 25 Июля 2016 г. 12:41 (ссылка)



В мире Elixir, Plug представляет собой спецификацию, позволяющую различным фреймворкам общаться с различными web-серверами, работающими в Erlang VM.

Если вы знакомы с Ruby, то можете провести аналогию с Rack: Plug пытается решать те же проблемы, но только другим способом. Понимание основ работы Plug позволит лучше разобраться как с работой Phoenix, так и других web-фреймворков, созданных на языке Elixir.







Роль Plug



Вы можете думать о Plug как о кусочке кода, который получает структуру данных, осуществляет с ней какие то трансформации, и возвращает ту же структуру данных, но уже частично модифицированную. Та структура данных, с которой работает Plug обычно называется соединением (connection). В этой структуре храниться всё что требуется знать о запросе (пер: и об ответе тоже).



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



Сама структура данных, представляющая соединение — обычная Elixir структура, называемая %Plug.Conn{} (документацию по ней можно найти здесь).





Два различных типа Plug



Существуют два различных типа Plug: Plug-функция и Plug-модуль.



Plug-функция — любая функция, которая в качестве аргумента принимает соединение (это тот самый %Plug.Conn{}), и набор опций, и возвращает соединение.



def my_plug(conn, opts) do
conn
end


Plug-модуль — это в свою очередь любой модуль, который имеет следующий интерфейс: init/1 и call/2, реализуемый таким образом:



module MyPlug do
def init(opts) do
opts
end

def call(conn, opts) do
conn
end
end


Интерес вызывает тот факт, что функция init/1 вызывается на этапе компиляции, а функция call/2 — во время работы программы.



Простой пример



Перейдём от теории к практике и создадим простейшее приложение, использующее Plug для обработки http запроса.



В начале, создадим новый проект с помощью mix:



$ mix new learning_plug
$ cd learning_plug


Отредактируем файл mix.exs, добавив в качестве зависимостей Plug и Cowboy (это web-сервер):



# ./mix.exs

defp deps do
[{:plug, "~> 1.0"},
{:cowboy, "~> 1.0"}]
end


Подтянем зависимости:



$ mix deps.get


и мы готовы начинать работу!



Наш первый Plug будет просто возвращать "Hello, World!":



defmodule LearningPlug do
# The Plug.Conn module gives us the main functions
# we will use to work with our connection, which is
# a %Plug.Conn{} struct, also defined in this module.
import Plug.Conn

def init(opts) do
# Here we just add a new entry in the opts map, that we can use
# in the call/2 function
Map.put(opts, :my_option, "Hello")
end

def call(conn, opts) do
# And we send a response back, with a status code and a body
send_resp(conn, 200, "#{opts[:my_option]}, World!")
end
end


Для использования этого модуля, запустим iex с окружением проекта:



$ iex -S mix


и выполним следующие команды:



iex(1)> Plug.Adapters.Cowboy.http(LearningPlug, %{})
{:ok, #PID<0.150.0>}


Мы используем Cowboy в качестве web-сервера, указывая ему использовать наш Plug. Второй аргумент функции http/2 (в данном случае пустой Map %{}) — это тот самый набор опций, который передастся в качестве аргумента функции init/1 в наш Plug.

Web-сервер должен был стартовать на порту 4000, поэтому если вы откроете http://localhost:4000 в браузере, то увидите "Hello, World!". Очень просто!



Попробуем сделать наш Plug чуточку умнее. Пусть он анализирует URL, к которому мы делаем запрос на сервер, и если к примеру мы пытаемся получить доступ к http://localhost:4000/Name мы должны видеть “Hello, Name”.



Так как соединение представляет фигурально всё, что нужно знать о запросе, то оно хранит и его URL. Мы можем просто осуществить сопоставление с образцом этого URL для создания такого ответа, который мы хотим. Немного переделаем call/2 функцию следующим образом:



def call(%Plug.Conn{request_path: "/" <> name} = conn, opts) do
send_resp(conn, 200, "Hello, #{name}")
end


Вот она мощь функционального программирования! Мы сопоставляем только ту информацию, которая нам нужна (имя), а затем используем её для генерирования ответа.



Pipeline и как это работает



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



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



pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end


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



pipeline :api do
plug :accepts, ["json"]
end


Конечно, pipeline макрос из предыдущего примера встроен в Phoenix. однако и Plug сам по себе предоставляет возможность строить такую pipeline: Plug.Builder.



Вот пример его работы:



defmodule MyPipeline do
# We use Plug.Builder to have access to the plug/2 macro.
# This macro can receive a function or a module plug and an
# optional parameter that will be passed unchanged to the
# given plug.
use Plug.Builder

plug Plug.Logger
plug :extract_name
plug :greet, %{my_option: "Hello"}

def extract_name(%Plug.Conn{request_path: "/" <> name} = conn, opts) do
assign(conn, :name, name)
end

def greet(conn, opts) do
conn
|> send_resp(200, "#{opts[:my_option]}, #{conn.assigns.name}")
end
end


Тут мы сделали композицию трёх модулей PlugPlug.Logger, extract_name и greet.

extract_name использует assign/3 для того, чтобы поместить значение с определённым ключом в соединение. assign/3 возвращает модифицированную копию соединения, которое затем обрабатывается greet_plug, которое наоборот читает это значение, чтобы затем сгенерировать ответ, который нам нужен.



Plug.Logger поставляется вместе с Plug и, как вы догадались, используется для логирования http запросов. Прямо из коробки доступен определённый набор "батареек", список можно найти тут



Использовать такую pipeline так же просто как и Plug:



Plug.Adapters.Cowboy.http(MyPipeline, %{})


Следует не забывать о том, что модули используются в той же последовательности, в которой они определены в pipeline



Ещё одна фишка: те композиции, которые созданы с помощью Plug.Builder — также реализуют интерфейс Plug. Поэтому, к примеру, можно составить композицию из pipeline и Plug, и продолжать до бесконечности!



Подытожим



Основная идея в том, что и запрос, и ответ представлен в одной общей структуре %Plug.Conn{}, и эта структура передаётся "по цепочке" от функции к функции, частично изменяясь на каждом шагу (пер: изменяется фигурально — данные иммутабельны, поэтому дальше передаётся изменённая копия структуры), до тех пор пока не получится ответ, который будет послан назад. Plug — это спецификация, определяющая как это всё должно работать и создающая абстракции так, что различные фреймворки могут общаться с различными web-серверами до тех пор, пока они выполняют эту спецификацию.



В "батарейки" к Plug входят различные модули, облегчающие множество разных распространённых задач: создание pipeline, простой роутинг, куки, заголовки и так далее.



А в конце хочется заметить, что в основе Plug лежит сама идея функционального программирования — передача данных по цепочке функций, которые трансформируют эти данные до тех пор, пока не получится нужный результат. Просто в этом случае данные — это http запрос.



Update: на самом деле это перевод, почему-то создался как публикация. Исправляю, приношу извинения. Дополнительно — мелкие орфографические исправления.


Original source: habrahabr.ru.

https://habrahabr.ru/post/306334/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Делаем многоканальную полнодуплексную рацию

Понедельник, 25 Июля 2016 г. 11:34 (ссылка)

Однажды к нам постучись за помощью – сделать сервис-рацию. После продолжительных поисков клиенту не удалось найти подходящее решение, поэтому он обратился в VoxImplant. Нам стало интересно, что же он там такое задумал и сможем ли мы реализовать его задумку на своей платформе. Нам редко удавалось найти сценарий, который на ней сделать невозможно. В общем, пообщались мы, все внимательно выслушали и пошли писать код. Рация должна была уметь подключаться к нескольким каналам одновременно (аналогично частотам в аналоговых рациях), а также давать возможность говорить в один из подключенных каналов + было желательно отображать активность в канале. Под катом рассказ о том, как мы сделали этот сервис за несколько часов.



Схема работы



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



Логика следующая:



1. Пользователь SDK делает звонок, сценарий (WTGatekeeper) пробрасывает звонок в конференцию

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

3. Локальная конференция обрабатывает сигнальные события join_channel, leave_channel, choose_channel, а также отправляет события channel_activity, channel_connected, channel_disconnected (см. сценарий WTUserConf) в сторону юзера

4. Каналы-конференции (см. сценарий WTChannelConf) просто подключают все входящие звонки из локальных конференций



Итого получается, что по одной конференции создается на каждого пользователя и на каждый канал.



Функционал клиента включает:




  • список каналов с соответствующими элементами управления

  • возможность подписаться на входящий звук от канала

  • кнопка для выбора канала, куда будем говорить

  • кнопка push-to-talk, которая активирует отправку исходящего звука в выбранный канал



Для ускорения процесса мы создали демо приложение с помощью Web SDK и ReactJS. Получился такой интерфейс:



Для реализации визуализации голосовой активности в подключенном канале мы воспользовались встроенным в платформу VAD. На каждый звонок можно повесить обработчик данного события и транслировать на клиент информацию про активность:



call.addEventListener(CallEvents.MicStatusChange, handleChannelAudio);
call.handleMicStatus(true);
function handleChannelAudio(e) {
// Send info about channel audio
user_call.sendMessage(JSON.stringify({
event: "channel_activity",
name: e.call.number().replace("channel_", ""),
active: e.active
}));
}


Визуализацию активности в канале сделали следующим образом:





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



Посмотреть на результат



Вы можете самостоятельно протестировать получившийся сервис и пообщаться в одном из нескольких доступных каналов по этой ссылке. Используйте Chrome/Firefox/другой браузер с поддержкой WebRTC.
Original source: habrahabr.ru.

https://habrahabr.ru/post/305306/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] 10 ошибок, приводящих к оверинжинирингу ПО

Понедельник, 25 Июля 2016 г. 11:27 (ссылка)

Несколько вещей гарантированно будут увеличиваться со временем: расстояния между звёздами, энтропия вселенной и бизнес-требования к ПО. Многие статьи пишут «Не усложняйте!», но не пишут почему или как это сделать. Вот вам 10 ясных примеров.



1. Инженерам виднее


Мы, инженеры, считаем себя умнейшими людьми. Ну, поскольку мы создаём разные штуки. И эта ошибка часто приводит к оверинжинирингу. Если вы спланировали и построили 100 модулей — Бизнес всегда попросит у вас 101-ый, о котором вы никогда не задумывались. Если вы соберётесь с силами и решите 1000 проблем — они придут к вам и выложат на стол 10 000 новых. Вы считаете, что у вас всё под контролем, а на самом деле вы даже не представляете, в каком направлении вас завтра поведёт дорога.

image

За мои 15 лет работы программистом я ещё ни разу не видел, чтобы Бизнес выдал законченные и стабильные раз и навсегда требования к ПО. Они всегда меняются, расширяются. И это природа бизнеса, а не ошибки людей, управляющих им.



Мораль: Казино (бизнес) всегда побеждает





2. Повторное использование кода


Когда Бизнес подкидывает нам всё больше и больше требований (как и ожидается), мы иногда говорим себе: «Ок, давайте попробуем сгруппировать и обобщить всё, что только можно!».

image

Вот почему большинство MVC-систем заканчиваются Большой Моделью или Жирным Контроллером. Но, как мы уже выяснили, бизнес-требования никогда не прекратят добавляться, а значит это путь в никуда. На самом деле нам нужно реагировать на это вот так:

image



Пример: однажды для одного из заказчиков мы разрабатывали модуль профиля пользователя. Начали с классического CRUD-контроллера, ну потому что это же просто профиль пользователя и там всё должно быть просто. Закончилось это всё реализацией 13 различных сценариев создания и заполнения этого профиля: регистрация через социальную сеть, обычная, упрощённая, быстрая с последующим редактированием, совсем иначе выглядящая для подсайтов, и т.д. Они имели между собой очень мало общего. Аналогично отличаются и, например, сценарии «просмотр заказа» и «редактирование заказа».

Попробуйте для начала разделить бизнес-функциональность вертикально, прежде чем делить её горизонтально. Это даже делает более простой задачу разделение монолита на микросервисы. Иногда и вовсе уже становится всё-равно монолит у вас или сервисы. В противном же случае становится всё сложнее и сложнее изменять части вашей системы.



Мораль: Предпочитайте изолированные действия, избегайте комбинирования



Совет: Возьмите некоторую видимую пользователю часть вашей программы (форму\страницу\команду). Сколько переключений контекста понадобиться программисту, чтобы понять весь код, связанный с ней?



3. Обобщим вообще всё


(Несколько перекликается с предыдущим пунктом, но иногда случается и независимо от него)


  • Нужно подсоединиться к базе данных? Давайте напишем Обобщённый Адаптер.

  • Сделать запрос? Обобщённый Запрос.

  • Передать ему параметр? Обобщённый Параметр.

  • Собрать несколько параметров во что-то? Обобщённый Builder.

  • Отразить полученный результат во что-то? Обобщённый Data Mapper.

  • Обработать запрос пользователя? Обобщённый Запрос.

  • Что-то выполнить? Обобщённый Исполнитель.

  • и т.д.





Иногда инженеров заносит. Вместо решения бизнес-проблем они тратят время для выбора правильного родительского класса. А ответ прост.

image



Архитектура ПО всегда играет в догонялки с требованиями бизнеса. Так что даже если вы с помощью какой-то магии найдёте идеальную абстракцию сегодня, в комплекте с ней сразу будет идти срок её годности — см. пункт №1 выше — бизнес всегда побеждает. Так что лучшая характеристика качества сборки вашей архитектуры — как быстро она может быть разобрана. Есть отличная статья о том, как писать код, который будет легко удалить, а не легко изменить.

Мораль: Дублирование кода лучше, чем неверная абстракция



Более того, дублирование кода иногда помогает найти ту самую правильную абстракцию. Потому, что когда вы видите несколько частей системы, использующий одинаковый код одинаковым образом — вы можете понять, что их объединяет. Качество Абстракции определяется качеством её слабейшего звена. Дублирование кода позволяет взглянуть на разные ситуации под разными углами и увидеть границы Абстракции чётче.



4. Написание обёрток для всех внешних библиотек


Существует практика написания обёрток (врапперов) для каждой используемой внешней библиотеки (в основном из-за следования стилю основного продукта, иногда из-за причин, описанных в предыдущих двух пунктах). Очень популярный подход в энтерпрайз-программировании. Программисты на динамических языках вроде Node/Ruby/Python просто добавляют библиотеку и начинают её использовать. Но Энтерпрайз Разработчик на это пойти не может — ему необходимо создать обёртку. А потом ещё обёртку над обёрткой. Возможно, это имело какой-то смысл в 2000-ых, когда большинство библиотек представляли собой мешанину, да и вообще открытого кода было не так много.



Но сегодня уже 2016-ый год. Внешние библиотеки улучшились на порядок. Они стали просто фантастичны. Скорее всего они написаны отличными программистами и оттестированы лучше вашего основного кода. Они имеют внятный API. В них можно встроить логирование. Вам не нужно тратить своё время на написание обёрток вокруг и так уже хорошего кода. Кроме того, большинство обёрток — совершенно бессмысленны. Их интерфейс очёнь тесно связан с лежащей ниже библиотекой, часто просто в виде отражения функций «один к одному». Если в будущем библиотека измениться, большинство кода с использованием данной обёртки также придётся изменить. Создание «агностической» обёртки, способной остаться неизменной даже, например, при полной замене оборачиваемой библиотеки на другую — нетривиальная задача. Такие задачи иногда ставятся с мыслью о потенциальной «конфигурабельности» общего решения, сама идея которого будет рассмотрена чуть ниже.



Мораль: обёртки должны быть исключениями, а не нормой



5. Слепое применение метрик качества кода


Бездумное следования концепциям качества кода (вроде того, что все переменные должны быть объявлены как «private final», каждый класс должен иметь интерфейс) не сделает ваш код АВТОМАТИЧЕСКИ хорошим. Посмотрите, если ещё не видели, на энтерпрайз-версию FizzBuzz или Hello World. Прорва кода. На микро-уровне каждый класс следует принципам SOLID и использует отличные паттерны. Если вы натравите на этот код какой-нибудь инструмент анализа качества кода — он скажет, что это прекрасный продукт, прямо загляденье. Но если вы сделаете шаг назад — то сразу увидите каким кошмаром является эта программа, всего лишь печатающая «Fizz Buzz».



Мораль: всегда делайте шаг назад и смотрите на общую картину.



Аналогично, автоматические средства хорошо определяют тестовое покрытие кода, но совершенно ничего не говорят о том, тестируете ли вы то, что нужно, или нет. Они могут измерить производительность в некотором тесте, но ничего не скажут насколько хорошо ваша программа обрабатывает данные в другом случае. Все они смотрят на микро-уровень: что делает этот класс\метод\строка. И только Человек смотрит на общую картину.



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



5.1. Слои сандвича




Давайте возьмём некоторый тесно связанный функционал и разделим его на 10-20 слоёв, где каждый слой не имеет никакого смысла без остальных. Ну, потому что мы хотим реализовать концепцию «Тестируемого кода», или «Принцип единой ответственности», или назовите это ещё как-нибудь модно. В прошлом это делалось через наследование. Класс А наследуется от Б, который наследуется от С и т.д.

image

Сегодня люди делают всё то же самое, кроме того, что каждый класс теперь представляется парой интерфейс/класс и инжектируется на следующий слой, потому что у нас же SOLID.

image

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



6. Синдром Новинки


Изучили дженерики. Теперь у нас простой «HelloWorldPrinter» станет «HelloWorldPrinter».

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



Изучили паттерн Стратегия. Теперь все операторы «if» будут стратегией.

Почему?



Научились писать DSL. Теперь у нас DSL будет везде и для всего.

Ну я даже не знаю…



Обнаружили моки. Теперь у нас будет замокано всё вдоль и поперёк.

Да ну как же…



Метапрограммирование — шикарная вещь, давайте используем здесь и здесь!

Объясни зачем…



Методы расширения\концепты\что-то ещё — хорошая штука, давайте будем использовать кругом!

А давайте не будем!



Мораль: ничего не надо применять везде и всегда. И раздел «Мораль» тоже не надо бы писать в каждый пункт.



7. «X–сть»



  • Конфигурабельность

  • Безопасность

  • Масштабируемость

  • Поддерживаемость

  • Расширяемость

  • ...





Расплывчато. Неизменно. Трудно поспорить.

Пример 1: Давайте создадим CMS, чтобы клиент смог сам добавлять поля вот в эту форму.

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



Пример 2: Давайте спроектируем большой слой для работы с базами данных, для упрощения «Конфигурабельности». Мы должны получить возможность сменить базу данных правкой одного конфиг-файла.

Результат: За 10 лет работы я видел лишь один проект, где понадобилось менять одну базу данных на другую по объективным причинам. И, когда до этого дошло дело, то «правкой одного конфиг-файла» дело совсем не обошлось. Была масса сопутствующей работы. Несовместимость, пробелы в функционале. А ещё однажды клиент попросил на перевести ПОЛОВИНУ наших моделей данных в новую NoSQL базу данных. У нас был «магический файл» с подключением базы данных, но во-первых, только реляционной, а во-вторых для всех данных, а не для половины. Возможно все эти пляски с конфигурабельностью имеют смысл, когда речь идёт о чём-то вроде Оракловской базы данных, которая стоит как найм 20-ти программистов — там и правда удобно иметь возможность переключиться на что-то другое при необходимости. Но для современных баз данных, всё что нам необходимо — это простой набор вертикальных DAO-классов вместо широкого горизонтального слоя ORM. Не существует единой модели, удачно сочетающей в себе SQL и NoSQL, так что, возможно, нам действительно стоит их разделять, используя в каждом случае то одно, то другое, вместо того, чтобы пытаться совместить несовместимое и городить ужасные неверные абстракции.



Пример 3: Мы построили систему OAuth-авторизации для энтерпрайз-клиентов. Для администраторов этой системы нас попросили добавить ещё один уровень — авторизацию администраторов через Google OAuth. «Потому, что должно быть безопасно». Если кто-то взломает нашу OAuth-авторизацию, нужно чтобы хотя бы учётки администраторов остались недоступны. Google OAuth — надёжная штука, так что возражать тут вроде бы особо нечего.

Результат: Тому, кто захочет взломать данную систему совсем не нужно пробиваться через OAuth-слой. Можно найти уязвимость в чём-нибудь попроще (такие всегда есть). В итоге все затраты на поддержку двух уровней OAuth (а они проходили насквозь через всю систему) дали примерно никаких результатов. Лучше было потратить это время на устранение обычных уязвимостей.

image

Мораль: Не принимайте все эти характеристики с окончанием на "-сть" как неизменную данность. Они имеют свою цену — так что чётко определяйте Сценарий\Историю\Использование.



8. Велосипедостроение


Это всегда круто в начале. Но через несколько лет это уже будет Груз Наследия.

Пара примеров:


  • Свои библиотеки (HTTP, мини-ORM, кеширование, конфигурация)

  • Свои фреймворки (CMS, обработка событий, многопоточность, фоновые задачи)

  • Свои инструменты (система сборки, система деплоя)





Что тут плохого:


  • Тривиальные, казалось бы, задачи на самом деле требуют приличных знаний и глубокого погружения в предметную область. Какой-нибудь «запускатель процессов» требует понимания менеджмента процессов в ОС, работы демонов, системы ввода\вывода и ещё кучи всего. CMS — это не просто что-то, подставляющие данные в шаблоны — там есть зависимости, проверки, визарды, обобщения и т.д. Самая простая на вид библиотека может иметь нетривиальную функциональность.

  • Всё это нужно ещё и поддерживать, обновлять.

  • Если вы выложите код в открытый доступ — всем будет плевать. Ну, может, кроме тех, кто работал над этим кодом раньше.

  • Люди, которые разбираются в этом коде — рано или поздно уйдут. А кроме них в этой реализации не разбирается никто в мире.

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





Мораль: Переиспользуйте. Заимствуйте хорошее. Пересматривайте свои решения.

Если вы всё-же решили строить свой велосипед — по крайней мере делайте его по принципу «внутреннего опенсорса» в своей компании. Объясните людям, зачем это нужно. Покажите первый набросок. Предложите им использовать или улучшать это. И подумайте 10 раз, стоит ли продолжать строить этот велосипед, если даже ваши коллеги не выскажут своего одобрения.



9. Развивайте свой код


Как только вы реализовали что-нибудь определённым образом — все остальные начинают это использовать в том виде, в каком это реализовано. Никто не задумывается, правильно ли это. Пока ваш код работает — это «хороший код». Люди начинают применять его даже для задач, которые он изначально не должен был решать. Получается иногда хорошо, а иногда очень плохо. И тут нужно не бояться брать и менять ваш код, совершенствуя его под текущие задачи. Здоровые программные системы всегда живут, меняются. Нездоровые — лишь дополняются. Если кусок кода не видел коммитов очень давно — с ним что-то не так, он «попахивает». Каждая часть кода должна развиваться. Вот отличная статья, описывающая это.

Вот как команды работают над задачами, а вот как они должны это делать, Каждый День:

image



Мораль: рефакторинг — это часть любой разработки. Никакой код не остаётся неизменным.



10. Неверные оценки сроков


Часто мы видим, как неплохие вроде бы команды или отдельные кодеры вдруг выдают откровенно слабый продукт. Мы смотрим на кодовую базу и удивляемся — «Как же так, неужели это было действительно создано этой командой\человеком, а я же считал их\его такими умными\умным!». Качество требует не только умения, но и времени. Даже умные разработчики часто переоценивают свои возможности. И вдруг обнаруживают себя перед горящим дедлайном, мучительно вписывающих в код ужасный костыль, дающий шанс как-то уложиться в сроки.



Мораль: неверная оценка сроков наносит вред качеству вашего проекта ещё до того, как написана первая строка кода.
Original source: habrahabr.ru.

https://habrahabr.ru/post/306328/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество

Следующие 30  »

<программирование - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda