Search
Write a publication
Pull to refresh
52
0.5
Дмитрий @bogolt

User

Send message

Миллион строк плохого кода

Reading time4 min
Views48K
«No pain, no gain», как гласит древняя восточная мудрость. И даже если мудрость не древняя и не восточная, лично для меня самый ценный жизненный опыт чаще всего был и самым болезненным. Недавний пост Дэвида Робинсона — аспиранта, занимающегося программированием в стенах Принстонского университета — посвященный код ревью, не только поднял важный вопрос повседневного быта каждого, кому волей (или неволей) приходится передавать свой опыт другим. Оригинальный текст был относительно «беззубым», однако, пост перестал быть томным после того, как в комментариях появился Джон Кармак.

Это история о плохом коде, который однажды написал ваш покорный слуга.

На одном из первых курсов университета я писал программу на Java, которая должна была читать файл весом в 6 MB в строку (этим файлом был геном бактерии в формате FASTA). Выглядел мой код следующим образом:

BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
String text = "";

while( ( line = reader.readLine() ) != null ) {
    text = text + line;
}

Построение строки при помощи серии конкатенаций подобным образом крайне неэффективно — у меня, без преувеличения, уходило около 40 минут на чтение файла (с тех пор я узнал несколько способов получше). Самое главное — после чтения файла весь оставшийся алгоритм в программе отрабатывал секунд за 10. Два дня я так и работал: делал изменения в коде, запускал программу и успевал посмотреть целый эпизод LOST, прежде чем программа завершала выполнение. «Черт, на двенадцатой строчке ошибка! Опять все по-новой...»
Читать дальше →

«Free to PAY» — результаты эксперимента

Reading time4 min
Views16K
Для начала ссылка на первую часть статьи: "«Free to PAY» — эксперимент по честной монетизации игры". В ней есть подробное описание всей затеи, голосование за «сработает — не сработает» и куча комментариев.

Перескажу вкратце суть: небольшая мобильная игра с конечным геймплеем, продавать внутри особо нечего, баннерную рекламу встраивать не хочется, равно как и городить стандартный “фритуплей-обвес”. Но хоть как-то отбить затраты, понятное дело, хочется. Вопрос: как монетизировать? Предположительный ответ: сделать максимально хорошую, полностью бесплатную игру, и только уже после прохождения предлагать игроку заплатить за полученные эмоции и потреблённый контент. Сказано — сделано.

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


Читать дальше →

Организация и использование сегментации в больших мобильных приложениях

Reading time11 min
Views7.7K
Однажды, ваше мобильное приложение становится достаточно большим и им ежедневно пользуются десять тысяч — сто тысяч — миллион, не важно, в общем очень много живых и разных людей. Что это значит для вас, как для разработчика?

Да, теперь стало гораздо страшнее нажимать кнопку «Submit», ведь если вы чего-то недоглядели — в отличии от веб-приложений не получится посидеть ночь, обложившись банками ред-булла и пиццами и все исправить — ревью на мобильных платформах занимает время, а если говорить про iOS — аж целую неделю. Неделя — более чем достаточный срок для того, чтобы лояльный ранее пользователь перестал открывать ваше приложение.

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



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

Когда у Шерил день рождения?

Reading time2 min
Views128K
Сингапурский телеведущий Kenneth Kong взорвал интернет логической задачей.

image

11 апреля 2015 он разместил на своей странице в Facebook задачу на логику для школьной олимпиады. SASMO (Singapore and Asean Schools Math Olympiads) уточнили позже, что задача предназначалась для детей 14 лет (уровень Sec 3).
Читать дальше →

Return oriented programming. Собираем exploit по кусочкам

Reading time8 min
Views28K
Введение
В этой статье мы попробуем разобраться как работает Return Oriented эксплоит. Тема, в принципе, так себе заезженная, и в инете валяется немало публикаций, но я постараюсь писать так, чтобы эта статья не была их простой компиляцией. По ходу нам придется разбираться с некоторыми системными особенностями Linux и архитектуры x86-64 (все нижеописанные эксперименты были проведены на Ubuntu 14.04). Основной целью будет эксплуатирование тривиальной уязвимости gets с помощью ROP (Return oriented programming).
Читать дальше →

Вы неправильно пишете животных

Reading time5 min
Views388K
Животные – это платформы с очень ограниченной памятью, вычислительными способностями и возможностями модификаций. Разработчикам энимал-сцены приходится выдавать практически гениальные низкоуровневые алгоритмы. Правда, большое количество хардкода вызывает характерные проблемы с отсутствием проверки в экзотических условиях. Та же фильтрация входных данных делается очень и очень криво.


Уязвимость рекурсивных алгоритмов навигации муравья: спираль смерти

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

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

N+4 полезных книг

Reading time5 min
Views82K


Привет! В посте блиц-обзор книг, которые будут полезны IT-специалистам, бизнесменам и тем, кто просто любит читать интересные технические вещи. Рядом с каждой – пояснения, чем оно может быть нужно. Этот обзор, в отличие от других ежегодных, более технически-прикладной.

Начнём со «Справочника по инженерной психологии» Вудсона и Коновера.

«Справочник по инженерной психологии» — Вудсон, Коновер


Книга о том, какие бывают кнопки и рычаги, как на них нажимают люди. И как проектировать так, чтобы люди работали с системой эффективно. Радует тем, что рассматривает пользователя как базовую систему ввода-вывода, замеряя его среднюю скорость передачи информации (около 20 бит в секунду на кнопочные интерфейсы), скорости ввода и вывода.
Читать дальше →

Как могла бы выглядеть поддержка JSON в современном С++

Reading time5 min
Views67K
Хорошо в плане поддержки JSON живётся программистам на Javascript — по какому-то невероятному стечению обстоятельств там JSON входит в спецификацию самого языка: есть JSON — есть объект. Удобно. Неплохо дело обстоит и в языках, где JSON не входит в сам язык, но поддерживается стандартной библиотекой (Python, Ruby): импортируешь модуль — и готово.

Жизнь программистов на С++ никогда не была особо простой — поддержки JSON у нас нет ни на уровне языка, ни в стандартной библиотеке. И не будет, возможно, никогда. «Тоже мне проблему нашел!» — скажут мне опытные коллеги — «Её там и не должно быть, С++ поставляется без „батареек“. Для решения этой задачи мы...» и вот здесь они разделятся на два лагеря:

1. «Мы используем большой фреймворк (boost, Qt, POCO, другой), который применяется во всех наших проектах и умеет 150 000 разных вещей, в том числе и JSON.»
2. «Мы придерживаемся подхода в котором для каждой задачи применяется своя легковесная библиотека. В частности, для JSON мы уже 150 000 лет назад выбрали отличную библиотеку %JSON_LIB%, которая прекрасно работает.»

Да, всё так и есть. Вот только…

Чем плох подход с использованием фреймворков
Во-первых, тянуть в проект огромный фреймворк ради одного JSON — как-то уныло. Ну ладно, допустим фреймворк у вас был и так. Но тогда придётся писать работу с JSON в терминах фреймворка, а это, как правило, тихий ужас. Посмотрите, например, на документацию по JSON в Qt — куча собственных типов вроде QJsonArray, QJsonDocument, QJsonObject, QJsonValue и т.д. и их придётся использовать. О том, чтобы потом перенести код в другой проект (где этого фреймворка нет) можно сразу забыть. Ну или вот Boost: парсер JSON находится очень логично в модуле Boost.PropertyTree. Ага, так бы я и догадался. Т.е. нам предлагают плясать не от формата JSON, а от структуры данных «дерево», которая умеет себя читать в том числе и из JSON.

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


Чем плох подход с использованием библиотек
Плох он вот этой частью: "...150 000 лет назад выбрали отличную библиотеку...". Скорее всего речь идёт о чём-то, что начинало писаться чуть-ли не во времена DOSа и, без сомнения, работает, но при этом, пытаясь быть совместимым со всеми платформами и стандартами языка совершенно отстаёт от прогресса. Да, всё компилируется и работает, даже тесты проходит. Но библиотека совершенно не знакома с такими вещами, как ключевое слово auto, range-based циклы, строковые литералы, raw-строки, конструкторы перемещения, списки инициализации и прочие классные вещи, делающие код одновременно более эффективным и более легко читаемым. А ведь у библиотеки, созданной годы назад, есть обязательства по обратной совместимости, а значит просто так взять и добавить это всё она не может.


Давайте немного помечтаем.

А что, если бы JSON вошел в стандартную библиотеку нового стандарта С++? Что, если бы он был написан в терминах С++11\14 и без требований обратной совместимости со старыми стандартами языка? Что, если бы синтаксис этого модуля попытались бы сделать максимально приближенным к родному для JSON использованию «а-ля Javascript», но в том же время сохранить дух С++ (эффективность, минимальное потребление памяти, совместимость с STL)? Что, если бы его можно было включить в проект одним инклюдом и не беспокоиться о его сборке и линковке? Как бы это всё выглядело и работало?

И у нас есть ответ на этот вопрос! Давайте посмотрим на JSON-библиотеку для С++ написанную в соответствии со всеми этими принципами, ну и вообще написанной людьми для людей, а не чужими для хищников, как это обычно бывает.
Читать дальше →

Ноутбуки Lenovo поставляются с вредоносным ПО Superfish и его CA-сертификатом и приватным ключом в хранилище

Reading time2 min
Views123K
Программа Superfish, которая поставляется с ноутбуками Lenovo Y50, Z40, Z50, G50 и Yoga 2 Pro, представляет из себя типичный Malware, который прослушивает трафик, анализирует поисковые запросы пользователя и вставляет рекламу на страницы сторонних сайтов. Работает это приложение на уровне системы, перехватывая, в том числе, HTTPS-трафик. Для этого, приложение устанавливает CA-сертификат Superfish в хранилище ключей Windows и проксирует весь трафик между хостом и браузером, подменяя сертификат на свой. Поставляется это ПО, как минимум, с июня 2014 года. Первое сообщение об этой программе на форуме Lenovo датировано сентябрем 2014 года.

image
Читать дальше →

Математическая задача о 100 коробках и спасении заключенных

Reading time7 min
Views149K
Предлагаю читателям «Хабрахабра» перевод публикации «100 Prisoners Escape Puzzle», которую я нашел на сайте компании DataGenetics. Все ошибки по данной статье присылайте, пожалуйста, в личные сообщения.

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


Читать дальше →

Git game или в поисках Линуса Торвальдса

Reading time1 min
Views44K


Наткнулся сегодня на этот замечательный проект. Из файла README.md репозитория проекта:

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

Поехали!


Склонируйте репозиторий с помощью команды:
$ git clone https://github.com/hgarc014/git-game.git

Читать дальше →

Робот на RaspberryPi, Arduino и RaspiCam + OpenCV. Часть 1 Обзорная

Reading time5 min
Views127K
Очень часто на хабре появляются статьи о том как использовать Raspberry Pi как медиацентр, передвижную видеокамеру, удаленную web камеру и… собственно все. Очень странно, что в такой большой IT тусовке — довольно мало информации о том — как его программировать и использовать одноплатный компьютер там, где он действительно довольно полезен — во всяких встраиваемых системах, где есть ограничения по размеру и стоимости, но также есть потребность в производительности. В нескольких статьях постараюсь описать на примере создания мобильного колесного робота с компьютерным зрением — как можно использовать малинку для создания роботов(штук с интеллектом на борту, а не управляемых с андроида машинок с веб камерой).
image
Читать дальше →

Музыка как big data. Почему вместо качества звука надо задуматься об удобстве

Reading time8 min
Views32K
Никогда еще музыкальная индустрия не была столь развита технически. Ассортимент, доступность, простота, дешевизна: в общем рай для меломана. Или ад. Никогда еще музыкальная индустрия не раздражала так сильно тех, кто приносит ей больше всего денег. Почему так? Много разных людей и компаний, преследуя свои, подчас диаметрально противоположные интересы, низвели музыку до статуса фонового шума, в котором почти отсутствует полезный сигнал. Имея на руках смартфон с дешевым, неограниченным, моментальным доступом к десяткам миллионов песен мы перестали музыку ценить. Или не перестали?

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

Тему этой «сложности» я затронул в предыдущем посте, но очень поверхностно. Несмотря на это, дискуссия в комментариях вышла весьма интересная и полезная. А поэтому – продолжим! Что если вынести за скобки и качество звука, и стоимость? Что если оценивать плеер, наушники, колонки и усилитель исключительно по тому, насколько удобно ими пользоваться, и насколько хорошо они соответствуют Основным Принципам моего меломанства? Такой подход очень интересен и, увы, нечасто встречается. Сразу скажу, что «удобство» — это тема не для одного поста, но с чего-то надо начинать. Начну с тех самых принципов.
Читать дальше →

Типобезопасные идентификаторы и фантомные типы

Reading time4 min
Views17K
Довольно часто в программе, работающей с базой данных, в качестве идентификаторов сущностей используются значения целочисленного типа (например, long). Но людям свойственно ошибаться, и программист может по ошибке использовать идентификатор одного типа сущности для адресации другой. Такая проблема может долго оставаться незамеченной, если идентификаторы сущностей пересекаются, а такое бывает довольно часто. К счастью, в языках, позволяющих манипулировать типами, коим является C++, есть довольно простое решение этой проблемы.
Читать дальше →

Краткий курс компьютерной графики: пишем упрощённый OpenGL своими руками, статья 6 из 6

Reading time6 min
Views61K

Содержание основного курса




Улучшение кода






Official translation (with a bit of polishing) is available here.




Shadow mapping


Ну вот наш краткий курс подходит к концу, задача на сегодня — научиться отрисовывать тени (внимание, просчёт полутеней — это отдельная тема):



Как всегда, код доступен на гитхабе
Читать дальше →

Интерфейс для Яндекс.Диска в Ubuntu 14.04

Reading time3 min
Views44K
image

Как известно, Яндекс.Диск на Ubuntu существует только как консольный клиент. Сегодня я решил «хватит это терпеть» и написал для себя простенький скрипт, который значительно упрощает работу с ним (исходники внизу статьи).
Читать дальше →

Dagaz: Пинки здравому смыслу (часть 2)

Reading time16 min
Views14K
imageЯ еще чуток добавил прыти —  
Все не так уж сумрачно вблизи:
В мире шахмат пешка может выйти —  
Если тренируется — в ферзи!

          Владимир Высоцкий "Честь шахматной короны"
 

Правила, особенно такие сложные, как рокировка или "взятие на проходе", не появляются на пустом месте. Никто не придумывает их просто так, чтобы позлить разработчика (во всяком случае, я надеюсь на это). В таких «устоявшихся» играх как Шахматы или Шашки, каждое из правил выстрадано десятилетиями. Тысячами игр, в десятках стран, по всему миру. Это бесценный материал для анализа. Неудачные решения отмирают, успешные — расцветают в сотнях различных вариантов (среди которых также есть как удачные, так и не очень). Сегодня, мы поговорим о двух особенно удачных находках... 
Читать дальше →

ErgoEmacs — a way to Lisp

Reading time7 min
Views15K
Если вы получаете удовольствие от программирования, то, наверняка, перманентно находитесь в состоянии поиска лучших инструментов, лучших идей, лучших решений. И знаете, конечной остановкой лично для меня стал Emacs. А точнее — его сборка под названием ErgoEmacs. Под катом будет попытка логического и последовательного рассказа об использовании данного текстового редактора в контексте знакомства с ним впервые в жизни (не вдаваясь в сильную конкретику, а скорее стараясь уловить общую идею); идеологическая пропаганда (емакса вообще и лиспа в частности); небольшая критика последней из статей на Хабре по данной тематике, а также небольшое философское заключение. Если вы хотите расширить свой кругозор, прошу под кат.
Расширить кругозор

Аннотация к «Effective Modern C++» Скотта Майерса

Reading time11 min
Views58K
Пару месяцев назд Скотт Майерс (Scott Meyers) выпустил новую книгу Effective Modern C++. Последние годы он безусловно является писателем №1 «про это», кроме того он блестящий лектор и каждая его новая книга просто обречена быть прочитана пишущими на С++. Более того, именно такую книгу я ждал давно, вышел стандарт С++11, за ним С++14, уже виднеется впереди С++17, язык стремительно меняется, однако нигде так и не были описаны все изменения в целом, взаимосвязи между ними, опасные места и рекомендуемые паттерны.

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

Information

Rating
3,179-th
Registered
Activity