MCP

четверг, 31 декабря 2015 г.

Про велосипеды

Несмотря на то, что сегодня 31-е декабря, хочется написать не праздничный, а технический пост. Хотя и философский слегка. Как же без этого. 

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

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

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

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

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

воскресенье, 15 ноября 2015 г.

Чем мне не нравятся async/await

Тут на днях у нас вышел спор с коллегами по поводу async/await в Microsoft .NET. Мне эта технология не очень нравится, несмотря на её круть, но сформулировать причины сходу весьма непросто. В этом посте попробую объяснить, в чём же проблемы (естественно, это моё мнение, и оно может не совпадать с генеральной линией партии).

1. Это не про потоки, это про асинхронность в одном

Т.е. основной смысл этой конструкции в том, чтобы занять основной поток, пока его часть ждёт какой-то асинхронной операции. Т.е. пока мы скачиываем файл, мы можем поделать ещё что-то, а не тупо ждать завершения. Идея здравая, но есть нюанс: должно существовать то, чем вам заняться. Например, если у нас клиентское приложение, мы в этом же потоке обработаем всякие события перерисовки, если однопоточное серверное, займёмся другим клиентом. Но если нам нечем заняться, то смысла в конструкции нет. Т.е. если мы сделали отдельный поток для пользователя и ждём когда скачается файл, чтобы что-то сделать. Мы не выиграем ничего от использования async/await. Просто будем использовать как небольшой синтаксический сахар с гигантcкой работой под капотом не по делу.

2. Неявная точка асинхронности

Когда мы вызываем асинхронный метод, мы не знаем, когда он реально перейдёт в асинхронность. Другими словами, возьмём стандартный подход: 
Task.Factory.StartNew(DoSomething);

Сразу после вызова данного метода, мы можем продолжать работу. А теперь глянем на async/await:
var t = DoSomething();
..........
await t;

В данном коде мы не знаем, когда реально дойдёт до нас управление, и будет ли реальная асинхронность. Фактически, мы вернёмся в метод, когда в DoSomething() будет встречен await, а когда это будет — зависит от реализации. Фактически, точка асинхронности слово await, но она находится внутри метода который мы вызываем, как результат, мы нам надо знать реализацию метода DoSomething, чтобы было всё прозрачно и понятно.
В большинстве случаев, это не проблема, но когда начинаются проблемы, вот такие мелкие нюансы очень портят жизнь.
Например, указано, что эксепшены пробрасываются на await, в результате можем получить код вида:
У которого вначале уничтожится мир, потом будет всё хорошо, а потом вылетит эксепшен. На мой взгляд не очень очевидно.

Вся эта неявность приводит к следующей проблеме:

3. Легко завалить производительность, при этом всё будет работать

Как я уже указал, данная технология про асинхронность. Соответственно всё должно быть асинхронно, всегда и везде. А что будет, если мы где-то забудем асинхронность? Или не мы, а тот кто написал библиотеку для нас. Может быть он не очень хороший программист и допустил маааленькую ошибку и сделал операцию синхронной. Как вы думаете, что будет? Да ничего фатального! Просто пользователь будет ждать. Например, один await не в том месте, привёл к тому, что HTTP-proxy на async/await стала обрабатывать все запросы от пользователей по очереди. И это работало год. Заметили случайно, при генерации отчётов сайт переставал открываться. А всему виной — ошибка в коде, про который все забыли и который с точки зрения логики, работал замечательно.

Другие примеры, чтобы понять масштаб проблемы: делаем запрос по HTTP, и перед запросом решили порезолвить DNS, синхронно (ну не нашли асинхронный метод). Можем получить 2 секунды тормозов на ровном месте. Использовали бы явную асинхронность вызовом метода в отдельном потоке — проблем не было бы. Ещё вариант — логгер, давно написанный, отлаженный, пишет в файлик, асинхронной версии не имеет, никому не нужна. Всё работает годами. Потом кто-то на том же интерфейсе решил запилить логгирование в базу, результат — пока один пишет, все ждут (у нас ведь синхронная версия). Провал производительности.

Хотя про то, что всё будет работать, я погорячился. Когда писал этот пост выяснил, что легко получить Deadlock из-за повторного входа и контекстов синхронизации. Не буду пересказывать статью, там на третьем примере всё достаточно просто и понятно рассказывается. 

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

4. async/await заразные


Чтобы заиспользовать его, методу надо указать что он async. Если метод async, то вызывающий его метод должен использовать await и самому стать тоже async.
Т.е. весь код резко начинает обрастать async'ами, как снежный ком. Вырваться из данной западни можно двумя способами: async void (не используйте никогда!) или явным хаком с вызовом Wait у таска, возвращаемого async методом (что может привести к некоторым проблемам с контекстом синхронизации).
В общем, для нормального использования async'ов, у нас должна быть вся библиотека, написанная на них, которая использует другие библиотеки, написанные тоже на них. Надо писать сразу весь код в этой концепции, добавление небольшого куска не даёт никакого профита. А раз это концепция, то хотелось бы явно выделять её. Например, я вызываю метод DoSomething(), в зависимости от того, async он или нет, при вызове будут абсолютно разные вещи. Но без поддержки IDE я никогда не у знаю об этом. Если я добавлю к сигнатуре async, позднее, код скомпилируется и будет работать как-то, но о проблемах я узнаю по факту, а не во время компиляции.

И это косвенно подводит нас к очередной проблеме

5. Reflection и кодогенерация

Reflection должен знать про то, что методы бывают async, т.к. от этого зависит логика их работы (банально проброс эксепшена о котором я уже упомянул вначале). Оверрайдить данные методы кодогенрацией (моё любимое занятие) тоже надо аккуратно, ибо просто для понимания, вызов метода:
public static async Task DoSomething() { Console.WriteLine("A"); await Task.Delay(1000); }

По факту превратится в что-то подобное:
 А реальная логика будет запрятана далеко, и будет выглядеть как-то так:
Согласитесь, не самый простой для понимания пример.
А так как все эти async/await сделаны на уровне языка, а не MSIL, то среда ничего не знает про это, и тем же рефлекшеном достать это сложно. Что в связи с неявной точкой асинхронности может резко менять логику.

Например, мы хотим добавить валидацию параметров метода через AOP, простой пример, они не должны быть null. Так вот, если мы это делаем кодогенрацией, мы пропустим слово async и добавим провеку  в метод. Вызывающий код упадёт на вызове метода. Если же мы добавим проверку вручную, то на слове await (да, это мой любимый пример с эксепшенами, раз я его разобрал). При этом не обязательно использовать кодогенерацию, достаточно просто наследования.

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

Выводы

На мой взгляд, данная технология похожа на внутренности Perl'а. Для тех, кто не знает этот чудесный язык, поясню: смотришь примеры, видишь как всё просто и круто. Начинаешь углубляться в язык, чтобы понять как это работает и с какого-то момента становится очень страшно. Ты понимаешь огромную магию внутри всего этого. Ты понимаешь, что неверное движение может всё поломать, а работает только благодаря умным людям, которые написали кишки и программистам, которые не суют нос, куда не надо. И лишь спустя длительное время ты становишься таким умным человеком, и тебе становится всё понятно. Тебе спокойно. Так вот, я с async/await не стал таким умным человеком, но мне страшно, я уже могу всё сломать и я боюсь что кто-то из моей команды тоже может всё сломать, и не поймёт этого. И я не пойму. В результате всё будет работать не так как надо, а мы не будет знать, в чём проблема. А чтобы узнать, не достаточно статей "Async и await для чайников". Надо действительно погружаться в технологию. А оно мне не надо. Я не пишу приложения под Windows 10, а больше смысла-то и  нет, хотя Microsoft толкает её в новые библиотеки, вполне можно прожить и без неё, без этого странного волшебства и магии.

воскресенье, 1 ноября 2015 г.

Про продукты Microsoft

Если кто со мной знаком, то он знает, что я достаточно давно являлся защитником Microsoft, несмотря на все её проделки. Мне могли не нравится определённые продукты, у данной компании ужасный менеджмент, но в целом, некоторые вещи, очень даже крутые.

Например, Visual Studio, одна из лучших IDE, а C#, на мой взгляд — лучший язык программирования (именно в качестве языка), а MSSQL — неплохая база данных, с отличными инструментами. IIS... в принципе, терпимо. Т.е. есть отличный стек для разработки программ, но дальше начинается жесть.

Была придумана придумана клёвая технология LINQ, для работы с базой данных, а потом появился он...  Entity Framework — ужасный и тормозной монстр, который захватил всю работу с базой, и которрый, всё толстеет и толстеет. Я уже запутался в версиях, просто вижу гигабайты места, сожранного им на билд-сервере.

MVC — это был глоток свежего воздуха по сравнению с Web Form'ами, третья версия была вообще отличная, но Microsoft было не остановить, сейчас есть какой-то могучий монстр 5-ой версии, из главных достижений которого — работа с Azure и клёвая интеграция с EF (это я на сайте посмотрел, чтобы выяснить, что же клёвого).

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

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

И весть этот комбайн должен крутиться на очень дорогом Windows Server, или не менее дорогом и ужасном Azure...

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

А сейчас... сейчас мир изменился. В вебе стало модно SPA и много логики на клиенте. Появился nodejs, просто работающий искаропки, появился nginx, который позволил замаскировать косяки линуксовых приложений через балансировку, появилось куча дешёвых и крутых Linux-хостингов (привет, DigitalOcean!), появился Docker.

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

И я уже думаю, а зачем оно мне всё? Есть столько всего вкусного. И это будет работать везде, а не только на Windows. Например, knockProxy я изначально хотел написать на C#, но потом передумал и написал на node.

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


понедельник, 7 сентября 2015 г.

knockProxy

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

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

Прямой доступ

Неплохой вариант, простой для использования, но есть нюансы. Первый, нельзя добраться до машин за NAT'ом, но это можно решить пробросом портов на шлюзе. Второй, более существенный, открывать доступ снаружи даже к одному сервису весьма неприятно в плане безопасности. Неверная настройка сервиса или security issue в нём, и твой компьютер уже как бы не твой. Ну или взять RDP в домене — можно не спеша перебирать логины и пароли всего домена, и если повезёт с одним каким-нить забытым тестовым логином, внутрь уже залезает злоумышленник. Так что этот способ отпадает

VPN

Отличный способ, постоянно использую. Положительных качеств вагон и маленькая тележка: работа с NAT'ом, видна вся сеть, сжатие и шифрование трафика при желании. Но есть один недостаток: сложная настройка. Например, самый простой для системы PPTP не работает на домашнем интернете от Билайна (ибо у них тоже PPTP, а PPTP over PPTP это слишком сложно). А универсальный OpenVPN требует телодвижений по настройки как на клиенте, так и на сервере. Одного логина с паролем не хватит. Так что хотелось бы что-то более простое.

IPSec

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

Отдельная программа для связи

Например, что-то типа TeamViewer. Платно и неспортивно.

Свой велосипед

Моё любимое занятие. Ибо точно знаешь что программа умеет, что нет, и какая область применения.
Итак, был написан свой велосипед knockProxy, на node.js, лежит на ГитХабе. Я думал следующим образом: самый удобный вариант, это прямой доступ, но напрямую доступ давать нельзя. Так будем его выдавать после ввода логина и пароля (отдельного, чтобы сузить область возможной атаки). Бонусом, дадим несколько логинов для разных пользователей.

Т.е. всё работает следующим образом: клиент заходит на сайт (браузер у всех ведь есть!), вводит логин и пароль. Для его IP открывается дырка на необходимый компьютер, дырка открывается на пару минут и 5 попыток подключения, так что перебором особо ничего не сделать, даже если пассивно слушать трафик (пароль, естественно не передаю в сыром виде, сплошные солёные хеши).

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

Но, естественно, есть недостатки, например, доступ только на один порт (я предпочитаю RDP), что для полноценной работы не хватает. Зато хватает быстро посмотреть. Второй, более существенный недостаток — соединение по этой дырке по-хорошему должно быть шифрованное. Иначе, где-то в кафе по WiFi могут утечь секурные данные. Но RDP шифруется, правильный VNC тоже, так что для них это не существенно. Обойти данную проблему можно созданием ручного туннеля, но тогда придётся настраивать клиента, что совершенно не подходит в плане удобства (уж лучше честный VPN).

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

Для тулзени выбрал лицензию MIT, для работы нужен node, и какой-нить сервер с мордой наружу (нужен прямой открытый TCP порт). Веб-часть может при необходимости жить через proxy, хотя больше любит напрямую. Работает и под *NIX и под Windows. Наверное и под маком может жить. Так что универсальность полнейшая.

В общем, прошу любить и пользоваться.

суббота, 5 сентября 2015 г.

Microsoft EDGE

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

Собственно по пунктам, банальные вещи, которые видны сразу:
  • Если обратиться к сайту на нестандартный порт, браузер не догадается что он предназначен для http и с упорством дебила пойдёт гуглить, что же ему подсунули. Ну детский сад же... UPD: это исправлено, претензия снимается
  • Восстановление сессий, вроде бы старая и must have фича, по-прежнему работает некорректно. А именно, постоянно восстанавливается куча пустых вкладок. Откуда, блин, он их берёт?
  • При запуске, если система тормозит, то при попытке ввести адрес, добрый браузер сотрёт его, и нарисует вместо него свою домашнюю страницу. Блин, я уже собираюсь уйти куда мне надо, не решай за меня!
Все эти пункты тянутся с IE и до сих пор не пофикшены, хотя в любом другом браузере — работают гораздо лучше. Неужели разработчика браузера запрещено смотреть на другие, не дай бог, сделают что-то удобное.

При этом в Edge оторвали всё хорошее из IE — акселераторы, фрагменты, плагины. Интерфейс теперь стал одним из самых габаритных среди других браузеров (а раньше хвалились, что они экономят место), окна браузера теперь все объединены в один значок, а не делятся на отдельные как в IE...

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

воскресенье, 30 августа 2015 г.

Проблемы REST API или Яндекс тоже лажает

Вчера заметил лажу Яндекса в реализации REST API и решил немного высказаться про идеологов правильного использования REST.

Под данными идеологами я понимаю людей, которые месяцами выбирают HTTP-метод (PUT или PATCH? Сложный выбор!), вылизывают урлы (так, /user/add/group или /group/add/user, или POST /, а остальное данными?), при этом по факту никому их API никогда не нужно, а если и нужно то используется через врапперы и библиотеки.

Красивые урлы и семантика, конечно, важна, но проблема в том, что REST работает через HTTP со своими заморочками и ограничениями. Например, в GET нельзя закидывать body, и надо пытаться засунуть всё в URL, а если не влезает, то сделать POST, получить ID запроса, и сделать GET. Идиотизм. зато семантично.

Или моё любимое: по стандарту GET-ответы кешируются, если не сказано иное (хотя хрому наплевать на это). Звучит разумно, например, мы получаем текущую фазу луны, никаких параметров, она всегда одинаковая, хотя... стоп... Давайте что-нить попроще, например количество входящих сообщений пользователя... блин... Пол пользователя! Во! Главное, чтобы он к врачу не сходил. В общем, если умерить сарказм, то получается, что GET-запросы для API практически никогда не надо кешировать, ибо хоть они и получают данные, но те данные имеют тенденцию меняться в самый непредсказуемый момент.

Решений для убирания кешироания несколько:
  • С сервера посылать запрет кеширования. Работает, но несемантично
  • К каждому запросу подсовывать рандомную строку. Работает, но выглядит ужасно и по факту засираем кеш браузера
  • Переделать API так, чтобы в нём участвовала рандомная строка. Например, дать количество сообщений пользователя на определённую дату. Пофиг, что кроме текущей мы ничего не можем сделать, зато прикрутили параметр
  • Делать POST, а потом GET - очень глупо, медленно, неудобно, но семантично
В общем, вместо того, чтобы тупо сделать всё на POST'ах, мы активно боремся с инфраструктурой. И подобные проблемы периодически возникают то тут, то там. И борьба с ними идёт в основном ради красоты.

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

Собственно, а что с Яндексом? Дело в том, что недавно они написали умную статью, о том как работать с HTTP, типа учитесь как правильно. Ок, поучился. Захожу на internet.yandex.ru и вижу картину следующего вида:
Естественно, со временем всё было в порядке. Просто я обновил данную страницу в браузере, а запрос о времени, сделанный по всем правилам Яндекса по урлу http://yandex.ru/internet/api/v0/datetime/ не имел никаких параметров кеширования. Что привело к тому, что браузер честно отдал ответ, который он запомнил 6 часов назад.
Как видите, Яндекс умеет делать красиво, рассказывать всем как правильно, только выкатывает в итоге нерабочий сервис.

UPD: Увидел ссылку, которая описывает архитектурные проблемы REST чуть в другом ключе, но пересекается с данным постом и я с ней в целом согласен. Также, могу сказать, что в одном из проектов я использовал JSON-pure API, и с ним не было никаких проблем. Данный код до сих пор бродит по разным проектам и не вызывает нареканий.

вторник, 2 июня 2015 г.

Чудесатые интернеты

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

Итак, есть виртуалка, вроде бы всё работает, но при попытке достучаться по самбе, получаю ошибку. Фактически, блокируются 135, 139 и 445-ые порты. Я поплясал с бубном, помучал фаирвол, всё бестолку. В конце-концов, решил проверить доступ с внешней машины. Он был. В полном офигении, я начал копать проблему дальше, и выяснил следующие факты
  1. Любой порт кроме этих трёх работает корректно
  2. Эти три порта работают корректно из любой доступной мне сети (и интернет-утилит), кроме рабочей
  3. Из рабочей сети доступ на данные порты на другие внешние сервисы открыт и работает
  4. Никаких запретов на подобное во внутренней сети нет
Т.е., фактически получается, что или провайдер, или хостер рубят эти три порта, именно для нашей сети или для сети хостера. Совершенно безумная ситуация, которая по идее невозможна, а если возможна, то кто-то ведёт себя очень плохо.

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

Вот так, блин, и работаем.

UPD: Оказалось, что это посредник Инфобокса блокирует часть портов, почему-то считая именно эти "небезопасными". Причём, блокирует только с части сетей. Признались они только после длительной переписки с саппортом.

вторник, 26 мая 2015 г.

Управление виртуалками для обычных пользователей в Hyper-V 2012 R2

Microsoft иногда очень оригинально относится к безопасности. Перекроет все щели так, что прорваться могут только админы. А потом начинает ныть, что же все сидят под админами. Ну, может быть, потому что кто-то ленится подумать про права?

В своё время, Microsoft выпустила сервер виртуализации Hyper-V, весьма неплохой, хоть и со своими тараканами. И там можно было сделать замечательную вещь: выдать пользователю права на виртуалку, которая крутится на сервере. Т.е. он мог её включать, выключать, дёргать у неё сеть, но при этом, он постоянно к ней подключён, и в тоже время не видит соседей.

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

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

Зато, после всех этих мучений, можно было весьма гранулированно раздавать права через AzMan (я, кстати, первый раз его видел, хотя, судя по всему, существовал в системе давно, с XP. Но мы-то знаем, что Microsoft не ищет лёгких путей и всегда есть по крайней мере три несовместимых технологии).

К сожалению, в 2012 R2, эта магия больше не работает. Всё сломано. Мне понадобилось достаточно длительное время, чтобы понять это, т.к. народ умудряется писать статьи о том, что всё таки работает. Не работает. Проверено. С большим скрежетом, я всё-таки нашёл, что можно с этим сделать. А сделать можно только одно: давать пользователю подключаться, к виртуальной машине. Т.е. включить он её не может, но хотя бы может работать с ней. Для того, чтобы как-то добавить права, судя по всему нужна отдельная прослойка, которая со своими жирными правами будет всё делать, уже сам раздавая права. Данной прослойкой может быть System Center Virtual Machine Manager или что-то своё самописное (можно добавить имперсонацию и рулить юзерами, действия тупо выполнять через PowerShell). Но само подключение можно реализовать чуть проще, хотя и не очень очевидно.

Собственно, для возможности подключения пользователя (не админа) к определённой виртуалке надо сделать следующее):

  1. Выдать права на виртуалку через PowerShell
    Grant-VMConnectAccess -ComputerName host_name -VMName vm_name -UserName user_name
    Есть ещё команды Get-VMConnectAccess для просмотра прав и Revoke-VMConnectAccess для отбирания
  2. В PowerShell выяснить id-нужной нам виртуалки
    Get-VM -ComputerName host_name | select id,name
  3. Установить Remote Desktop Connection Manager (стандартный не катит)
  4. В нём сделать новую группу, в группу добавить сервер, на вкладке Server Settings поставить VM Console Connect, ввести нужный Id и сохранить всё это дело


После этого можно пользоваться прямым подключением к виртуалке (возможно придётся открыть ещё порт 2179).

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



четверг, 23 апреля 2015 г.

Ещё одна проблема HttpWebReqest

Я уже писал про грабли HttpWebRequest, но тут нашёл ещё одну забавную, и местами неприятную. Правда наполовину она относится к HttpWebResponse, но классы связаны метровым канатом, так что не принципиально.
Вкратце: работа с куками организована очень оригинально, и не очень логично.

Для удобства распишу по условным пунктам. Для начала диспозиция:
  • Сервер возвращает куки в Http-заголовке Set-Cookie
  • Если надо установить две куки, сервер передаёт два заголовка (не очень логично, но ок)
  • HttpWebResponse имеет пропертю Headers, и по имени заголовка можно получить значение
Тут начинаются проблемы, ибо куки две, а заголовок один. Как вы думаете что вернётся? Не буду томить, скажу, что вернётся в этом методе содержимое двух кук через запятую. Очень, блин удобно. Считаем, что куки у нас разломаны в этом виде.

Но! У Headers можно взять значения через .GetValues(), вернётся честный массив из двух элементов. И вроде бы всё хорошо, и пост можно жакончить, но тут приходит сервер, и выдаёт нам:

Set-Cookie: ABC=123; expires=Fri, 31 Dec 2010 23:59:59 GMT; path=/;


Вы заметили, что между пятницей и 31-ым числом есть запятая? HttpWebResponse тоже заметил, и вместо этой куки честно вернул нам две, обе разломанные. Всё, приехали.

Но обойти это надо, поэтому можно сделать следующие вещи:
  • Вручную распарсить значения кук, зная, что запятая, по стандарту, запрещённый символ. Т.е. встретится она может только в expires
  • Взять у HttpWebResponse пропертю Cookies, с уже обработанными куками
Вроде второй вариант самый правильный и логичный, за исключением случаев, когда вам хочется посмотреть на изначальные данные от сервера, а не обработанные странным кодом. Но чтобы он работал, надо обязательно, у HttpWebReqest установить пропертю CookieContainer, иначе вам вернётся пустой массив в респонзе.

request.CookieContainer = new CookieContainer()

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

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

пятница, 27 февраля 2015 г.

Немного про починку винды через много букв

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

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

Винда, с трудом но поднялась после всего этого, правда для этого пришлось починить несколько важных для загрузки файлов и собрать монстра из реестра (комбинация из встроенного бекапа в C:\Windows\System32\config\RegBack\ и основного реестра), но в общем-то фатальных проблем не было.
Правда при работе слегка глючила, не давала подключиться удалённо, плюс были ещё мелкие и не очень проблемы (некоторые выявились только спустя несколько месяцев).
Что можно с этим сделать, и как чинить?

Вариант 1. Апгрейд винды на саму себя из установочных файлов

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

Вариант 2. sfc /scannow

Способ, который рекомендуют на всех форумах, к сожалению помогает он плохо, т.е. ничего не лечит (ему неоткуда взять корректные файлы при серьёзных повреждениях), но зато создаёт логи в C:\Windows\Logs\CBS\CBS.log, с помощью которых можно узнать повреждённые файлы и физически заменить их с аналогичной системы (тут очень помогает Far, который достаточно вольно относится к отсутствию прав на файлы (т.е. если есть права выдать себе права, но в данный момент их нет, а приказ что-то сделать с файлом есть, фар решит эту проблему самостоятельно). Без фара можно ручками выдавать права на проблемные файлы, меняя владельца с TrustedInstaller на себя и раздавая права (если хочется красоты, следующий запуск sfc /scannow всё починит).
Таким образом я починил большинство проблем и система жила, пока не потребовалось ещё кое-что настроить.
Но для начала

Вариант 3. dism

Утверждается, что свежая винда может себя починить через следующую команду:

DISM.exe /Online /Cleanup-image /Restorehealth

или

DISM.exe /Online /Cleanup-Image /RestoreHealth /Source:C:\RepairSource\Windows /LimitAccess

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

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



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

Итак, на первый взгляд проблемы появились в том, что не ставились апдейты. Изучение ошибок и логов привело к парадоксальному результату: они не ставились, потому что валился Task Scheduler со статусом что-то типа Initialize::UserTable (за точность ошибки не ручаюсь, ибо по памяти). Т.е. совершенно невменяемая ошибка. Были перепробованы все средства, пока не оказалось, что проблема в том, что в управлении пользователями отсутствовали локальные пользователи, а при открытии групп вылезало две ошибки с чтением данных. Т.е. проблема не в этом, а в том что есть именно проблема с пользователями. При этом из консоли (net user, net localgroup) проблем явных не было.

Тут я полез уже в дебри и выяснил следующее:
Вся информация о пользователях хранится в ветке реестра SAM, которая в реестре замаплена на HKEY_LOCAL_MACHINE\SAM. Если вы откроете ветку сейчас, вы ничего там не увидите. Рекомендую добавить себе права.
Там всё внутри устроено оригинально и не так как в остальном реестре. В частности, есть группы пользователей (SAM\Domains\Account\Aliases) и сами локальные пользователи (SAM\Domains\Account\Users). Они идентифицируется неким id, а сопоставление имён и id идёт в отдельном разделе (SAM\Domains\Account\Users\Names\), где в качестве типа указан данный id. Т.е. не значение, а тип. который обычно DWORD, STRING, BINARY. Впрочем, это можно списать на особенности отображения и то, что этот раздел не предназначен для обычных глаз.
У пользователей есть бинарные параметры F и V, а у групп С, которые содержат описание объекта, SIDы, и кто кому принадлежит.
В моём случае, были повреждены разделы C (их тупо не было) у групп администраторов и пользователей, и был один повреждённый пользователь (хотя визуально он был в порядке.
Эти проблемы и вызывали странное поведение в управлении пользователями.
Если хочется тут что-то сделать, вначале делаем бекап, потом играемся как хотим. У нас есть возможность откатиться.
Эмпирическим путём проблемный пользователь был вычислен и уничтожен (удалением ветки реестра), пользователи вернулись в норму. Раздел C, был импортирован с соседнего компьютера и всё ожило (Планировщик, а вместе с ним и апдейты. То ли у них были проблемы с группами, то ли с пользователем). К сожалению, в управлении группами в этих группах появились неизвестные SIDы (неудивительно, с таким-то импортом), которые не удалялись, а также не добавлялись новые пользователи.

Наилучшим решением проблемы я посчитал следующее (очень не хотелось разбираться в бинарной структуре данных записей, не стоит оно того). Например, у нас проблемная группа Administrators. Создаём группу Bdministrators. В эту группу добавляем нужных пользователей (самого администратора, например). Экспортируем из реестра обе группы по отдельности. Переносим бинарные данные из экспортированного файла от Bdministrators в Administrators, и импортируем его назад. Тем самым, у нас появились правильные администраторы (с правильным id), но неправильным именем. Ну, тут открываем в редакторе реестра бинарный редактор и меняем код байтика, отвечающий за B, на A. Всё, у нас правильные администраторы. Лишнюю группу удаляем, чтобы не мешалась. Повторяем тоже самое для других групп.
Результат — всё красиво и работает.



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

среда, 31 декабря 2014 г.

Итоги моего года

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

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

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

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

С поиском разницы в файлах пришлось изобретать велосипед: ибо это не обычный дифф, а дифф файлов, находящихся на разных компьютерах в разных датацентрах. И обмен информации следует максимально сократить. А потом ещё и подумать — искать разницу, или плюнуть и отдать файл целиком. Т.е. в отличии от теории, надо пользоваться жёсткими эвристиками для оценки требуемых действий. И это интересно.

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

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

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

PS: А ещё я научился собирать кубик Рубика за полторы минуты. А потом разучился. И полностью разучился собирать обычные, дешёвые кубики.

воскресенье, 28 декабря 2014 г.

Новогоднее RDP

Скоро новый год, а значит выходные, т.е. к серверам лучше не прикасаться, а если прикасаться, то аккуратно. Естественно, Microsoft всех приучило, что самый простой и ненапряжный способ это сделать - RDP (нет, конечно, PowerShell рулит и бибикает, но назвать этот способ простым, как-то язык не поворачивается).

Итак, RDP живёт, проблем вроде бы нет, но... в один прекрасный момент вы обнаруживаете следующую картину, которые можете наблюдать продолжительное время без видимых результатов.


Другими словами, при попытке подключения — RDP тупит, а потом идёт отлуп с пространными объяснениями, что всё плохо.
Вы дома, сервер далеко, к нему не подойти и не пнуть ногами. Подключиться — не удаётся.
Практика показывает, что это частое явление при разрывах сети. Т.е. кроме разрыва соединения, ещё появляются такие шикарные эффекты. Причем страдают обычно 8-ые винды (т.е. Windows Server 2012 и 2012 R2)
Что в этом случае можно сделать?

Для начала, конечно же выполнить пункт номер 0 — иметь пути отхода и дырку в фаирволле. Причём делать это по-возможности всегда. Т.е. у вас всегда должно быть как минимум 2 пути подключения к серверу (например через рабочий компьютер и через другой сервер), и желательно на определённые IP иметь хороший список открытых портов для этих дружественных компов. Винда это вам не Linux, тут одним SSH не обойдёшься, особенно когда так тупит RDP!

Вариант первый, банальный и неинтересный:
shutdown /m \\server /r /t 1
Отправляем компьютер в ребут... очевидно и неинтересно. Надо идти другими путями. Другие пути заключаются в том, что надо бы перепустить службу Remote Desktop, которая зовётся TermService.

Тут 2 варианта:
sc \\server restart TermService (оцените синтаксис команды относительно предыдущей)

Или же, с помощью мышки: mmc.exe, добавить остнаску, службы, другой компьютер, перезапуск.

Но, тут как всегда нас ждёт сюрприз... в 90% случаях служба зависнет и не захочет останавливаться. Так что придётся добивать её ногами. Битьё усложняется тем, что она висит в процессе svchost.exe (благо обычно на нужном ничего полезного нет).

Так что
tasklist /s server /svc | findstr TermService (оценили синтаксис?)
taskkill /s server /pid 123456

Ну и запускаем службу. Вроде просто и очевидно, но как всегда лезут нюансы: если у нас плохо с логином и паролем (а мы дома, а не в домене), то получим отказ в доступе. Некоторые команды имеют возможность указать логин с паролем, некоторые используют существующее соединение (net use \\server\c$ - получим замечательное подключение и для управления), некоторые просто отказываются работать.

Можно применить PowerShell, создать сессию на сервер и там всё сделать, но ведь его надо настроить... добавить доверие... в общем если вы не занимаетесь этим специально, работать не будет.

Так что, если всё плохо и ничего не работает, то придётся ползти в сторону Sysinternals, а именно PsTools, и через psexec уже всё делать. Что удивительно, работает это гораздо надёжнее, чем встроенные средства системы. Даже если не разбираться, можно написать


psexec \\server tasklist /svc

И получить тот же результат (да, мне лень изучать другие команды из этого набора ).

Собственно, зачем я это написал? Вроде очевидные вещи. Да в общем-то с двумя простыми целями: в очередной раз поныть на винду, и показать, что если что-то не работает, можно всё-таки обойтись без перезагрузки.

UPD: Спустя время, надо бы добавить ещё пару команд, которые помогут решить подобную проблему. Ибо у Microsoft всё устроено очень сложно, половина команд может работать, а другая половина не работать с дурацкими сообщениями вида (не шутка):
Couldn't access server:

The operation completed successfully.

Соответственно, tasklist /svc в нашём случае можно заменить на
sc queryex TermService

А вот с taskkill посложнее. Может прокатить скрипт на PowerShell
Invoke-Command -ComputerName server -ScriptBlock {Stop-Process -Id 123456 -Force} -Credential DOMAIN\user

понедельник, 10 ноября 2014 г.

Interstellar, впечатления

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

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

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

Дальше будет много спойлеров, так что, если вы ещё не смотрели данный фильм — не рекомендую читать.

Итак, поехали...

Завязка истории следующая: Земле кирдык, все жрут одну кукурузу, но поскольку она у всех сидит в горле, то периодически сжигают посевы. Хотя ладно, буду чуть серьёзнее — постепенно все растения заболевают и дохнут, чтобы другие не болели — посевы периодически сжигают. Все ресурсы человечества брошены не на борьбу с болезней растений, а не выращивание ещё большего их количества. Также, постоянно случаются пылевые бури (слава богу, не радиоактивные), и доблестным американским фермерам, живущих в насквозь дырявых халупах приходится постоянно вытирать песок.
Да, этот мир весьма странен, в нём летают беспилотные самолёты (причём летают 10 лет и больше, на солнечных батареях), комбайны управляются автоматикой, при этом все живут в халупах, ездят на древних пикапах и пользуются унылыми ноутбуками.
У главного героя есть сын, у которого из способностей только возможность стать фермером, и дочь, которая видит призраков. Главный герой одновременно и пилот, и инженер, и мегафизик, который запросто считает баллистические траектории и гравитационные манёвры. Ну а сейчас работает фермером и ремонтирует комбайны.

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

По ходу дела, дочери призрак сообщает банарным кодом некоторые координаты, и главный герой сразу это определяет. Мазафака, запишите координаты двоичным кодом, посмотрите что получится, а потом попробуйте собрать это назад. Ну да ладно. ГГ ведь очень крут! Он бросает всё и ломится по указанным координатам, где застаёт сверхсекретную базу NASA. Где его сразу же берут пилотом на космический корабль, у которого цель найти планеты, пригодные для жизни, чтобы срулить нафиг из этой планеты. Т.е. по факту, получается, что ресурсов у населения планеты Земля дохрена, что они могут отправить толпу людей в другую галактику, лишь бы не жрать кукурузу. Ну и делать всем точно нехрена, потому что все знают, насколько ГГ крут, правда позвонить по телефону ему и пригласить — как-то не догадались.

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

В общем, быстренько все собрались и полетели. ГГ, девушка учёный, бородатый негр и ещё один дядька (тоже учёный). Прилетели они на первую планету, и случайно оказалось, что она находится рядом с чёрной дырой, что на орбите время течёт нормально, а если спуститься, то замедляется. И час, проведённый на планете, равен 7 годам на Земле. Ну а ещё, из иллюминатора не видно, что там происходит. В общем, нашим героям делать нечего, они спускаются на планету, и узнают, что там сплошной океан (и почему в кораблях не делают иллюминаторы?), а предыдущая команда разбилась, и только робот сообщает об успешном приземлении. Твою мышь... Надо было проделать такой путь, чтобы догадаться до того, что догадались герои!

Ладно, минус один участник команды, минус 23 года на Земле, три седых волосинки в бороде у негра, который 23 года тусил на корабле и жрал кукурузу. Никаких психических отклонений нет, на землю отправить ничего не смог (предыдущая команда смогла — эти нет, для пущего сюжета). Герои вернулись на корабль, и стали слушать входящие послания. На Земле люди весьма умные, поэтому из всех вариантов: корабль разбился, корабль засосало в чёрную дыру, команду съели рептилоиды, выбрали самый вероятный: команда просто решила срулить с Земли, ибо в космосе веселее. Ооок...

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

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

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



И вот после этого, мне пытаются рассказать, какой это крутой фильм, и какая там глубокая философия. Я вот честно, целый день думал о фильме, пытался что-то выжать, не получилось ничего. Единственное светлое пятно в фильме — боевой нечеловекоподобный робот с чувством юмора, исполняющий роль говорящего R2D2.
Фильм при этом слегка отдаёт Космической Одиссей, но почему-то у Кубрика получилось сделать длинное, затянутое повествование без какого-либо действия очень интересным, тут я не увидел этого. 

воскресенье, 19 октября 2014 г.

Android. Часовые пояса. 2014 год.

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

Заканчивается 2014-ый год, в России опять переводят время, все телефоны опять начнут страдать фигнёй и путаться в показаниях.Меня удивляет, что несмотря на многочисленные пинки и тычки (а часовые пояса постоянно кто-то меняет, недавно, например, хорошо отличились Чили и Египет), в Андроиде не только не хотят подумать над автоматическом обновлением часовых поясов, даже не хотят нормально решить проблему их установки в новых прошивках. Например, у меня сейчас телефон с прошивкой недельной давности, в котором стоят зоны от 2013 года!

Немного технической информации для понимания механизма: практически во всём мире (кроме Microsoft, конечно же), информация о часовых поясов берётся из полуофициальной базы TZ Database. Я говорю полуофициальной, потому что, несмотря на контролирование этого файла IANA, по факту изменения в него вносятся обычными людьми. Т.е. я узнал, что в России будут новые часовые пояса, написал письмо и файл обновили. Никакого официоза (конечно, я надеюсь, что эту информацию хотя бы проверяют по новостям).

Эта база имеет формат ГодБуква, где год — это год обновления базы, а буква — порядковый номер обновления. На данный момент это 2014h, следующая будет 2014i или 2015a, в зависимости от того, когда выйдет.

База представляет собой набор текстовых файлов определённого формата, которые под *nix компилируются в специальные бинарные файлы с правилами. Текущая зона вешается симлинком на один из этих файлов. Например, на Europe/Moscow.
В других системах, эта база может иметь другой вид. Например, на андроиде до версии 4.3, это было 3 файла, но с версии 4.3 — стал уже один. Значит зачем-то программисты подбирались к этому коду, но совершенно не подумали о том, что он может устареть.

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

Конечно, если у вас есть рутовые права на телефоне, вы можете воспользоваться программой TimeZone Fixer, которая делает ровно одну вещь: копирует 3 файла в нужную папку. Эти 3 файла решают все проблемы. Но к сожалению, программе нужен рут, что не у многих есть. Вот так приходится работать за ленивых гугловских программистов, которым гораздо веселее в 7-й раз перерисовать иконки, чем сделать что-то полезное для людей. 

понедельник, 25 августа 2014 г.

Про мышей. Компьютерных

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

Например, я 5 с лишним лет купил самую модную мышь от Microsoft — Sidewinder X8, у которой на тот момент (да и до сих пор) были весьма модные и оригинальные решения: небольшой экран, показывающий статус (например заряд и текущий DPI), металлическое колесо прокрутки, сменные ножки, подключаемый зарядный провод на магнитике. Ну так вот, она до сих пор работает. Чуть пообтёрлась но работает абсолютно также, как и раньше. Но т.к. я любитель мышей, я периодически поглядываю на то, что можно заменить. А проблема в том, что за эти 5 лет — полная тишина.
Logitech по-прежнему клепает грустые Performance MX мыши, Mad Catz делает совершенно безумную R.A.T.9, которая очень круто выглядит но по факту почти не работает от батареи, а грязь забивается куда только можно. У Razer и то, только Mamba 2012-ого года без всяких чудес, но за приличные деньги, и Ouroboros — за неприличные. Редкие оригинальные решения типа Microsoft Arc Mouse занятны для поездок, но не для работы. 

Т.е. грусть и тоска, хочется потратить деньги, а не на что.

И тут, совершенно случайно, во время поисков в интернет-магазине чего-нить для добития суммы покупки, обнаруживаю A4Tech Bloody R8. Не буду вдаваться в маркетинговый bullshit, но A4Tech, действительно в очередной раз придумала что-то новое. Во-первых, это металлические ножки (обычно тефлон или что похуже). Во-вторых зарядка от обычного microUSB, т.е. даже спец-кабель не нужен, а приёмник вставляется внутрь мыши для переноски. Ну а в третьих, это всё стоит 1000 руб! При этом, она светится разными цветами, есть всякие мега-опции по уменьшению задержек и увеличению точности, и прочая белиберда, которая есть в той или иной мере у всех. Но 1000 руб. за мышь со встроенной батарейкой, модными ножками и приятным колёсиком — это очень круто.

А ещё более круто, что какая-то китайская компания делает больше новшеств в мышах чем все остальные вместе взятые. Например, у них всю жизнь было самое лучшее ребристое колесо (среди дешёвых мышей), которое никогда не разваливалось (привет Genius и Microsoft). Они делали мыши с двумя колёсами (очень круто), с софт-тач пластиком, с резинкой сбоку для удобного хвата. Делали мышки с питанием от коврика, делали беспроводные мыши с четырьмя аккумуляторами, зарядником от USB за какие-то смешные деньги (я до сих пор использую эти аккумы в различной технике). Они придумали гениальную MOP-35, мелкая мышь, которая была у огромного количества народа. Потому что она очень милая. Они развлекались с маленькими дырками для сенсора, чтобы было меньше пыли, делали дополнительные кнопки для двойного клика (если приноровиться, очень полезные). В общем, удивительно, сколько всего они напридумывали. Ну и вообще, у них есть одна из лучших для меня форм мышей.

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

Очень хорошо, что есть такая компания, которая периодически делает что-то действительно интересное и если хочется что-то для души, я знаю куда смотреть.

среда, 30 июля 2014 г.

Про мобильный интернет

Обнаружил, что мой пакет мобильного интернета отправился в утиль, точнее в архив. Пока работает, но на всякий случай, надо искать замену. Пока искал обнаружил следующие факты:
  • МТС даёт за 250 руб/месяц 3Гб интернета по СуперБиту, действующему по всей России (с неявными условиями действия, возможно 30 руб. в сутки за межгород)
  • Мегафон за те же 250 руб/месяц уже даёт 5Гб интернета, но только в домашнем регионе (+10 руб/сутки за межгород)
  • Билайн за те же 250 руб/месяц (как бы случайно совпало) даёт те же 5Гб интернета, но зато действует по всей России без ограничений
  • СМАРТС за 200 руб/месяц даёт полный анлим 2G интернета, что реально позволяет выкачать аж 200Мб. На большее он не способен.
Зачем я это написал? Мне показалось интересно, что что для удобства сравнения конкурентов вся большая тройка решила выровнять цены, несмотря на то, что обычно они любят чуть отличающиеся параметры для более сложного выбора.
А так получается, что в нашей деревне самый лучший и без вариантов — Билайн, и даже нет ни одного факта смотреть на других провайдеров (по качеству самого интернета претензий особых тоже нет). 
Ну, а МТС имеет неясные условия, но похоже что самый дорогой.

воскресенье, 15 июня 2014 г.

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

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

Начнём по-порядку.
  • zlibnet — считает метод Flush сигналом для записи финального блока, что приводит к некорректному поведению. Надо чинить (а лучше переписать самому, где там мой блокнотик?)
  • SharpCompress — любитель вызывать метод записи с длиной в 0 байт, что, имхо, весьма неаккуратно. Может на некоторые потоки создавать бессмысленную нагрузку
  • SharpZipLib — никаких нареканий
  • Встроенный GZip — буфер в 8Кб, полностью игнорируется Flush, оказывается для потоков его использовать нельзя.
  • Snappy — блочный алгоритм, блоки с префиксом и контрольной суммой, что накладывает отпечаток на возможностях
  • Snappy for .NET — нет реализации стримов, пропускаем
  • Snappy.NET — блок прибит гвоздями в 64Кб, Flush вызывает запись независимого блока. Т.е. частый флуш приведёт к потере сжатия и увеличению объёма
  • LZ4 — тоже блочный, при уменьшении блока резко падает степень сжатия, поведение аналогично Snappy. В реализациях (lz4-net и LZ4.NET) проблем не обнаружил (кроме самого факта с проблемами потока). Из хороших новостей — потоковое API для LZ4 разрабатывается (прямо в тот момент, как я пишу этот текст). Оно ещё не стандартизировано, но шансы есть, что будет всё круто.
  • LZF — я его достал с дальнего ящика и смотрю на него. Его особенность, что сжатие позволяет писать данные хоть по байту (и читать сжатые по байту). Правда исходные данные пока выглядят блочными, но думаю это можно будет поправить, если поисследовать алгоритм. 

суббота, 14 июня 2014 г.

Выбор быстрых алгоритмов сжатия под .NET

Для начала, пара таблиц для привлечения внимания:

Быстрый компьютер:
MemCopy:         1561.050       1709.7218        100.000%
GZipStd:           66.736        221.6318          6.335%
#ZipLib.Gzip:      52.800        136.0018          6.358%
zlibnet:          100.572        466.2888          6.500%
SharpComp.GZip:    52.568        154.7598          6.501%
Snappy.Net:       970.382        944.8468         13.312%
SnappyforNet:     997.337       1795.2078         14.499%
lz4net/CC:        485.191       1122.0048         10.740%
lz4net/MM:        997.337       1158.1988         10.740%
lz4net/N:         535.883       1122.0048         10.740%
lz4net/S:         386.066        690.4648         10.740%
lz4net/HC:         42.794       1282.2918          7.751%
LZ4.Net:          997.337       1158.1988         10.896%
QuickLZ:          460.310        528.0028          8.032%
LZO_1X   :       1683.082       1561.0508         11.824%
LZF     :         272.001        398.9358         13.882%
Медленный компьютер:
MemCopy:          394,551        394,5518        100,000%
GZipStd:           18,006         50,4278          8,738%
#ZipLib.Gzip:      16,137         45,2198          6,358%
zlibnet:           31,086        105,6008          6,500%
SharpComp.GZip:    18,356         46,6898          6,501%
Fail Snappy.Net: Инициализатор типа "Crc32C.NativeProxy" выдал исключение.
SnappyforNet:     260,175        432,5808         14,499%
Fail lz4net/CC: Ссылка на объект не указывает на экземпляр объекта.
Fail lz4net/MM: Ссылка на объект не указывает на экземпляр объекта.
lz4net/N:         218,928        228,6898         10,740%
lz4net/S:         120,484        141,9148         10,740%
Fail lz4net/HC: Ссылка на объект не указывает на экземпляр объекта.
LZ4.Net:          234,668        274,0778         10,896%
QuickLZ:           60,445         65,0448          8,032%
LZO_1X   :        374,001        505,6928         11,827%
LZF     :          44,880         60,3438         13,882%

Это я тестировал различные реализации алгоритмов сжатия и их скорости. Столбцы: скорость сжатия в MB/s, скорость декомпрессии, процент сжатого текста, относительно исходного материала.

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

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

  • QuickLZ — проблемы с лицензией,
  • LZO — работает через P/Invoke, мутный враппер, какие-то косяки с дебагом, проблемы с 64 битами не ясно дальнейшее развитие, собственно, его высокие показатели в тестах отчасти связаны с ограниченностью функционала, из-за которого, тест оказался в более выгодном положении относительно некоторых других (я даже не уверен, что он стабильно работает, хотя то что работает хотя бы один раз, это точно, я проверил)
  • LZF — хорош как вариант микро-компрессора (собственно, весь код можно зафигачить в 200 строчек не сильно экономя, при этом результат вполне сносный. Но, если вы не специалист по алгоритмам, не очень рекомендую заниматься этим делом. Хотя, возможно идея довести код до ума, вполне неплохая (надо записать себе в блокнот "обязательно сделать в следующей жизни").
Также в алгоритме не приняли участие: BZip2, LZMA и PPMd (степень сжатия отличная, скорость настолько низкая, что даже ради научного интереса их тут не стоит использовать.

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

Теперь детально разберу оставшиеся GZip, LZ4, Snappy.

Gzip

Собственно, самый известный алгоритм сжатия, использующийся поголовно везде (хотя правильнее сказать, что алгоритм — Deflate, а GZip — поток с дополнительной метаинформацией). Если вы будете использовать его — у вас не будет никаких проблем с совместимостью, так что он очень хорош в плане требования по памяти и работы в потоковом режиме.
Но с выбором реализации есть некоторые проблемы — если вы сравните две верхних таблицы, то увидите что GZipStd (я так обозвал встроенный в .NET) даёт абсолютно разные варианты. Хитрость в том, что до .NET4.5, реализация GZip в .NET была ужасная, и её использовать стоило только в одном случае — никогда. Сейчас всё изменилось, и если вы пишите под 4.5, то вполне стоит использовать этот вариант, если нет критичного требования по скорости.

Если нужна максимальная скорость, то используйте zlibnet, это P/Invoke wrapper, поэтому он работает весьма шустро. Если у вас нет желания использовать P/Invoke (чуть сложнее деплой и требуется больше прав приложению), используйте SharpCompress, он мне показался чуть более удобным, быстрым и функциональным относительно классического SharpZipLib. Есть ещё библиотека SevenZipLib — P/Invoke wrapper к 7zip, но по внешниему интерфейсу я не очень понял, как работать с GZip, хотя в описании указано.

Snappy

Алгоритм от Гугла, ориентированный на максимальную скорость. Для .NET есть 2 реализации P/Invoke с оригинальными названиями: Snappy for .NET и Snappy.Net. Есть Safe-реализация Snappy.Sharp, но я её даже не пробовал, т.к. судя по всему работы ещё дофига, она полузаброшена, ничего особо не протестировано. Опять же, если есть желание — берите сами и дописывайте, иначе не советую использовать (записал второй пункт в блокнот).

Сам алгоритм очень шустрый (судя по всему, разработка велась с учётом особенностей процессоров и их кеширвоания), но сжатие у него так себе. Также у обоих реализаций есть проблемы. Snappy.Net не работает в 32х битах из-за какой-то ошибки в реализации библиотеки, вычисляющей CRC32 (третий пункт в блокнот — написать автору, что он лох и надо поправить). Snappy for .NET — требует VS2010 runtime, о чём надо помнить (я для тестов подложил нужные dll'ки на тестовый компьютер).
В общем, пока следует использовать с осторожностью, это не Production-решение

LZ4

Один из моих фаворитов, благо скорость отличная, но надо выбрать реализацию. Их две и обе хорошие. lz4-net — P/Invoke wrapper и LZ4.NET, флакон от автора с четырьмя разными реализациями, которые выбираются по приоритету и доступности: Mixed Mode, C++/CLI (требуется установленный VS2010 runtime, проверка идёт по наличию пакета в реестре, а не по DLL), Unsafe, Safe. Также, автор, возможно будет пилить дальше и улучшать свой код.

Также у алгоритма есть HC версия, которая даёт лучшее сжатие (но скорость сильно проседает), зато декомпрессия просто безумная. По идее, можно использовать это сжатие для данных, которые редко пишутся, но активно читаются.

Качество сжатия алгоритма зависит от дополнительного буфера на словарь, который в разных реализациях по дефолту 1Мб и 256Кб, в реальности, 64Кб дают пристойный результат, но и 1Мб не очень жалко для объёмных данных. Имейте в виду.

Заключение

Я, пока в раздумьях по поводу алгоритма и реализации, склоняюсь к GZip в P/Invoke исполнении и LZ4 в комплектном. Надо заранее определиться, какая скорость вам требуется: если вы передаёте огромные данные по сети со скоростью 1МБ/c, то GZip'а вам хватит за глаза, а сжатие будет активно помогать уменьшить объёмы. Если же сеть в гигабит, а данных немного, то со сжатием связываться вообще не стоит. LZ4 сидит где-то посередине и при своей скорости подходит для всего мало-мальски сжимаемого.

Решайте сами, я пока думаю, решение напишу позднее, когда потестирую всё это в продакшене (т.е. возможно, спустя длительное время).

пятница, 13 июня 2014 г.

LeapMotion первые впечатления

Мне подарили LeapMotion, и я хочу поделиться первыми впечатлениями.
Не буду пересказывать существующие отзывы, просто несколько пунктов от меня.

  • Выглядит всё очень круто, упаковка в стиле Apple, ничего лишнего, зато два кабеля USB (короткий и длинный)
  • Софт симпатичный и просто работает (а на случай проблем есть куча диагностики)
  • Всё очень красиво, плавает и летает
  • На первый взгляд, очень хорошее API и SDK (можно получить хоть сырую информацию, хоть жесты — т.е. API само занимается математикой, чтобы вручную не вычислять)
  • Распознаются руки с пальцами: включая ориентацию ладони и фаланги (хотя точность их распознавания очень неважная), а также тыкательные предметы типа ручки (причём он понимает, что это не палец и у ручки нет ладони.
  • По факту — ладонь должна быть повёрнута вниз, пальцы растопырены, иначе не определяет. Т.е. боком ладонь нельзя использовать (или очень хорошо обрабатывать исчезающие и появляющиеся пальцы.
  • Дрожание в принципе очень хорошо сглаживается стандартным софтом.
  • Он умный и у него большой угол обзора, т.е. не надо держать руку прямо над ним, я положил под монитор и он вполне понимает мои руки, находящиеся перед
  • Идеально (имхо) положить его на место клавиатуры, но, естественно, это не получится. Перед клавиатурой — будет мешаться, так что остаётся место за клавиатурой или где-нибудь сбоку для одной руки
  • Есть программа для управления компьютером, но она так себе. Не очень удобно попадать по углам, да и резкое неправильное движение приводит к тому, что курсор прыгает и кликает в самых неожиданных местах. Её поведение — следит за пальцем (как курсор), при пересечении виртуальной границы проходит клик. Ладонью скролл. Как-то правая кнопка работает и прочие хитрости, ещё не разобрался. 
  • На весу управлять — руки быстро устают, и кроме того, сам рукой закрываешь экран (поэтому, возможно лучше где-то сбоку подцепить)
  • В магазине есть много игрушек и приложений. Но, имхо, на побаловаться. Кроме того, везде управление слегка отличается.
  • Google Earth управлением руками выглядит красиво, но постоянно куда-то крутится и двигается
  • Вообще, управление компьютером с помощью него выглядит как использование некого виртуального тачскрина.
  • В реальности, мышку заменить можно, но не нужно, если всё в порядке с руками.
В общем, не буду дальше разводить писанину, возможно, дополню пост после более длительного использования. Пока у меня планы не управлять курсором, а управлять окнами (свернуть, развернуть, закрыть, назад, вперёд, изменить громкость, и т.д.). Но стандартного софта не нашёл (во всяком случае бесплатного), поэтому попробую написать сам, именно так, как я хочу.

Если будут конкретные вопросы, пишите, отвечу. 

суббота, 24 мая 2014 г.

Деградация размера MFT от времени

Небольшая заметка посвящена тому, что недавно я обнаружил тот факт, что MFT в Windows не умеет уменьшаться.

MFT — это базовый служебный файл файловой системы NTFS, в котором хранится информация обо всех остальных файлах. Всё это весьма неплохо работает, но есть различные грабли. Сегодня расскажу про один косяк, связанный с тем, что MFT может только расти.

Представьте ситуацию, вы создали на диске миллион файлов (что не так уж и сложно), а потом их все удалили. В результате, казалось бы, место должно вернуться к исходному значению, но оно не вернётся. Потому что в MFT остались записи об этих удалённых файлах, которые никто не собирается чистить. С учётом того, что размер записи обычно порядка 1Кб, вы получили 1Гб мусора, который ни к чему хорошему не приводит. Вроде немного, но всё равно неприятно.

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

Если вы найдёте способ лучше, буду премного благодарен.

четверг, 24 апреля 2014 г.

Смена браузера

Небольшой личный пост о ощущениях при смене браузера.

Я очень давно в качестве основного браузера использовал Оперу, и всё было хорошо, несмотря на её глюки, но около года назад её похоронили и перешли на Chromium. За этот код в новом браузере появилось полторы новых фичи, так что рассматривать его в качестве основного инструмента весьма опрометчиво. Хотя в качестве другого браузера, на замену старому, вполне.

Ну так вот, старая опера постепенно работает всё хуже и хуже (сайты просто её не поддерживают, а поддержки новых стандартов как-то не прибавляется), и рано или поздно надо переезжать на что-то другое. Что я и сделал на днях.

Сразу скажу, что по жизни, я одновременно пользуюсь тремя браузерами (жизнь разработчика обязывает), так что, в общем, имею опыт работы со всеми. Но одно дело опыт, другое — основной инструмент.

И каково же было моё удивление над самим собой, что переехав на новый браузер (я выбрал Яндекс.Браузер, это такой Хром, но с мелкими вкусными плюшками), я ожидал что мне будет не хватать множества фич оперы в виде списка закрытых страниц, навороченной статусной строки, диалога при скачивании файла, встроенного блокировщика рекламы, и многого другого. А оказалось, что больше всего приносят неудобства в новом браузере — табы. Неудобная навигация между ними, отсутствие группировки, визуального превью, плохое поведение при большом количестве. И это оказалось для меня самым большим удивлением. Оказывается, наиболее важное в опере не огромное количество фич, а то как они выверены для удобства. И что не хватает, так это такого мелкого повседневного удобства. Удивительно.


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

суббота, 29 марта 2014 г.

Паранойя в андроиде, или как задолбать пользователей

Я неоднократно говорил, что если перекрутить безопасность в приложении, то это приведёт к тому, что пользователи будут отключать её, лишь бы не бесила. Или бездумно кликать на "Разрешить", потому что это окно лезет всегда.
Примеры: UAC в Vista, который лез на каждый чих (в семёрке стал реже появляться), или sudo в SUSE, которое лезет на каждое действие. Пришлось рутовый пароль поставить в 1, чтобы хоть как-то можно было жить.

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

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

Казалось бы, что страшного в установке дополнительного сертификата? Ну есть проблемы, что с помощью него могут подменять сайты, но ведь в системе и так установлена сотня сертификатов, которые никто не проверяет. И вполне может быть дырка для гугла, для производителя телефона, просто любимый сертификат АНБ. И никто по этому поводу не нервничает. Что сделали в гугле? Сразу после установки появляется неотключаемая нотификация, о том что установлен сертификат. Ещё раз. Нотификация. Неотключаемая. Т.е. вам всю жизнь надо жить с иконкой, где написано что ты идиот, даже если это не так.
Решается данная проблема с помощью рута и переноса сертификата в системное хранилище. Глупо, зато хотя бы можно решить. Через одно место, но проблему хотя бы можно решить.

Но появилась другая проблема. Мне нужен клиентский сертификат. И он работает. И всё хорошо. Но в гугле решили, что я должен себя обезопасить, и обязан включить блокировку планшета с паролем, пин-кодом или графическим кодом. У кого такая блокировка уже включена, те даже не заметят проблему. Но я тестирую на планшете, основная цель которого — смотреть фильмы, читать книжки и кидаться птицами в свиней. И ради одного сертификата, я должен включать блокировку? Да нафига? Была бы идея, если бы к этой блокировке были бы привязаны другие данные. Но если посмотреть: браузеры сохраняют пароли для сайтов, система сохраняет пароли для WiFi и Bluetooth, приложения сохраняют пароли для почты, аккаунтов синхронизации, и доступа к внешним сайтам. Это нормально. Я могу взяв чужое устройство читать чужие письма, смотреть чатики, ходить по сайтам с паролями. Никаких проблем. Но если мне вдруг понадобился клиентский сертификат, я сразу же должен всё запаролить. На мой взгляд полный бред.
Решения этой проблемы я не нашёл. Только косвенное, с установкой сертификата, тестированием и удалением. По-моему бред. Зато можно жить.

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

воскресенье, 23 февраля 2014 г.

Мысли про возможности инструментов

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

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

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

Т.к. я программист, то пример из этой области: студия без Решарпера, кажется удобной. После его использования, его отсутствие приводит к ломке. Хотя сам по себе инструмент не меняет ничего кардинально. Скрипты на нормальном языке программирования (или хотя бы на перле), приводят к тому, что можно сделать логику, которую раньше просто никто и не думал реализовывать. Знание многих языков, приводит к тому, что можно соединить несколько разных технологий и быстро написать то, что надо. Наличие большого количества оперативной памяти может привести к тому, что можно держать весь объём данных в памяти, тем самым в сотни раз ускорив приложение.

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

PS: Кстати, что удивительно, лучшие кубики Рубика делает не фирма Rubik's, а самые настоящие китайцы, фирма DaYan. Т.е. не в том плане, что в китае делается, а в том, что именно сам китайский бренд котируется лучше всего. Так, в копилку бесполезных фактов.

пятница, 31 января 2014 г.

Про кубик Рубика

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

Мысль раз — как головоломка, кубик Рубика весьма плохо выполняет свою роль. Я имею ввиду то, что практически невозможно собрать его без алгоритмов. При этом, чтобы их придумать, нужно или очень много терпения и анализа, или же очень крутым IQ.
Т.е. по факту, большинство людей без подсказок не смогут его решить. А смысл в головоломке, которую нельзя решить от меня ускользает.
При этом, если разобранный кубик раздражает чувства перфекциониста, можно выучить 7 простых алгоритмов (можно ограничиться четырьмя, но не стоит), и собирать его. Удовольствия никакого.

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

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

Итак, чем же может быть полезен кубик Рубика. Во-первых, он развивает мелкую моторику рук. Во-вторых, может слегка прокачать пространственное мышление. Возможно, также слегка помогает оценивать обстановку и быстро принимать не самое плохое решение. Не уверен.

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