MCP

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

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

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

воскресенье, 29 декабря 2013 г.

Про Internet Explorer

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

Итак, во всех рекламных статьях про новый браузер Microsoft упорно напирает на скорость и поддержку стандартов. И тут я действительно вижу улучшения. Всё достаточно шустро уже с 9-ой версии (правда, 8-ая была тем ещё тормозным ужасом), и уже можно пользоваться для обычной жизни. Но есть одно но. Имя ему интерфейс.

Судя по всему, интерфейс браузера пишет отдельная команда, и делает это из рук вон плохо. Я уже привык к мелочам, что ошибки от браузера не добьёшся. Только дурацкая страница, что ты дурак и сделал что-то не то. Недавний пример: браузер захотел идти по TLS1.2, а сервер (IIS) отдал ему TLS1.1. В результате — дурацкий текст ошибки. Хорошо, что был хром, который открыл страницу и всё объяснил.

Но у интерфейса есть более серьёзные проблемы. Во-первых, IE ещё ни разу не восстановил корректно вкладки. Постоянно меняется порядок и появляются фантомные дефолтные страницы. Эта катавасия тянется с тех пор, как в нём появились вкладки. Подобных проблем нет ни у одного другого браузера.
Во-вторых, модальные окна и невозможность остановить скрипты, если что-то пошло не так (например, зацикленный alert можно убить или с помощью ловкости или убийством из таск менеджера всех процессов IE — а потому что не найти нужный). Но модальность, на то и модальность, чтобы доводить до белого каления. Представьте, у вас есть сайт, который использует NTLM-авторизацию (или клиентские сертификаты). При его открытии вылезает окно с требованием ввести логин и пароль. Если в это время перейти на другую вкладку, и сделать это в очень правильный момент, можно получить ситуацию, когда браузер упорно не реагирует на команды, ибо я должен сделать что-то в модальном окне, которое спрятано в другой вкладке. Всё, приехали. Task Manager, killall iexplore.exe

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

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

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

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

вторник, 24 декабря 2013 г.

Забавности с async/await

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

public static void Process()
{
try
{
DoSomething();
}
catch (Exception)
{
}
}

public static async void DoSomething()
{
throw new Exception();
}

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

Подумали? Теперь правильный ответ. Будет необработанный эксепшен и аварийное завершение приложения. Бздынь! Размещаем метод DoSomething где-нибудь подальше и наслаждаемся неожиданными крешами приложения в самый неожиданный момент.

Вот это один из примеров разрыва шаблонов. Чтобы такого не повторилось DoSomething должен возвращать не void а человеческий Task, после этого, чтобы избавиться от предупреждения о некорректном поведении в методе Process надо написать await DoSomething, а чтобы скомпилировалось к Process добавить async. И вот только после этого всё будет работать как и ожидалось.

Приятного кодинга 

суббота, 16 ноября 2013 г.

Windows, делаем бекап самого дорогого

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

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

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

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

Где хранится реестр?

Он хранится в нескольких файлах. Во-первых, в папке C:\Windows\System32\config\ Там находятся файлы вида SYSTEM, SOFTWARE, SAM, COMPONENTS, DRIVERS. Это соответствующие ветки реестра. Например, SYSTEM — информация о сервисах и драйверах, SOFTWARE — установленные драйвера, SAM — данные о пользователях с внутренними идентификаторами и паролями (именно данная ветка обычно хорошо так меняется при установке, из-за чего система становится "особенно другой").
Также в этой папке находится системный профиль (профиль компьютера, который с точки зрения системы почти настоящий пользователь), и всякая другая мелочёвка.
При перезагрузке системы копия реестра сохраняется в папке RegBack. Я не очень представляю, когда данные из RegBack могут использоваться автоматически, но в случае проблем можно попытаться подменить файлы реестра из данной папки, чтобы восстановить работоспособность.

Также, в папке с профилем каждого пользователя (C:\Users\username\) находится файл ntuser.dat, являющийся реестром для данного пользователя.

Собственно, эти файлы мы и будем архивировать.

Как сделать архивную копию?

Какзалось бы, просто взять и скопировать. Но не всё так просто. Дело в том, что данные файлы заблокированы системой (справедливости ради, из RegBack можно достать файлы достаточно просто, но они будут не очень свежими в случае отсутствия перезагрузок, да и реестр пользователя не архивируется самостоятельно).

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

Мы же не будем искать аварийных путей, и займёмся использованием встроенных средств Windows, а именно Volume Shadow Copy, теневой копией.

При создании теневой копии диска, создаётся снимок всей файловой системы на заданный момент времени, с неизменяемыми файлами. Который можно использовать для чтения заблокированных файлов или использовать в качестве версии файлов на определённый момент времени (так работает System Restore в Windows, она делает примерно тоже самое, в определённых случаях).

Итак, что надо сделать:
  1. Сделать теневую копию диска
  2. Подмонтировать её симлинком для удобства работы
  3. Скопировать нужные файлы
  4. Удалить копию
Всё это можно сделать из консоли, используя стандартные утилиты, я для удобства написал всё это на Powershell.

Итак по пунктам (полный скрипт в конце поста):

Делаем теневую копию и монтируем её:
Function CreateShadow($disk)
{
    # e.g. c: -> c:\
    $disk = $disk[0] + ':\';

    $shadowObj = (gwmi -List Win32_ShadowCopy).Create($disk, "ClientAccessible")
    $currentShadow = gwmi Win32_ShadowCopy | ? { $_.ID -eq $shadowObj.ShadowID }
    $shadowID = $currentShadow.ID
    $name  = $currentShadow.DeviceObject + "\"
    $dummy = cmd /c "mklink /d .\$shadowID $name"
    Write-Host $dummy
    return $shadowID
}

В данном куске скрипта мы через WMI создаём теневую копию, получаем её идентификатор, и монтируем её в качестве симлинка в текущей папке (с названием как идентификатор теневой копии).
Используя данный скрипт уже можно вручную скопировать файлы. Ну или автоматически, примерно так:
Function PerformBackup($shadowPath, $bakRoot)
{
    if ($shadowPath -like '%\')
    {
        $shadowPath = $shadowPath.SubString(0, $shadowPath.Length - 1)
    }

    if ($bakPath -like '%\')
    {
        $bakPath = $bakPath.SubString(0, $bakPath.Length - 1)
    }

    $tmpFile = "$PWD\tmpFileList.txt"

    # if script was incorrectly finished
    if (Test-Path $tmpFile)
    {
        Remove-Item $tmpFile
    }
    Get-ChildItem -Recurse "$($shadowPath)\Windows\System32\Config" -Force -ErrorAction Continue | % { $_.FullName.Remove(0, $shadowPath.Length + 1) | Out-File -FilePath $tmpFile -Encoding ascii -Append }

    Get-ChildItem "$($shadowPath)\Users\" -Directory | % { Get-ChildItem -File -Force "$($_.FullName)\ntuser.*" -ErrorAction SilentlyContinue | % { $_.FullName.Remove(0, $shadowPath.Length + 1) | Out-File -FilePath $tmpFile -Encoding ascii -Append } }

    $archName = Get-Date -Format 'yyyyMMdd'

    # if file exists, using _1, _2, ...
    $archPath = $bakRoot + '\' + $archName;
    $iterator = 1;
    while (Test-Path "$archPath.7z")
    {
        $archPath = $bakRoot + '\' + $archName + '_' + $iterator;
        $iterator++;
    }

    $curPWD = $PWD
    cd $shadowPath
    cmd /c "$($curPWD)\7z.exe a -m0=LZMA2 $archPath.7z @$tmpFile"
    cd $curPWD
    Remove-Item $tmpFile
}

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

Дальше мы удаляем лишнюю копию:
Function DropShadow($shadowID)
{
    $dummy = cmd /c "rmdir .\$shadowID"
    Write-Host $dummy
    $currentShadow = gwmi Win32_ShadowCopy | ? { $_.ID -eq $shadowID }
    $currentShadow.Delete()
}

И лишние файлы:
Function RemoveOldBackups($bakPath)
{
    dir $bakPath | ? { $_.CreationTime -le $(Get-Date).AddDays(-30) } | Remove-Item
}

Скрипт целиком можно взять тут: backup-registry.7z (вместе с 7zip). В скрипте надо будет поправить необходимые пути и настроить его на периодическое выполнение, например, раз в день (что мелочиться-то?).

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