Pull to refresh
9
0
Send message

Заблуждения программистов относительно времени

Reading time3 min
Views90K
За последние пару лет я потратил много времени на дебаггинг чужих тестов. Это была интересная работа, иногда расстраивающая, но всегда поучительная. Кто-то может подумать, что в тестах нет багов, но конечно баги есть везде, и тесты не исключение.

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

На самом деле, я повидал так много заблуждений, которые оставляют след в чужих (и моих собственных) программах, что посчитал полезным составить список самых частых проблем.
Читать дальше →
Total votes 241: ↑218 and ↓23+195
Comments216

Ремесло программиста. Золотые правила

Reading time14 min
Views29K
imageДанный пост представляет собой выдержку «золотых правил» из примечательной книги Питера Гудлифа «Ремесло программиста».

Кто-то освежит память, кто-то сверится как с чек-листом, а кто-то заинтересуется и прочтет книгу. Т.к. пост получился достаточно объемным, можно добавить его в закладки и периодически к нему возвращаться.
Читать дальше →
Total votes 108: ↑90 and ↓18+72
Comments62

Весёлые (сосисочные) рефакторинги

Reading time2 min
Views72K


Привет, %habrausername%. Я хочу сыграть с тобой в игру.

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

От предыдущего разработчика осталась кучка кода и домашние тапочки. Ты осторожно кладёшь тапочки в мусорную корзину и начинаешь рефакторинг.

Этот код ужасен. Во-первых, нет никого, кто мог бы сказать, зачем этот код писался. Во-вторых, нет никакой документации. Нет даже комментариев, не говоря уже о юнит-тестах. В-третьих, код не структурирован, а имена классов и методов ни о чём не говорят. И, наконец, работать это должно начать не сегодня, и даже не вчера, а внезапно.
Ну как, %habrausername%, пробежал холодок по спине?
Читать дальше →
Total votes 159: ↑144 and ↓15+129
Comments174

Читайте код, с остальным справится компилятор

Reading time3 min
Views3.1K

Введение


Уже не в первый раз мне задают связанные вопросы:
«Зачем ты делаешь так много функций?»;
«Зачем ты выносишь, однократно используемый, код в функции?»;
«Остальные не знакомы с твоими правилами именования функций. Как они будут с этим работать?». Поэтому опишу свое видение проблемы. Ну а сообщество подскажет, к чему же стоит стремиться.
Читать дальше →
Total votes 100: ↑74 and ↓26+48
Comments112

Говнокод или суперархитектура? Сначала говнокод, а потом эволюционный рефакторинг!

Reading time3 min
Views74K
Ответ на статью.

Если вы не разрабатываете ПО для машин или систем автоматического поддержания жизни и тд — нижесказанное работает для вас при грамотном применении.

Сразу скажу — не моя идея, в статье «Проектирования больше нет?» сам Мартин Фаулер писал об эволюционном рефакторинге. А Боб Мартин даже целую книгу запилил с примером поэтапного развития приложения (и не одним), назвав «Быстрая разработка ПО» и продемонстрировав умение виртуозно материться на Java и C++.

Во-первых, говнокод на первом этапе обязателен. Причин куча. Раз — вы ничего не знаете о реальных условиях работы приложения, все ваши домыслы фигня. Пока реальный опыт не получен, пока не занесены первые живые данные реальным пользователем — у вас нет обратной связи. Если вы не согласны, почитайте Макконнелла, миф о стабильных требованиях, и получите левелап.
Читать дальше →
Total votes 202: ↑157 and ↓45+112
Comments170

Практика рефакторинга в больших проектах

Reading time4 min
Views14K
Некоторое время назад я попал в геймдев, где столкнулся с проектами по 2 млн. строк кода, которые пишут десятки программистов. При таких масштабах кодобазы возникают проблемы неведомого мне ранее характера. Об одной и них я хочу вам сейчас рассказать.

Итак, представьте себе следующую ситуацию. Так уж случилось, что вам надо отрефакторить очень большой кусок кода, целую подсистему. Строк, эдак, на 200К. Причем рефакторинг явно выглядит очень крупным, затрагивающим базовые концепции, по которым построена ваша подсистема. Фактически надо переписать всю архитектуру, сохранив бизнес логику. Такое бывает, если, например, вы сделали один проект и у вас впереди новый, и вы хотите в нём исправить все ошибки прошлого. Допустим, по первым прикидкам, на рефакторинг надо месяца 2, не меньше. В процессе рефакторинга всё должно работать, в том числе нельзя мешать другим программистам добавлять новые фичи и чинить баги в подсистеме. Часто такой рефакторинг бывает насколько сложен, что совершенно невозможно замерджить старый код в новый, а также невозможно выкатить результат по частям. Фактически вам надо заменить двигатель самолёта на лету.

Примеры из практики, как моей, так и моих коллег:
  • Переделать всю работу с базой данных с чистого JDBC на Hibernate.
  • Переделать архитектуру сервиса с отсылки-приёмки сообщений на удалённый вызов процедур (RPC).
  • Полностью переписать подсистему трансляции XML файлов в рантайм объекты.


Что делать? С какой стороны подойти к проблеме? Ниже представлен набор советов и практик, которые нам помогают справиться с этой проблемой. Сначала более общие слова, а потом конкретные методики. В общем-то ничего сверхъествественного, но кому-то может помочь.
Читать дальше →
Total votes 55: ↑50 and ↓5+45
Comments51

Минифест (манифест разработчиков-минималистов)

Reading time6 min
Views50K
От переводчика

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

Снова прошу прощения за отсутствие перевода словосочетания “computer science”.


Кратко


  • Боритесь за закон Парето, следите за тем, чтобы 20% вашего труда давало вам 80% результата;
  • Расставляйте приоритеты, ведь минимализм нужен для того, чтобы делать то, что нужно, а не распыляться по мелочам;
  • Лучшее — враг хорошего: сначала просто сделайте, потом сделайте правильно, потом сделайте лучше;
  • Убивайте в зародыше, не бойтесь начать всё сначала. Чем быстрее ошибётесь, тем быстрее научитесь;
  • Повышайте свою ценность. Постоянно думайте о том, чем можно помочь команде, — и развивайтесь в этом направлении;
  • Сперва основы. Мыслите последовательно, ориентируясь на лучшие практики мира Computer Science;
  • Посмотрите с разных сторон. Простое получается тяжелее, чем сложное, поэтому включайте воображение;
  • Синтаксис — основа взаимодействия. Мы пишем код для людей, а не для машин;
  • Не запутывайте. Старайтесь проектировать слоями, по мере возможности не зависящими друг от друга;
  • Вычищайте оставленное-на-всякий-случай. Минимализм борется с отвлекающим от основного.

Читать дальше
Total votes 131: ↑120 and ↓11+109
Comments39

Не пишите комментарии к коду!

Reading time7 min
Views69K

Вступление


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

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

Для понимания проблемы обратимся к Вики, а после перейдем к примерам:

Коммента́рии — пояснения к исходному тексту программы, находящиеся непосредственно внутри комментируемого кода.

Читать дальше →
Total votes 169: ↑97 and ↓72+25
Comments325

Юнит-тестирование для чайников

Reading time15 min
Views1.1M
Даже если вы никогда в жизни не думали, что занимаетесь тестированием, вы это делаете. Вы собираете свое приложение, нажимаете кнопку и проверяете, соответствует ли полученный результат вашим ожиданиям. Достаточно часто в приложении можно встретить формочки с кнопкой “Test it” или классы с названием TestController или MyServiceTestClient.



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

Оно выполняет свою задачу, но сложно для автоматизации. Как правило, тесты требуют, чтобы вся или почти вся система была развернута и сконфигурирована на машине, на которой они выполняются. Предположим, что вы разрабатываете web-приложение с UI и веб-сервисами. Минимальная комплектация, которая вам потребуется: браузер, веб-сервер, правильно настроенные веб-сервисы и база данных. На практике все еще сложнее. Разворачивать всё это на билд-сервере и всех машинах разработчиков?

We need to go deeper
Total votes 70: ↑63 and ↓7+56
Comments65

Версионное хранение данных в Persistent-классах Caché

Reading time9 min
Views3K
В стандартных хранимых классах Caché при модификации записи прежние значения свойств исчезают безвозвратно. Но бывают случаи, когда это нежелательно, когда «все ходы должны быть записаны». В первую очередь, конечно, такое требование возникает при разработке приложений для материально ответственных лиц, для которых критична возможность, например, отменить ошибочное действие и восстановить состояние документа на заданное время, или, что ещё важнее, провести расследование инцидента с попыткой злоумышленника «замести следы» в базе.
В этой статье демонстрируется, как реализовать хранение и восстановление версий для объектов Caché.
Читать дальше →
Total votes 3: ↑3 and ↓0+3
Comments12

TDD в JavaScript. Разработка приложения

Reading time9 min
Views14K
Всем привет. Данная статья посвящается методологии Разработки через тестирование (TDD) в применении c JavaScript.
Напишу лишь вкратце о методологии TDD, более подробную информацию можно почерпнуть из ссылки выше.

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

Читать дальше →
Total votes 48: ↑45 and ↓3+42
Comments26

Притча о покрытии кода тестами

Reading time2 min
Views42K

Ранним утром программист спросил великого мастера:
— Я готов писать модульные тесты. К какому покрытию кода я должен стремиться?
Великий мастер ответил:
— Не переживай о покрытии, просто пиши хорошие тесты.
Программист улыбнулся, поклонился и ушел.

Немного времени спустя другой программист задала этот же вопрос. Великий мастер указал на котел с кипящей водой и сказал:
— Сколько зерен риса я должен положить в этот котел?
Программист с озадаченным видом ответила:
— Как я могу ответить наверняка? Все зависит от того, сколько людей вам надо накормить, насколько они голодны, какие еще блюда вы подаете, сколько риса у вас есть и от многого другого.
— Совершенно верно. — сказал великий мастер.
Второй программист улыбнулась, поклонилась и ушла.
В конце дня...
Total votes 143: ↑127 and ↓16+111
Comments65

BRMS 150 лет назад и сегодня: репозитории правил принятия решений

Reading time7 min
Views17K
Попытки освоить бизнес-логику для ИТ-систем начались в нашей стране примерно в 1820-х. Тогда один из основателей русской кибернетики статский советник (и сын инженера-полковника) Семен Николаевич Корсаков сделал две вот такие штуки:


Прямолинейный гомеоскоп


Простой компаратор

Это то, что мы бы сегодня назвали механическими зачатками современных экспертных систем. Помните новость про то, что IBM распространяет свой искусственный интеллект по больницам? Так вот, С. Н. Корсаков начал делать что-то похожее минимум за 150 лет до этого. Его идея была предельно проста: нужно раздать устройства врачам на местах, и тогда врачи смогут копить опыт вместе, не делать общие ошибки и вообще лечить по стандартам. Компаратор служил средством дифдиагностики, а более простой гомеоскоп мог выступать в роли автомата, куда врач заносил симптомы и получал на выходе заболевание.

То есть, говоря иными словами, Корсаков попробовал создать репозиторий медицинских знаний и систему управления правилами. Поскольку не верил, что одни и те же болезни будут лечиться во всех уголках страны одинаково эффективно и точно.
Читать дальше →
Total votes 37: ↑35 and ↓2+33
Comments9

Основной цикл в Javascript

Reading time9 min
Views77K


Все мы слышали про ajax и node.js. Они прочно обосновались уже не просто в словарном запасе, но и в наборе инструментов веб-разработчика. Ajax — асинхронное подтягивание данных с сервера на страницу, node — фреймворк с асинхронным IO. Но как в таком однопоточном языке, как Javascript, реализуется та самая асинхронность?

Вы, наверное, уже догадались из заголовка, речь пойдет об основном цикле («main loop»).
Читать дальше →
Total votes 190: ↑186 and ↓4+182
Comments41

Новое в СУБД Caché 2013.1: встроенная поддержка WebSockets

Reading time11 min
Views3.8K
В одной из предыдущих статей уже рассматривалась работа с WebSocket на примере собственной серверной реализации этого протокола поверх обычных сокетов.

В СУБД Caché 2013.1 CSP-Шлюз теперь включает поддержку спецификации HTML 5 для WebSocket-соединений между веб-сервером и HTML 5 совместимым браузером. Эта функция доступна для Apache 2.2 и выше, и для IIS 8.0, который является частью Windows Server 2012.

Поскольку в Caché 2013.1 уже встроен Apache 2.4, мы будем наши примеры запускать именно на нём.
Для реализации клиентской части использовался фреймворк ZEN, но вы можете переделать примеры и на технологию CSP или любую другую.

Итак, приступим...
Total votes 7: ↑6 and ↓1+5
Comments2

Индексация неатомарных атрибутов

Reading time16 min
Views3.3K
Цитаты из википедии (1NF):
Каждое пересечение строки и столбца содержит ровно одно значение из соответствующего домена (и больше ничего).

Одно и то же значение может быть атомарным или неатомарным в зависимости от смысла этого значения. Например, значение «4286» является
  • атомарным, если его смысл — «пин-код кредитной карты» (при разбиении на части или переупорядочивании смысл теряется)
  • неатомарным, если его смысл — «набор цифр» (при разбиении на части или переупорядочивании смысл не теряется)

В данной статье будут рассмотрены стандартные способы ускорения SQL-запросов по следующим типам полей: строка, дата, простой список (в формате $LB), коллекции-cписки и коллекции-массивы.
Будет много SQL, немного классов и совсем чуть-чуть NoSQL
Total votes 8: ↑5 and ↓3+2
Comments0

intro.js — пошаговое руководство для веб-страницы

Reading time1 min
Views51K


Эта маленькая библиотека позволяет очень просто создать пошаговое введение для сайта или приложения. Достаточно добавить атрибуты data-intro и data-step с описанием и номером шага соответственно к нужным элементам страницы. Вот так:

<a href='http://google.com/' data-intro='Hello step one!' data-step='1'></a>
Читать дальше →
Total votes 139: ↑134 and ↓5+129
Comments24

Вертикальная черта, затем ноль

Reading time3 min
Views41K
Заголовок, выраженный словами, понадобился только для поисковой находимости. Но речь пойдёт о роли символьной конструкции «|0» в JavaScript.

Впервые на неё я обратил внимание, когда переводил FAQ про asm.js и читал спецификации этого подмножества языка JavaScript. Там «|0» служит, например, для указания типа значения, возвращаемого из функции: увидели «|0» после значения — значит, перед нами знаковое целое.

Вдругорядь я заметил конструкцию «|0» в примере кода на Гитхабе, где происходило преобразование к целому числу результата деления на 1024².

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

( 3|0 ) === 3;       // целые числа не изменяет
( 3.3|0 ) === 3;     // у дробных чисел отбрасывает дробную часть
( 3.8|0 ) === 3;     // не округляет, а именно отбрасывает дробную часть
( -3.3|0 ) === -3;   // в том числе и у отрицательных дробных чисел
( -3.8|0 ) === -3;   // у которых Math.floor(-3.3) == Math.floor(-3.8) == -4
( "3"|0 ) === 3;     // строки с числами преобразуются к целым числам
( "3.8"|0 ) === 3;   // при этом опять же отбрасывается дробная часть
( "-3.8"|0 ) === -3; // в том числе и у отрицательных дробных чисел
( NaN|0 ) === 0;     // NaN приводится к нулю
( Infinity|0 ) === 0;     // приведение к нулю происходит и с бесконечностью,
( -Infinity|0 ) === 0;    // и с минус бесконечностью,
( null|0 ) === 0;         // и с null,
( (void 0)|0 ) === 0;     // и с undefined,
( []|0 ) === 0;           // и с пустым массивом,
( [3]|0 ) === 3;          // но массив с одним числом приводится к числу,
( [-3.8]|0 ) === -3;      // в том числе с отбрасыванием дробной части,
( [" -3.8 "]|0 ) === -3;  // и в том числе с извлечением чисел из строк,
( [-3.8, 22]|0 ) === 0    // но массив с несколькими числами вновь зануляется
( {}|0 ) === 0;                // к нулю также приводится пустой объект
( {'2':'3'}|0 ) === 0;         // или не пустой
( (function(){})|0 ) === 0;    // к нулю также приводится пустая функция
( (function(){ return 3;})|0 ) === 0;    // или не пустая

Итак, во-первых, перед нами удобное средство отбрасывания дробной части.

  • По отношению к отрицательным числам оно полезно тем, что дробное число превращается не в ближайшее меньшее целое число (возрастая по модулю), как это случилось бы после «Math.floor()», а в ближайшее меньшее по модулю целое число (возрастая по значению). Нередко именно это и требуется.
     
  • По отношению к положительным числам оно полезно уж тем одним, что конструкция «|0» более чем на порядок короче по сравнению с «Math.floor()». Поэтому она может и должна вызывать у разработчиков привыкание не меньшее, чем та принятая в jQuery запись «$()», о которой я говорил четыре дня назад, что с неё никто добровольно не перейдёт обратно на «document.getElementsByClassName()», например.

Во-вторых, перед нами удобное средство преобразования различных типов к целым числам.

Читать дальше →
Total votes 184: ↑159 and ↓25+134
Comments93

Сложность ERP систем

Reading time5 min
Views66K
Наверняка вы видели такую картинку.

Все, абсолютно все мои коллеги, друзья, знакомые, даже я сам смеюсь над этими горе-разработчиками, захламившими программу кнопками, ссылками и прочим шлаком.
Хотя мне то что смеяться. Я, как архитектор ERP систем, сам регулярно прикладываю к этому свои руки, и понимаю, откуда возникает такой хаос.
Узнать о хаосе
Total votes 132: ↑117 and ↓15+102
Comments124

Примеры генерации и отправки Email средствами СУБД Caché

Reading time6 min
Views4.3K
Нередко возникает необходимость в автоматической генерации и отправке электронных писем на основе данных из БД. Это могут быть различные отчёты с таблицами, диаграммами или уведомления о наступлении каких-то событий.
Всё это можно реализовать непосредственно в самой СУБД Caché, выступающей здесь и как почтовый сервер приложений.

Далее рассмотрим следующие примеры:
  • создание текстового письма
  • создание письма в формате HTML
  • добавление вложений
  • добавление изображений в само тело письма
  • другие примеры
Читать дальше →
Total votes 3: ↑2 and ↓1+1
Comments44

Information

Rating
Does not participate
Location
Минск, Минская обл., Беларусь
Date of birth
Registered
Activity