...

суббота, 10 декабря 2016 г.

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

Специалисты ESET обнаружили, что миллионы посетителей популярных новостных веб-сайтов были мишенью нескольких вредоносных объявлений, которые специализировались на перенаправлении пользователей на набор эксплойтов. Этот набор эксплойтов использовался на компрометации пользователей вредоносным ПО с привлечением эксплойтов для Flash Player.

Начиная, по крайней мере, с октября месяца этого года, пользователи могли сталкиваться с объявлениями, рекламирующими такие приложения как «Browser Defence» и «Broxu». Ниже приведены баннеры этих объявлений, которые использовались для показа на веб-сайтах.

Эти рекламные баннеры хранились на удаленных доменах с названиями hxxps://browser-defence.com и hxxps://broxu.com.

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

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

Закодированный таким необычным образом скрипт использует уязвимость в Internet Explorer с идентификатором CVE-2016-0162, а также проверяет среду своего исполнения на предмет обнаружения виртуальной среды.

В том случае, если скрипт не обнаруживает признаков того, что аналитики пытаются отследить его активность, он перенаправляет пользователя на страницу посадки (landing page) набора эксплойтов Stegano с использованием сервиса TinyURL. Страница посадки пытается воспроизвести файл Flash, который специализируется на эксплуатации трех уязвимостей (CVE-2015-8651, CVE-2016-1019, CVE-2016-4117) в зависимости от того, какая версия Flash Player установлена в системе.

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

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

Мы уже наблюдали более ранний вариант этого набора эксплойтов в кибератаках на голландских пользователей. Весной 2015 г. злоумышленники специализировались на компрометации пользователей Чехии, а теперь обратили внимание на Канаду, Великобританию, Австралию, Испанию, и Италию.

В более ранних кампаниях злоумышленники пытались замаскировать свою вредоносную активность в форме рекламы. При этом набор эксплойтов использовал названия доменов, которые начинались в названия «ads», а также названия URI, которые содержали watch.flv, media.flv, delivery.flv, player.flv, или mediaplayer.flv.

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

Особенностью текущих кампаний было и то, что злоумышленники использовали такие популярные наборы эксплойтов как Angler и Neutrino в меньшей степени, чем набор эксплойтов Stegano. Количество перенаправлений на Stegano с веб-сайтов с вредоносными баннерами было выше чем в случае с Angler и Neutrino.

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

В подавляющем большинстве случаев, рекламные объявления специализировались на продвижении продукта под названием «Browser Defence». Не так давно мы обнаружили баннеры, занимающиеся продвижением ПО под названием «Broxu». Тем не менее, для простоты восприятия, мы остановимся на рассмотрении вредоносной кампании «Browser Defence». Кроме этого, обе кампании практически идентичны по своим свойствам.

Рекламное объявление было расположено на ресурсе browser-defence.com с форматом URI, похожим на следующий.

hxxps://browser-defence.com/ads/s/index.html?w=160&h=600

Документ index.html загружает скрипт countly.min.js и подает ему при исполнении начальные параметры. Этот скрипт, однако, не представляет из себя библиотеку для работы с фондовым рынком платформы и веб-аналитики с открытым исходным кодом. Злоумышленники используют сильно модифицированную и обфусцированную версию этой библиотеки, из которой был удален определенный код и вставлен новый. Этот новый код отвечает за первоначальную проверку окружения. Затем информация об окружении отправляется на удаленный сервер в качестве параметров файла gif, которые зашифрованы с помощью XOR. Информация об этом показана на скриншоте выше.

Следующая информация об окружении отправляется на удаленный сервер.

systemLocale^screenResolution^GMT offset^Date^userAgent^pixelRatio

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

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

Например, если первоначальные несколько байт альфы содержали значения 239, 253, 237, 243, 239, 237, 241, 239, 237, 245, 239, 247, 239, 235, 239, и 237, они будут декодироваться в слово «функция» (function). В этом примере, первые байты значения альфы 239 и 253 соответствуют символу 'f'.

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


(слева направо: чистое изображение, вредоносный аналог, расширенный для маскировки вредоносный аналог)

Альфа-канал неиспользованных пикселей заполняется некоторыми псевдослучайными значениями для того, чтобы сделать т. н. «альфа-шум» равномерно распределенным, что усиливает маскировку. После успешного извлечения, скрипт проверяет целостность кода JavaScript и сравнивает полученный хэш с тем заранее зафиксированным значением хэша, который указан в конце картинки. После этого, скрипт исполняется.

После своего запуска, скрипт пытается проверить среду своего исполнения, а именно, веб-браузер и запущенную ОС на предмет присутствия инструмента захвата сетевых пакетов, песочницы (sandbox), ПО для виртуализации, а также присутствие установленных security-продуктов. При этом код скрипта также пытается эксплуатировать уязвимость CVE-2016-0162 в Internet Explorer. Он также проверяет присутствие в системе различных графических и security-драйверов для обнаружения автоматической системы анализа вредоносного ПО.

В том случае, если никаких из вышеперечисленных признаков в системе не обнаружено, скрипт создает IFRAME (размером в один пиксель), устанавливает свойство окна window.name, которое будет использоваться в дальнейшем. После этого пользователь перенаправляется на TinyURL через https. Далее, TinyURL перенаправляет пользователя на http веб-страницу посадки набора эксплойтов.

После успешного перенаправления, страница посадки эксплойта проверяет UserAgent на соответствие веб-браузеру Internet Explorer, затем загружает файл Flash и устанавливает параметры FlashVars через зашифрованный файл JSON. Страница посадки также выступает в качестве посредника для Flash и удаленного сервера через ExternalInterface и обеспечивает функции шифрования и расшифровки.

Загружаемый Flash файл содержит у себя внутри еще один Flash файл и как в случае с набором эксплойтов Neutrino, он содержит три различных эксплойта для различных версий Flash Player. На втором этапе Flash файл расшифровывает FlashVars. Он содержит файл JSON с адресом URI для отправки сообщения об ошибке, названия функций JS для ExternalInterface, название функции обратного вызова и некоторые не используемые данные.

{“a”:”\/e.gif?ts=1743526585&r=10&data=”,”b”:”dUt”,”c”:”hML”,”d”:true,”x”:”\/x.gif?ts=1743526585&r=70&data=”}

В дальнейшем, он вызывает JavaScript через ExtelnalInterface.call(), который проверяет версию Flash и передает эту информацию на сервер через веб-страницу посадки. Это выполняется через зашифрованный URI параметр запроса для GIF файла. Алгоритм шифрования достаточно прост и использует значение window.name из рекламного объявления.

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

Ответ представляет из себя JSON, содержащий символ, который обозначает используемый эксплойт (CVE-2015-8651, CVE-2016-1019 или CVE-2016-4117), пароль для соответствующего эксплойта и готовый шелл-код с адресом URI полезной нагрузки.

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

Он особенно заинтересован в проверке присутствия следующего программного обеспечения.

  • vmtoolsd.exe
  • VBoxService.exe
  • prl_tools_service.exe
  • VBoxHook.dll
  • SBIEDLL.DLL
  • fiddler.exe
  • charles.exe
  • wireshark.exe
  • proxifier.exe
  • procexp.exe
  • ollydbg.exe
  • windbg.exe
  • eset*, kasper*, avast*, alwil*, panda*, nano a*, bitdef*, bullgu*, arcabi*, f-secu*, g data*, escan*, trustp*, avg*, sophos*, trend m*, mcafee*, lavaso*, immune*, clamav*, emsiso*, superanti*, avira*, vba32*, sunbel*, gfi so*, vipre*, microsoft sec*, microsoft ant*, norman*, ikarus*, fortin*, filsec*, k7 com*, ahnlab*, malwareby*, comodo*, symant*, norton*, agnitu*, drweb*, 360*, quick h

В случае обнаружения одного из вышеперечисленных компонентов, шелл-код не будет пытаться загрузить полезную нагрузку. Если полезная нагрузка получена, первые 42 байта GIF изображения отбрасываются, остальные данные расшифровываются и сохраняются в файл с использованием одного из ниже перечисленных функций.
  1. CreateFile, WriteFile
  2. CreateUrlCacheEntryA(*” google.com”,,,,), CreateFileA, CreateFileMappingA, MapViewOfFile, {loop of moving bytes}, FlushViewOfFile, UnmapViewOfFile

Сам файл полезной нагрузки запускается с помощью инструментов regsvr32.exe или rundll32.exe.

Мы наблюдали в загрузке шелл-кодом вредоносных файлов полезной нагрузки (Stegano exploit kit), которые имеют следующие обнаружения AV продуктов ESET.

Win32/TrojanDownloader.Agent.CFH
Win32/TrojanDownloader.Dagozill.B
Win32/GenKryptik.KUM
Win32/Kryptik.DLIF

После анализа загрузчиков и файлов с обнаружениями семейств Kryptik, мы выяснили, что они либо содержали в себе, либо загружали удаленно вредоносное ПО Ursnif и Ramnit.

Ursnif содержит множество модулей для кражи учетных данных электронной почты, имеет в своем составе бэкдор, кейлоггер, инструмент создания скриншотов и видео, компонент внедрения кода в веб-браузеры Internet Explerer, Firefox, Chrome и модификации http трафика. Он также может украсть любой файл из зараженной системы. Согласно информации из конфигурационных файлов, которые были найдены в образцах этого вредоносного ПО, оно ориентировано на корпоративный сектор и, особенно, на платежных сервисах и институтах.

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

Заключение

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

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

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

Присутствие следующих продуктов в системе пытается обнаружить Stegano exploit kit.



Присутствие следующих драйверов и библиотек в системе пытается обнаружить Stegano exploit kit.

К следующим строкам в своем теле вредоносная программа не обращается.

Индикаторы компрометации (IoC)

Хэши представлены в формате SHA1.

countly.min.js
24FA6490D207E06F22A67BC261C68F61B082ACF8

Код из баннера
A57971193B2FFFF1137E083BFACFD694905F1A94

banner.png с Stegano
55309EAE2B826A1409357306125631FDF2513AC5
67799F80CEF4A82A07EFB3698627D7AE7E6101AB
09425B3B8BF71BA12B1B740A001240CD43378A6C
4528736618BBB44A42388522481C1820D8494E37
FE841DF1ACD15E32B4FFC046205CAAFD21ED2AB2
7BE0A9387F8528EC185ACC6B9573233D167DF71B
A5BC07E8E223A0DF3E7B45EEFD69040486E47F27
EC326BA5CD406F656C3B26D4A5319DAA26D4D5FE
3F1A5F624E0E974CAA4F290116CE7908D360E981
33F921C61D02E0758DCB0019C5F37A4D047C9EC7
2FF89048D39BE75F327031F6D308CE1B5A512F73
9A0D9EBC236DF87788E4A3E16400EB8513743233
F36C283B89C9F1B21A4AD3E384F54B0C8E7D417A
17787879D550F11580C74DA1EA36561A270E16F7
9090DB6731A8D49E8B2506087A261D857946A0EB
45B3EE46ADA9C842E65DCF235111AB81EF733F34
F56A878CA094D461BDF0E5E0CECED5B9903DB6E0
6C74A357B932CF27D5634FD88AA593AEF3A77672
0C3C22B8AA461C7DE4D68567EEA4AE3CD8E4D845
5A5A015C378159E6DC3D7978DAD8D04711D997F8
B2473B3658C13831C62A85D1634B035BC7EBD515
9638E1897B748D120149B94D596CEC6A5D547067
0195C8C7B687DD4CBF2578AD3CB13CD2807F25CB
FEC222095ABD62FC7635E2C7FA226903C849C25C
0FCB2B3ED16672A94CD003B4B53181B568E35912
03483E4039839F0807D7BEC08090179E62DBCC60

Страница посадки набора эксплойтов Stegano
67E26597CF1FF35E4B8300BF181C84015F9D1134
CD46CEE45F2FC982FBA7C4D246D3A1D58D13ED4A
191FFA6EB2C33A56E750BFFEFFE169B0D9E4BBE4
4B2F4C20CC9294F103319938F37C99C0DE7B4932
3FCEA1AFDA9888400D8DE5A232E4BF1E50D3380F
CA750F492691F4D31A31D8A638CE4A56AF8690D0
1374EE22D99ECFC6D68ADE3ACE833D4000E4705B
6BF1A2B7E8CA44E63E1A801E25189DC0212D71B9
B84AB2D5EAD12C257982386BC39F18532BF6939E
476A0455044B9111BDA42CDB7F4EA4E76AA7AB2D
0C1CA7D9C7E4B26A433946A6495782630EF6FD18
29B6DD92FBDF6070B171C38B1D3CA374F66E4B66
89DA7E7A88F9B6CBBFAF7F229BFEA8767220C831
CEE32C8E45A59D3084D832A9E6500AE44F75F7B5
A152AB43BEDCD8F6B7BFB67249C5599CF663D050
3AC722AC0D4764545A3E8A6DF02059C8A164CA17
25E0474E4F8D7D3053278B45A9C24380275B4705
35FB5F3C2957B4525A0330427397915AEEFDDD91
19EEE9745E25194DD573423C6DB0F5AF5D8CFE1D
E88B2B7A08322738C74B29C4CA538741F85A0B7F
A388A2A241339489685CB4AD22EBA9E04B72CD67

Файлы Flash
BADAE04BFF7AFD890C3275E0434F174C6706C2C6
6EF95ACB8AA14D3BA8F1B3C147B7FB0A9DA579A2
10840AEB8342A26DFC68E0E706B36AC2B5A0D5B2
093B25B04FE21185BFEEAFD48F712942D3A3F0C6
C680734AF8670895F961C951A3629B5BC64EFE8E
EEDBBB65A441979974592343C6CA71C90CC2550F
DE288CADE8EE3F13D44719796A5896D88D379A1E
9488CDBB242BE50DF3D20B12F589AF2E39080882
B664365FC8C0B93F6A992C44D11F44DD091426DD
7557B5D987F0236FF838CD3AF05663EFA98EBC56
24B7933A8A8F6ED50FBAF2A5021EF47CE614A46F
11BA8B354001900ED79C43EA858F1BC732961097

Образцы URL
TinyURL.com
/jf67ejb
/jqp7efh
/j56ks2b
/gplnhvm
/gwwltaf
/hgnsysa
/hvfnohs

Страница посадки набора эксплойтов Stegano
hxxp://conce.republicoftaste.com/urq5kb7mnimqz/3dyv72cqtwjbgf5e89hyqryq5zu60_os24kfs1j3u_i
hxxp://compe.quincephotographyvideo.com/kil5mrm1z0t-ytwgvx/g7fjx4_caz9
hxxp://ntion.atheist-tees.com/v2mit3j_fz0cx172oab_eys6940_rgloynan40mfqju6183a9a4kn/f
hxxp://entat.usedmachinetools.co/6yg1vl0q15zr6hn780pu43fwm5297itxgd19rh54-3juc2xz1t-oes5bh
hxxp://connt.modusinrebus.net/34v-87d0u3
hxxp://ainab.photographyquincemiami.com/w2juxekry8h9votrvb3-k72wiogn2yq2f3it5d17/j9r
hxxp://rated.republicoftaste.com/6t8os/lv-pne1_dshrmqgx-8zl8wd2v5h5m26m_w_zqwzq
hxxp://rence.backstageteeshirts.com/qen5sy/6hjyrw79zr2zokq1t4dpl276ta8h8-/3sf9jlfcu0v7daixie_do6zb843/z7

Комментарии (0)

    Let's block ads! (Why?)

    [Из песочницы] Классические парсер-комбинаторы на Python

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

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

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

    На языке Python классические парсер-комбинаторы можно описать следующим образом. Определение парсеров будет осуществляется посредством описания классов. Каждый класс будет переопределять метод __call__, который и будет выполнять всю работу.

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

    В качестве результата разбора будет возвращаться объект типа Res, который, в случае успеха, будет содержать часть разобранного AST (abstract syntax tree) и следующую позицию во входной последовательности, иначе – позицию элемента, который вызвал ошибку.

    Определение класса Res:

    class Res:
            def __init__(self, subtree, pos):
                    self.subtree = subtre
    self.pos = pos
            def __str__(self):
                    return '(' + ', '.join((str(self.subtree), str(self.pos))) + ')'
            def __bool__(self):
    return self.subtree != None
    
    

    Определение класса Tree:
    class Tree:
            def __init__(self, root = None, children = None):
    self.root = root
    if children == None:
    self.children = []
    else:
    self.children = children
            def __str__(self):
    r = str(self.root)
    c = ', '.join(str(c) for c in self.children)
    if c:
    r = '[' + r + ', ' + c + ']'
    return r
    
    

    Опишем базовый класс, от которого будут наследоваться все парсеры:
    import abc
    class Parser(metaclass = abc.ABCMeta):
            @abc.abstractmethod
            def __call__(self):
                    pass
            def __lshift__(self, other):            # переопределение оператора <<
    return Concat(self, other, 1)
            def __rshift__(self, other):            # переопределение оператора >>
                    return Concat(self, other, 0)
            def __or__(self, other):                        # переопределение оператора |
    return Alt(self, other)
    
    

    Парсер Atom принимает один элемент и сопоставляет его с элементом во входной последовательности. В случае успеха возвращает лист, ассоциированный с этим элементом.
    class Atom(Parser):
            def __init__(self, token):
                    self.token = token
            def __call__(self, tokens, pos = 0):
                    if pos != len(tokens) and self.token == tokens[pos]:
                            return Res(Tree(tokens[pos]), pos + 1)
                    return Res(None, pos)
    
    

    Парсер Concat принимает на вход два парсера. Сначала применяется левый парсер, затем – правый. Если он отрабатывает успешно, результат будет содержать лево- или право-ассоциативное дерево. Если один из них не разобрал свою часть последовательности, то вся комбинация возвращает неудачу.
    class Concat(Parser):
            def __init__(self, left, right, F = 0):
                    self.left = left
                    self.right = right
                    self.F = F              # если F == 0 строиться лево-ассоциативное дерево, иначе – право-ассоциативное                                                   
            def __call__(self, tokens, pos = 0):
                    left_res = self.left(tokens, pos)
                    if left_res:
                            right_res = self.right(tokens, left_res.pos)
                            if right_res:
                                    if self.F == 0:
                                            right_res.subtree.children.insert(0, left_res.subtree)
                                            return right_res
                                    left_res.subtree.children.append(right_res.subtree)
                                    return Res(left_res.subtree, right_res.pos)
                            return right_res
                    return left_res
    
    

    Опишем парсер альтернативы. Парсер Alt принимает на вход два парсера. Он отрабатывает успешно, если успешно отработал левый или правый парсер.
    class Alt(Parser):
            def __init__(self, left, right):
                    self.left = left
                    self.right = right
            def __call__(self, tokens, pos = 0):
                    left_res = self.left(tokens, pos)
                    if left_res:
                            return left_res
                    right_res = self.right(tokens, pos)
                    if right_res:
                            return right_res
                    if left_res.pos > right_res.pos:
                            return left_res
                    return right_res
    
    

    Опишем опциональный парсер Opt. Если его аргумент отработал успешно, то возвращает результат, иначе все равно возвращает успех, но с заданным значением по умолчанию.
    class Opt(Parser):
            def __init__(self, parser, default = None):
                    self.parser = parser
            def __call__(self, tokens, pos = 0):
                    res = self.parser(tokens, pos)
                    if res:
                            return res
                    return Res(Tree(default), pos)
    
    

    Парсер повторения Repeat работает пока не “сломается”. Если аргумент не сработал ни разу, это тоже считается успехом.
    class Repeat(Parser):
            def __init__(self, root, parser, F = 0):
                    self.root = root
                    self.parser = parser
                    self.F = F
            def __call__(self, tokens, pos = 0):
                    tree = Tree(self.root)
                    while True:
                            res = self.parser(tokens, pos)
                            if not res:
                                    break
                            if self.F == 0:
                                    tree.children.append(res.subtree)
                            else:
                                    tree.children.insert(0, res.subtree)
                            pos = res.pos
                    return Res(tree, pos)
    
    

    Парсер Prog последовательно применяет, преданные ему, парсеры и возвращает результат указанного (по умолчанию последнего).
    class Prog(Parser):
            def __init__(self, parser, *others, N = -1):
                    self.parser = parser
                    self.others = others
                    self.N = N
            def __call__(self, tokens, pos = 0):
                    i = 1 + len(self.others) + self.N if self.N < 0 else self.N
                    if i < 0 or i > len(self.others):
                            raise IndexError
                    res = self.parser(tokens, pos)
                    if not res:
                            return res
                    t = res
                    error = 0
                     j = 1
                    for parser in self.others:
                            res = parser(tokens, res.pos)
                            if not res:
                                    error = 1
                                    break
                            if j == i:
                                    t = res
                            j += 1
                    if error:
                            return res
                    return Res(t.subtree, res.pos)
    
    

    Парсер Lazy используется для описания рекурсивных парсеров. Он принимает на вход функцию без аргументов, которая возвращает парсер. Это связано с тем, что на момент описания парсер еще не определен и не может ссылаться на себя непосредственно.
    class Lazy(Parser):
            def __init__(self, parser_func):
                    self.parser_func = parser_func
                    self.parser = None
            def __call__(self, tokens, pos = 0):
                    if not self.parser:
                            self.parser = self.parser_func()
                    return self.parser(tokens, pos)
    
    

    Парсер LExp в некоторых случаях позволяет обойти левую рекурсию (к примеру, при разборе лево-ассоциативных операторов). Принимает на вход три парсера: для разбора левого элемента, разделителя и правого элемента. При отсутствии очередного разделителя возвращает результат.
    class LExp(Parser):
            def __init__(self, first, sep, parser):
                    self.first = first
                    self.sep = sep
                    self.parser = parser
            def __call__(self, tokens, pos = 0):
                    left_res = self.first(tokens, pos)
                    if not left_res:
                            return left_res
                    error = 0
                    while True:
                            sep_res = self.sep(tokens, left_res.pos)
                            if not sep_res:
                                    break
                            right_res = self.parser(tokens, sep_res.pos)
                            if not right_res:
                                    error = 1
                                    break
                            sep_res.subtree.children.append(right_res.subtree)
                            sep_res.subtree.children.insert(0, left_res.subtree)
                            left_res = Res(sep_res.subtree, right_res.pos)
                     if error:
                            return right_res
                    return left_res
    
    

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

    Комментарии (0)

      Let's block ads! (Why?)

      Персона. Алан Кэй — пророк, автор концепции GUI и языка Smalltalk

      image

      Алан Кэй любит ссылаться на себя, и часто начинает свою речь с фразы: «Закон Кэя номер один гласит...». Наверное, он имеет на это право. Много лет его недооценивали, загоняли в рамки и даже гнобили.

      Алан Кэй – человек, который не может держать свое мнение при себе, если тема дискуссии действительно волнует его. За это ему и пришлось поплатиться пару раз. Однако ему везло, и в результате он оставался в выигрыше. В его случае справедливо изречение: «Все, что ни делается — все к лучшему».

      Благодаря странному стечению обстоятельств Кэй стал заниматься разработкой ПО, а позже оказался первопроходцем в областях объектно-ориентированного программирования и графического интерфейса. На этом пути он придумал и реализовал то, что казалось невозможным ранее, о чем большинство его коллег просто не задумывалось. «Простое должно оставаться простым. Сложное должно быть возможным», — это его жизненное кредо.

      Против системы


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

      Одаренный ребенок уже в три года научился читать и, становясь старше, непрерывно расширял свой кругозор новыми знаниями. В десять лет Алан Кэй стал победителем Национальной игры-викторины (National Quiz).

      «Когда я пошел в школу, я уже прочитал пару сотен книг. Я знал в первом классе, что они лгали мне, потому что у меня уже была своя точка зрения. Им (учителям) не нравилась идея различных точек зрения, так что это была битва», – рассказывал Кэй.
      Действительно, зная больше, чем все его одноклассники и большинство учителей, он не мог не демонстрировать этого. Но неординарные способности и не по годам развитый ум стали поводом для насмешек со стороны сверстников и травли со стороны педагогов. Таким образом достоинства ребенка система превратила в недостатки.

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

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

      image

      Поворот в карьере


      Но другой талант, принесший ему гораздо большую известность, неожиданно обнаружился у Кэя … в армии, куда он пошел добровольцем. Нет, речь не о виртуозном умении подметать асфальт граблями: тестирование показало, что у него блестящие способности к программированию. В связи с этим Кэй был направлен в ВВС США для работы на компьютере IBM 1401. Это стало судьбоносным моментом в его карьере.

      Алан служил на военной базе Рандольф, где работал с компьютером Burroughs 220.

      Burroughs 220 – ламповый компьютер фирмы Burroughs Corporation, который тогда располагался в Детройте. Он был разработан в 1957 году компанией Electrodata Corporation и назывался Electrodata Datatron 220 до того, как Electrodata была поглощена Burroughs. В разное время устройство стоило от $601 000 до $325 000 и выполняло умножение за 2, а деление почти за 4 микросекунды.

      Университеты


      По завершении службы в ВВС Алан Кэй был направлен Национальным Центром Атмосферных Исследований в университет Колорадо на факультет математики и молекулярной биологии.
      Получив степень бакалавра, в 1966 году он поступил в университет Юты на факультет инженерии. К тому времени Кэй понял, что посвятит свою жизнь ИТ-технологиям.

      image

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

      С 1967 по 1969 год Алан Кэй в рамках работы над своей диссертацией разрабатывал программное обеспечение для компьютера Flex. Хотя Flex не был запущен в массовое производство, он по существу явился прототипом персонального компьютера.

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

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

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

      Пайперт и ставший его соратником Дуглас Энглебарт пытались превратить тяжеловесную машину (в то время, кроме мэйнфреймов, ничего и не было) из «поезда», движущегося по лимитированным компанией путям, в «автомобиль», обладающий свободой передвижения.

      «В 1968-м я впервые увидел, как Сэймур Пейперт работает с детьми и LOGO, и узнал по-настоящему эффективную систему распознавания рукописного текста. Это — невероятная система… Когда я объединил это с идеей того, что дети должны использовать это, понятие компьютера обрело смысл суперсреды», – вспоминает Алан Кэй.
      В это время у него созрел замысел о создании первой в истории модели персонального компьютера — «Динамическую книгу» (Dynamic Book).

      image

      В 1969 году Кэй защитил докторскую диссертацию, в которой разработал принципы создания персонального компьютера — мощного, но простого в управлении. После этого Алан Кэй стал профессором Стэнфордского университета и проработал два года в Стэнфордской лаборатории искусственного интеллекта.

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

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

      Первый — это запоминание поучительных историй; иногда они формулируются в виде афоризмов, пословиц и поговорок. Это также народные предания, фольклор… Второй метод — это метод логических рассуждений, метод изучения цепочек причинно-следственных связей, путь математики и формальной логики. Остается третий метод — это метод «системной динамики». Метод формирования в мозгу интуитивных картин поведения тех или иных объектов и систем, принадлежащих внешнему миру.

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


      Xerox


      С таким багажом Кей в 1972 году занял должность руководителя группы перспективных исследований (Learning Research Group) в Xerox Palo Alto Research Center (PARC). На тот момент компания практически добилась монополии на рынке копировальной техники и стремилась расширить сферу своей деятельности.

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

      В начале 70-х многим казалось, что «вот-вот» бумажные носители информации и средства из обслуживания канут в небытие. На смену должно было прийти что-то другое. Было ясно, что в основе должен быть компьютер. Алан Кэй и команда должны были придумать, как именно это можно реализовать.

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

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

      Работая над соотношением между семантикой сообщения и носителем, Кэй писал:

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

      Dynabook — прототип ноутбука


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

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

      В марте 1977 года Алан Кэй и Адель Голдберг отправили статью под названием «Personal Dynamic Media» в журнал Computer.

      «Представьте себе, что Вы можете иметь Ваш собственный навигатор знаний в портативном пакете размером и формой с обычную записную книжку… Предположите, что он имеет достаточно возможностей, чтобы сохранить тысячи страниц исходных материалов, стихотворений, писем, рецептов, записей, чертежных данных, анимаций,… динамических моделей, и что-нибудь еще, что бы вы хотели сохранять и редактировать. DynaBook можно использовать для чтения или записи как обычную книгу с иллюстрациями, но она (DynaBook) предоставляет гораздо больше возможностей: динамический поиск может быть осуществлен для индивидуального контекста», — писали Кэй и Голдберг.
      Кэй описал DynaBook как портативное интерактивное устройство с плоскопанельным сенсорным экраном, беспроводной системой коммуникации и мультимедийными возможностями. Здесь предполагался принцип WYSIWYG (what you see is what you get), текстовые редакторы и система рисования.

      image

      Для этой машины будущего был спроектирован и смоделирован графический интерфейс Star GUI, включивший все знакомые нам сегодня элементы — окна, пиктограммы, меню и многое другое. Графический интерфейс Star стал прототипом интерфейса Macintosh.

      Проект Dynabook так никогда и не был завершен, однако его роль в ИТ-индустрии очевидна.

      SmallTalk


      Самым значительным практическим результатом работы Алана Кэя в Xerox PARC стало создание языка Smalltalk. Существовавшие в то время языки программирования в основном были ориентированы на решение вычислительных задач. Они обладали необходимыми средствами для работы с символами, но были слишком сложны и не соответствовали проекту Dynabook. Поэтому разработке нового языка был отдан высокий приоритет. Некоторые его идеи были заимствованы из Simula и у Пайперта, который создавал язык Logo на основе работ французского психолога Жана Пиаже.

      В течение двух лет, начиная с 1970 года, Алан Кэй работал над языком Smalltalk, который разрабатывался для того, чтобы смоделировать ранее описанную биологическую модель, состоящую из ячеек (или «клеток») и передачи сообщений между ними. После выхода Smalltalk на рынок (1983 год) язык приобрел широкую популярность. Он был одним из первых языков объектно-ориентированного программирования, олицетворяющим методологию, на основе которой можно создавать параллельные системы, базы данных и базы знаний.

      image
      Структура классов в SmallTalk на примере 'Rectangle'

      Изначально предполагалось, что инструмент программирования Dynabook будет совсем простым, доступным для детей. Его первая версия, написанная на BASIC, вышла в октябре 1972 года. Через четыре месяца появилась версия на языке ассемблера (Smalltalk-72), и позже, в 1974 году, когда ее установили на Alto, можно было начинать экспериментальную работу с детьми.

      В Smalltalk-80 были добавлены метаклассы, что соответствовало концепции «всё есть объекты». Smalltalk-80 был первой версией, доступной за пределами PARC — сначала как Smalltalk-80 Version 1, розданный небольшому количеству компаний и университетов для «экспертной оценки». Позже, в 1983 году, были выпущены общедоступная реализация, известная как Smalltalk-80 Version 2. Эти модификации языка были уже «недетскими».

      image

      Чтобы язык можно было использовать на различных платформах, его реализовали в виде виртуальной машины (Virtual Machine, VM) и виртуального образа (Virtual Image, VI). VI представлял собой библиотеку классов, в которой реализована функциональность Smalltalk, включая определение структур данных, методов работы с текстами и графикой, компиляторы, декомпиляторы, отладчики. Компилятор генерировал код на промежуточным языке, названном byte codes. VM обеспечивала интерпретацию байт-кодов на любой платформе. Все это вызывает ассоциации с Java на уровне подкорки. Это говорит о той серьезной роли, которую сыграл SmallTalk в программировании.

      Жизнь после Xerox


      Кроме DynaBook и SmallTalk у Алана Кэя были и другие проекты. Будучи лидером научно-исследовательской группы в PARC, Кэй содействовал разработке Ethernet, лазерной печати и сетевой клиент-серверной модели ARPANet.

      Кэй предлагал Xerox инвестировать в некоторые из его проектов, но управление Xerox не пожелало развивать его идеи и вкладывать крупные ресурсы в его работу. Когда Стив Джобс, Джеф Раскин и некоторые другие лидеры Apple посетили PARC в 1979 году, они сразу же увидели огромные перспективы в работах Алана. Они были поражены идеей оконного интерфейса и гибкостью языка Smalltalk. Работа Алана в PARC была зерном, из которого вырос Арple Macintosh.

      Кэй ушел из Xerox в 1983 году и после небольшого перерыва стал ведущим программистом-исследователем в Apple Atari, в 1984 году — на Macintosh, первом массовом компьютере с графическим пользовательским интерфейсом.

      image

      В 1996 году Кэй перешел на должность вице-президента по исследованиям и разработкам в компанию Walt Disney. Он трудился в подразделении Walt Disney Imagineering Lab., где разрабатывались самые новые аттракционы для парков Disney World.

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

      После ухода из Disney, в 2001 году, он основал исследовательский Институт Вьюпоинта (Viewpoints Research Institute), некоммерческую организацию, посвящённую детям, обучению и передовым разработкам программного обеспечения, где является председателем.

      В 2003 году Кэй стал лауреатом премии Тьюринга за вклад в развитие объектно-ориентированного программирования. В 2004 году он получил Премию Киото.

      Позже Кэй работал в команде Applied Minds, затем стал главным сотрудником (Senior Fellow) в Hewlett-Packard пока HP не распустил команду перспективных исследований в области программного обеспечения 20 июля 2005 года.

      С 2006 года Алан разрабатывает систему STEPS (STEPS Toward Expressive Programming Systems) на гранты National Science Foundation.

      В 2015 году Илон Маск вместе с группой инвесторов из IT-индустрии основал фонд OpenAI, который займется исследованиями, способными предотвратить восстание искусственного интеллекта против людей. У фонда будет наблюдательный совет, который возглавил Алан Кей.

      След в истории


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

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

      Комментарии (0)

        Let's block ads! (Why?)

        В C и C++ (C++17) до сих пор нет нормальных многомерных массивов, которые были в Fortran начиная с Fortran 90

        [Перевод] Интервью с разработчиком инопланетного софта: «Случись что, моя задница приняла бы основной удар»

        Багофича .RU или как получить проблемы там, где их не должно быть уже много лет

        «Один мой друг» (с) рассказал историю про свои приключения с DNS.

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

        Глава 1
        Еще раз проверяем DNS зоны, убеждаемся, что нигде нет старых адресов и очень давно. Проверяем из разных регионов запросами на каждый из своих NS. Везде всё отдаётся правильно. Берем tcpdump и смотрим запросы на 53 порт на старыx DNS. Оказывается, что запросов к ним удивительно много. И это при том, что IP адреса этих серверов уже много месяцев нигде не фигурируют!
        Смотрим tcpdump на новых DNS, а там запросов заметно меньше, чем на старых. Просто чудеса!
        Проанализировав запросы к старым DNS, берем top10 клиентских адресов и выясняем, что это BIND9 (отвечает на dig +short version.bind txt chaos @сервер) крупных отечественных провайдеров (Ростелеком, ТТК и т.д.).

        Глава 2
        Слезно просим нескольких коллег прорезолвить клиентские домены с домашнего интернета через DNS сервер провайдера ( dig any clientsite.ru. @ns1.provider.ru ) и получаем ответ с неверными IP адресами и громадным TTL 345600 (4 суток!!!) в ADDITIONAL SECTION. Причем, если прорезолвить имя, на которое делегирован домен, то DNS сервер провайдера начинает отвечать правильными IP и правильным TTL, но «счастье» заканчивается вместе и истечением этого TTL. Ситуация воспроизводится в 6 случаях из 10, там, где рекурсором у провайдера используется BIND9. Собираем тестовую площадку с последней версией BIND9 на debian и ubuntu, ситуация воспроизводится, перезапуск и т.п. не помогают.

        Глава 3
        Внезапно приходит идея запросить корневые сервера зоны .RU ( на текущий момент это a.dns.ripn.net., b.dns.ripn.net. и т.д., список можно получить командой dig ns ru. ). И получаем тот самый ответ с неверными IP адресами, TTL 345600 в ADDITIONAL SECTION. Проблему удалось локализовать, теперь нужно понять, как она возникла.

        Глава 4
        Вспоминаем теорию про DNS, читаем на всякий случай статью в Википедии про склейку зон (Glue Records). Так как уже очень давно Glue Records не используются (лет 5-6), то приходим к неверному выводу: кто-то из клиентов умудрился при делегировании домена указать старые IP адреса DNS. Пришлось написать скрипты, которые по списку клиентских доменов запросили whois для анализа.
        К сожалению, из-за этого неверного предположения потеряли время, но зато нашли другие ошибки. Например, клиенты любят доменную почту от Яндекса и умудряются делегировать домен на наши NS и на NS Яндекса одновременно.

        Глава 5
        На следующее утро, проанализировав еще раз собранные данные whois, ничего не находим. Остаётся только обращаться в RU-Center с диагностикой и нашими предположениями. Не смотря на длительное сотрудничество с этой компанией, у нас практически не было обращений в техподдержку, в основном вопросы возникали по бухгалтерской части. Поэтому отправляем письмо на support@ и ждём ответа. Через пару часов ожидания ответа на Email наши сотрудники уже не могут терпеть и пытаются звонить по телефону. Послушав достаточное количество музыки попадаем на живого человека, который находит наше письмо и сообщает номер тикета. Ура! Однако, ответа по заявке не получаем. Еще несколько звонков с периодичностью в 1-2 часа результат не приближают. К счастью, под конец рабочего дня получаем примерно такой ответ:

        Существование glue records означает, что ранее для домена были указаны дочерние DNS-серверами с этими IP-адресами. Чтобы изменить данные записи необходимо делегировать домен на такие же дочерние DNS-сервера с указанием новых IP-адресов.

        Очень удивляемся. Последний раз glue records были очень много лет назад. Неужели, такое возможно? Поднимаем архивы почты, находим там письма за 2011 год, когда домен был делегирован на другие ns и еще раз удивляемся. Получается, столько лет оно работало неправильно и никто ничего не заметил!

        Глава 6
        А тем временем идут последние часы аренды старых железок, и мы понимаем, что при TTL в 4 дня в провайдерских кешах, потребуется проплатить еще месяц аренды, а это не совсем то, что планировалось.
        Просим поддержку Ru-Center удалить glue records. Нам ведь они совсем не нужны, зачем нам привязываться к новым IP адресам?! Тем более, что в нашей DNS зоне для каждого NS указаны несколько IP адресов + IPv6. И получаем ответ, который ставит нас в тупик. Примерно такой:

        заявка передана на исполнение в отдел системного администрирования, о результате сообщим

        Т.е. делаем вывод, что готового механизма для этой операции у регистратора нет (нам представлялось это кнопкой в интерфейсе сотрудника поддержки), а это значит, что либо никто не сталкивался с подобной проблемой (что маловероятно), либо просто меняли IP адреса в glue records и жили дальше. Но это же неправильно, ведь логично, что если удаляются IP адреса для NS у регистратора, то должны удалиться и glue records. Предполагаем, что это старые глюки, начала этого десятилетия, давно решены, и, вероятно, нам просто не повезло.

        Глава 7
        К полудню следующего дня осторожно интересуемся по email, есть ли ответ на заявку? После проходим несколько раз в квест с прослушиванием музыки по телефону, дозваниваемся до живых людей, но кроме «ваша заявка передана в отдел системного администрирования» ничего добиться не можем. Проходят еще почти сутки, нам ничего не остаётся, как последовать совету с указанием новых glue records, что мы и делаем. Через несколько часов изменения вступают в силу (как вы помните, .RU обновляется не слишком часто) и мы удаляем эти glue records (они же нам не нужны и даже мешают). Ждём следующего обновления .RU, однако, корневые сервера .RU продолжают отвечать с этими записями, но уже с новыми IP адресами. Неужели глюк остался?!!!

        Глава 8
        Так как ответа по заявке нет, на следующий день опять проходим квесты с телефонной музыкой. Особенно понравится уровень, когда попросили соединить с руководителем поддержки и девушка предупредила, что «придется некоторое время подождать» и поставила нам музыку, которая прекратилась через 30 минут и звонок разорвался. К счастью, ближе к концу рабочего дня пришел наконец ответ, что glue record удалены. Ура, товарищи!

        Глава 9
        Вспоминая про TTL в 4 дня в провайдерских кешах смотрим tcpdump. Действительно, запросов к старым DNS серверам становится всё меньше, т.е. всё идёт как задумано. Остаётся только ждать. На всякий случай, берем пару ненужных доменов и пытаемся воспроизвести ситуацию. И она повторяется!

        Для истории оставлю тут рецепт, как воспроизвести ситуацию:

        Берем первый домен ingavto.ru, создаём в нём A записи для ns10.ingavto.ru и ns11.ingavto.ru, указывающие на одну пару DNS серверов и делегируем на них этот домен с указанием IP адресов. Ждём, пока обновится зона .RU

        Берем второй домен body-m-auto.ru, делегируем его на ns10.ingavto.ru и ns11.ingavto.ru, ждём обновления.

        Первый домен делегируем на другие NS, в зоне меняем в A записях адреса для ns10.ingavto.ru и ns11.ingavto.ru, также ждём обновления.

        В результате имеем в корневой зоне .RU неправильные glue records и глюки, которые описаны выше.

        Запросим IP адреса NS серверов у гугла

        $ dig +short A ns10.ingavto.ru. @8.8.8.8
        136.243.55.209
        $ dig +short A ns11.ingavto.ru. @8.8.8.8
        136.243.55.194
        
        

        Ответ совпадает с тем, что прописано в DNS-зоне.

        Пример запроса к корневому серверу, видно, что отдаются совсем другие IP адреса:

        $ dig any body-m-auto.ru @a.dns.ripn.net.
        
        ; <<>> DiG 9.10.3-P4-Ubuntu <<>> any body-m-auto.ru @a.dns.ripn.net.
        ;; global options: +cmd
        ;; Got answer:
        ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 269
        ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 3
        ;; WARNING: recursion requested but not available
        
        ;; OPT PSEUDOSECTION:
        ; EDNS: version: 0, flags:; udp: 4096
        ;; QUESTION SECTION:
        ;body-m-auto.ru.                        IN      ANY
        
        ;; AUTHORITY SECTION:
        BODY-M-AUTO.RU.         345600  IN      NS      ns11.ingavto.ru.
        BODY-M-AUTO.RU.         345600  IN      NS      ns10.ingavto.ru.
        
        ;; ADDITIONAL SECTION:
        ns10.INGAVTO.RU.        345600  IN      A       89.249.20.188
        ns11.INGAVTO.RU.        345600  IN      A       89.249.24.177
        
        ;; Query time: 42 msec
        ;; SERVER: 2001:678:17:0:193:232:128:6#53(2001:678:17:0:193:232:128:6)
        ;; WHEN: Sat Dec 10 00:00:30 MSK 2016
        ;; MSG SIZE  rcvd: 153
        

        Эпилог
        К сожалению, не удалось выяснить, это проблема связана только с Ru-Center или актуальна для других регистраторов. Если у вас есть пара доменов для экспериментов, купленных через другого регистратора, пожалуйста, протестируйте и напишите в комментарии.
        С большой вероятностью, такая проблема может существовать не только для домена .RU, но и для домена.РФ, но у нас тоже нет сейчас таких доменов для теста.
        Также напрашивается очевидный вывод, что в настоящее время не стоит использовать glue record для домена .RU и в некоторых случаях имеет смысл обращаться к регистраторам с заявкой на зачистку таких записей.
        P.S. Было бы неплохо, если бы кто-то из специалистов, работающих в Ru-Center или другом регистраторе, прокомментировал ситуацию.

        Комментарии (0)

          Let's block ads! (Why?)

          Telegram-bot: моя история. Часть вторая

          пятница, 9 декабря 2016 г.

          Путеводитель по JavaScript Promise для новичков

          Функциональные языки в разработке аппаратуры

          [Перевод] Асинхронная обработка запросов в СУБД в памяти, или как справиться с миллионом транзакций в секунду на одном ядре

          Анимации на GPU: делаем это правильно

          Russian AI Cup. Промежуточные итоги чемпионата

          Вот уже месяц длится Russian AI Cup 2016. Это соревнование по программированию искусственного интеллекта, которое проходит в форме игры. Мы подробно рассказывали об идее и правилах нынешнего года здесь.

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

          Открытый бета-тест первого раунда


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

          Много объектов. CodeWizards — это первая игра с большим количеством объектов. Во все предыдущие годы мы ограничивалось десятками, сейчас их может быть около пятисот: это деревья, миньоны, строения, снаряды и так далее. Такое количество объектов плохо влияет на работу стратегий и тестирующей системы.

          Большое потребление оперативной памяти. Описания объектов занимали слишком много места в ОЗУ. Игра долго загружалась и тормозила. Самое неприятное — она могла даже упасть из-за того, что не укладывалась в лимиты памяти, отведённые для одной вкладки браузера.

          Основную работу мы провели над визуализатором. Вместо того чтобы заново загружать изменяемые объекты, мы стали хранить историю их изменений. Все положения 3D-моделей мы подсчитываем в начале игры. Это немного замедляет загрузку, зато увеличивает fps. Нам удалось снизить среднее количество потребляемой оперативной памяти почти вдвое: с 1 Гб до 500 Мб. Когда всё заработало, мы добавили в игру звуки, чтобы наблюдать за результатами было интереснее.

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

          Мы внедрили специальный механизм кеширования. Он позволил не передавать объекты, которые не изменились со времени прошлой отправки. Это было непросто: мы обновили код взаимодействия на всех языках программирования. Сейчас у нас есть несколько участников, прошедших во второй раунд на Ruby. Python же используется многими топ-игроками и спокойно конкурирует с быстрыми языками вроде Java, C# или C++.

          Изменения правил игры. Мы внимательно следили за отзывами игроков на форуме. Они помогли нам сбалансировать правила и сделать игру более ровной. Помимо некоторых незначительных изменений стоит отметить увеличение урона зданий, увеличение количества баллов за подбор бонуса со 100 до 200, а также появление бонусов парами, а не случайно в одной из двух точек. В начале игры никто не боялся башен, а ходить за бонусами было невыгодно: очков они давали мало, а могли и вообще не появиться.

          Новые языки. Как и в прошлые годы, сообщество расширило список языков, на которых можно писать стратегии. Теперь Russian AI Cup поддерживает сразу 10 языков. Добавились D, Go, JavaScript и Scala. Спасибо авторам языковых пакетов!

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

          Итоги первого раунда


          25 и 26 ноября прошел первый раунд чемпионата. Для участия в нём мы отобрали 1090 лучших стратегий из 1500 поступивших к тому моменту. Первый раунд состоял из двух этапов по 12 часов с перерывом в 24 часа. Во время них тестирующая система комплектовала и запускала игры. Итоговый рейтинг основан на результатах 40 сражений.

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

          Жулики :(


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

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

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

          Бета-тест второго раунда


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

          Новые правила. Кроме того, мы вновь внесли ряд изменений в правила.

          • Количество жизненной энергии зданий во всех режимах игры уменьшено вдвое

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

          Поскольку набор опыта зависит от количества урона, мы подняли этот коэффициент, чтобы не замедлять прокачку героев.
          • Количество опыта за подбор бонуса уменьшено с 200 до 150

          Подняв количество опыта до 200 в первом раунде, мы получили ситуацию, в которой во время появления бонуса все покидают битвы и бегут за ним. Теперь стоять на линии значительно выгоднее за счёт первых трёх изменений.
          • Мультипликатор урона от бонуса empower снижен с 2 до 1,5

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

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

          Приглашаем принять участие в чемпионате


          Присоединяйтесь к CodeWizards 2016! Технически в игру можно загрузить крутую стратегию хоть за три дня до финала и выиграть. Дополнительный набор из Песочницы ждёт талантливых программистов!

          Комментарии (0)

            Let's block ads! (Why?)

            HighLoad++2016: как это было

            [Перевод] Как мы превратили 140 тысяч $ на Kickstarter в 40 тысяч $ долга, а затем вошли в ноль

            Этот пост является 3-й частью статьи «Создание игры «The Contender» («Соперник»)»: концепция завершения". Здесь ссылки на часть 1 (как мы сделали игру) и часть 2 (как мы запускали проект на Kickstarter).

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

            Я — Джон Тисдэйл. Мы с другом создали «The Contender» («Соперник»): игра на тему президентских дебатов. 9 сентября 2015 года мы собрали 127 827,01 долларов США на Kickstarter. Казалось бы — очень большие деньги, но лишь на этой неделе, 22-го ноября 2016 года, мы, наконец, расплатились с долгами. Прошло 440 дней работы после создания продукта и кампании на Kickstarter, прежде чем мы получили 1 доллар.

            Мы не ожидали, что так будет.

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

            image

            Вопрос 1. Где производить?


            image

            Что мне делать со всеми этими деньгами!?

            В игровом бизнесе самые большие возможности имеют США и Китай. Наш перечень достоинств и недостатков обоих этих вариантов выглядел следующим образом:

            США

            • Мы получаем возможность поставить старую, добрую, крупную надпись «Сделано в США».
            • Быстрая доставка, особенно в праздники.
            • Ясное и быстрое общение. Мы можем даже посещать завод.
            • Быстрая доработка, если качество окажется не тем, что мы ожидали.

            КИТАЙ
            • Намного дешевле. Почти на 50% дешевле.
            • Я печатал игры в Китае ранее и имел хорошие отношения с компанией, которую мы использовали.

            После обсуждения мы решили остановиться на США. Мы надели розовые очки и очень хотели выпустить продукт на рынок к Рождеству. В октябре все компании делают большие заказы, чтобы подготовиться к празднику. Если опоздать, то задержки, возможные при изготовлении и доставке, могут сорвать срок доставки.

            Мы выбрали крупного производителя из США, который печатал карты для игр Uno, Settlers of Catan и Magic: The Gathering. Полагаясь на их опыт, мы рассчитывали, что ребята смогут обеспечить нам некоторую «страховку» от плохих производственных идей.

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

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

            Наше предположение о «страховке» не оправдалось. Здесь даны три примера проблем, приведших к потере времени, денег и доброжелательного отношения инвесторов:

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

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

            3. Наши расширения «Politically Incorrect» (PI) прибыли в Amazon без какой-либо маркировки. Компании Amazon пришлось задержать наши поступления для обработки, а многие коробки PI затем были вообще отмаркированы неправильно. Мы всё ещё получаем 3-4 возврата в месяц от клиентов, которые получили коробку PI вместо базовой игры.

            Все эти задержки накапливались, угрожая сорвать нашу поставку к Рождеству, несмотря на печать в США. Если вы поддержали наш Kickstarter, то вы, возможно, помните наше сообщение, в котором шла речь именно об этом. Людей это, конечно, не обрадовало. Ещё хуже: после того как Amazon поместил игру на склад, некоторые люди могли начать получать игру через сервис Amazon Prime до того, как пошла поставка от Kickstarter.

            К нам потоком пошли письма. Проблема, с которой к нам обращался каждый наш приверженец в середине декабря, была одна: «спасите Рождество». Мы обратились ко всем, кто планировал подарить игру. Все, кто откликнулся, были переведены на бесплатную доставку в течение 2 дней. Примерно 1 000 игр поступила покупателям вовремя, но некоторые опоздали. Всё это обошлось нам примерно в 10 000 долларов США.

            Вопрос 2. Сколько заказывать?


            Здесь надо решить, сколько вы готовы инвестировать в самого себя. Создавая свой проект на Kickstarter, необходимо иметь перед собой 2 цели. Публичная цель — сколько денег надо собрать, чтобы их хватило на выпуск продукта. Личная цель — сколько денег надо собрать, чтобы запустить компанию, способную выпустить этот продукт. Последняя цель много выше. Наша прикидка давала 150 000 долларов США. Это значило, по нашему расчёту, сработает эффект масштаба, и бизнес сможет сам поддерживать себя, принося прибыль.

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

            1. Мы продали 4 000 игр за месяц, и это было только начало года выборов. Если мы сможем удержать хотя бы 25% нашего драйва, то мы продадим приблизительно 20 000 игр ко дню выборов в США.

            2. Однако — если мы закажем 20 000 игр, то у нас сразу же появится долг 40 000 долларов. Не считая того, что мы окажемся подвешенными с расширениями PI & 2016.

            3. Соображение #2. Если мы закажем 20 000 игр и продадим их, то получим по 150 000 долларов!

            4. Мы: «Мы хотели бы заказать 20 000 игр!»

            5. Изготовитель: «Пожалуйста! Убедитесь, что вы заплатите нам оставшуюся часть денег, которую вы нам должны, когда вы продадите их!»

            6. Реальность:

            image

            7. Мы:

            Оказывается, Kickstarter — это страна волшебных фантазий, где люди приходят в восторг от ваших предложений таким способом, который не преобразуется в ваш малый бизнес. После разговоров с разными людьми, занимающимися этим делом, выяснилось, что это норма. Если вы удержите 8% от вашего Kickstarter-импульса в течение года, то это значит, что вы преуспели. У нас было 4%. Генеральный директор гораздо более опытной игровой компании сказал нам, что, когда он чувствует себя особенно агрессивным, он заказывает в 2-3 раза больше объёма предварительного заказа. Мы импульсивно заказали в 5 раз больше. Ясно, что мы были сверх-оптимистичны.

            Насколько оптимистичны?

            image

            Большой урок: если вы планируете продавать за пределами Kickstarter, то закажите максимум вдвое больше уже проданного.

            Если бы мы печатали в Китае и напечатали только то, что мы должны, то мы получили бы по 23 000 долларов каждый.

            Малыш, что теперь?


            Первая проблема, с которой мы столкнулись, была в хранении изделий. Начальная максимальная вместимость Amazon.com была 5 000 изделий. Я пустил в дело знаменитый «северный шарм» и получил бесплатное расширение до 8 000 единиц. Это было прекрасно, поскольку у нас было как раз 7 500 единиц товара (базовая колода + расширение PI) для немедленной отправки. Недоставка этой партии привела бы к серьёзным задержкам. Несколько сотен копий игры расположилось вдоль стенок офиса «Guts and Glory». Где было остальное, я не мог сказать точно. Видимо, где-то на краю пространства и времени.

            И это привело нас ко второй проблеме. Как нам продавать всё это? Сначала всё казалось так легко. Ниже описано то, что мы пытались делать:

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

            Попытка: реклама через Фейсбук.
            Результат: вложено ~1 000 долларов в 30 различных рекламных забросов, получено ~20 кликов, 0 продаж.

            Попытка: представлено на каналах YouTube, имеющих >1 000 000 подписчиков.
            Результат: по результатам было продано 3-4 игры.

            Попытка: выпущено несколько комических рекламных роликов, где кукольные президенты играют в эту игру.
            Результат: потеряно очень МНОГО времени — разочарование полное. Нет какого-либо заметного усиления продажи.

            Попытка: мы побывали на кокусах в Айове и на первичных выборах в Нью-Гемпшире, фигурировали в локальных новостях, были подробно описаны на Daily Dot.
            Результат: усиление онлайн-продажи на 75%, пока мы двигались. Но это едва окупилось, поскольку мы тратили деньги, чтобы оставаться на волне. Мы приписываем более активное усиление социальным сетям.

            Попытка: написание статей, позиционирующих любезность штаб-квартир компании в штатах Айова и Нью-Гемпшир.
            Результат: море веселья. Денег немного.

            Попытка: хвалебная реклама в Wall Street Journal (отчасти просто свалилась нам в руки)
            Результат: усиление онлайн-продажи на 100% за 3 дня.

            Попытка: аренда стенда на «Politicon».
            Результат: чистая прибыль ~1 000 долларов.

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

            Попытка: продукты, спонсируемые компанией Amazon.
            Результат: действительно работает. Мы затратили примерно 2,70 доллара на рекламу на каждую продажу базовой игры.

            — ОБНОВЛЕНИЕ —

            Попытка: написание серии откровенных материалов о нашем бизнесе в надежде, что кто-нибудь раздует этот материал на Hacker News / Reddit.
            Результат: привет всем!

            — КОНЕЦ РЕДАКТИРОВАНИЯ -

            Попытка: сделать больше расширений и рассказать о них людям, которым уже понравилась наша игра.
            Результат: ЧЁРТ ПОБЕРИ, ПОЧЕМУ МЫ НЕ ДЕЛАЛИ ЭТО ВСЁ ВРЕМЯ!

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

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

            Что дальше?


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

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

            Комментарии (0)

              Let's block ads! (Why?)

              Первый баг на Марсе

              В 1971 году СССР доставили на Марс первые в мире планетоходы «на лыжах», которые должны были щупом (динамический пенетрометр и гамма-лучевой плотномер) ткнуть поверхность, и сказать — Марс твердый или жидкий пыльный. Первый аппарат разбился 27 ноября, второй совершил мягкую посадку 2 декабря, но марсоходик не смог выбраться из «скорлупы» посадочного модуля, поэтому попытку не засчитали.

              Прошло 25 лет.
              4 июля 1997 года на Марс прилетел американский аппарат и привез «пришельца» с первым багом.


              Кадр из к/ф «Марсианин». Главный герой держит в руках марсоход Sojourner

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

              Соджорнер (Sojourner)


              image

              Стоимость программы была относительно невысокой — 265 млн $.
              Марсоход проработал в течение 83 сол.

              Название марсохода, Соджорнер, дословно означает «временный житель» или «проезжий», оно было дано победителем голосования — 12-летним мальчиком из штата Коннектикут, США. Марсоход назван в честь женщины-борца с негритянским рабством — Соджорнер Трут.

              image

              Результаты миссии:

              • 2.3 миллиарда бит информации
              • 16500 изображений с посадочного модуля
              • 550 изображений с марсоходика
              • 15 химических анализов камней и пыли
              • много климатических данных
              • пища для размышления тестировщикам

              Priority inversion


              image

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

              image

              Компьютер на посадочном модуле — радиозащищенный IBM Risc 6000 Single Chip (Rad6000 SC) 20 MIPS CPU с 128 MB RAM и 6 MB EEPROM. Операционка — VxWorks.
              image

              На ровере был 0.1 MIPS Intel 80C85 CPU с 512 KB of RAM и 176 KB твердотельной флэш-памяти.


              На 1553 шине висят 3 таска с различными приоритетами.

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

              image
              image

              Оставалось только подправить пару флагов для семафора.

              Как исправляли баг


              No, we did not use the vxWorks shell to change the software (although the shell is usable on the spacecraft). The process of «patching» the software on the spacecraft is a specialized process. It involves sending the differences between what you have onboard and what you want (and have on Earth) to the spacecraft. Custom software on the spacecraft (with a whole bunch of validation) modifies the onboard copy. If you want more info you can send me email.

              Процесс «исправления» ПО на космическом корабле является специализированным процессом. Он включает в себя отправку различий между тем, что вы имеете на борту и тем, что вы хотите (и имеете на Земле) космическому кораблю.

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

              — Глен Ривз, тимлид разработчиков софта для Mars Pathfinder

              How the patch was uploaded?

              VxWorks contained a C language interpreter to execute statements on the fly during debugging. The JPL engineers decided to launch the spacecraft with this feature still enabled. A short C program was uploaded to the spacecraft, which when interpreted, changed the values of the mutex flag for priority inheritance from false to true. No more system reset occurred!


              Глен Ривз на фоне дубликата Mars Pathfinder, инженер, который нашел и исправил баг

              Баг был обнаружен при тестах на Земле еще до запуска, но ему присвоили низкий приоритет.

              Подробности


              image

              Презентация китайского эксперта


              Комментарии (0)

                Let's block ads! (Why?)

                Можно ли обойтись без jsx и зачем?

                Я уверен, большинство из вас, кто использует react используют jsx. Благодаря своему лаконичному синтаксису jsx улучшает читабельность шаблонов. Сравните:


                render() {
                    return React.createElement('div', { className: 'block'}, 'Text of block');
                }
                // vs
                render() {
                    return <div className='block'>
                        Text of block
                    </div>;
                }
                

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


                Чем плох jsx


                Все бы хорошо, если бы jsx был бы стандартной возможностью javascript, но это не так. Для работы с jsx вам потребуется транспилятор. Решив использовать jsx вы навечно становитесь зависимы от транспиляции. Еще недавно, такая зависимость никого не пугала, так как для использования новых возможностей из ecmascript 2015 вам в любом случае необходим транспилятор. Но все меняется, уровень поддержки es6 близок к 100%


                По крайней мере, в develop-окружении уже можно избавляться от транспиляции. Представляете, какие возможности это открывает? Не нужно при дебаге ковыряться в выходе babel, который многое изменил, не нужны source map, после изменения файла нет необходимости ждать, пока закончится пересборка. И jsx в данном случае будет главной помехой… Есть ли альтернативы jsx?


                Альтернативы jsx


                Стандарт ecmascript 2015 определяет тегированные шаблонные строки. Пример, выше можно переписать так:


                render() {
                    return es6x `<div className='block'>
                        Text of block
                    </div>`;
                }
                

                Более сложный пример:


                import Input from './input';
                
                render() {
                    return <div className='block'>
                        <Input name='name1'
                            value={this.props.value}
                            {...this.props.inputProps}
                            checked
                        />
                        {this.props.items.map(item => <span {...item.props}>{item.text}</span>}
                    </div>;
                }
                // преобразуется в:
                render() {
                    return es6x `<div className='block'>
                        <${Input} name='name1'
                            value=${this.props.value}
                            ${this.props.inputProps}
                            checked
                        />
                        ${this.props.items.map(item => es6x `<span ${item.props}>${item.text}</span>`)}
                    </div>`;
                }
                

                Как подключить


                npm install --save es6x
                

                Пакет es6x поддерживает разные движки. Среди них react, hyperscript (h), а также (по умолчанию) универсальный вывод в json вида:


                {
                    tag: 'div',
                    attrs: {
                        className: 'block'
                    },
                    children: ['Text of block']
                }
                

                Чтобы использовать совместно с react нужно указать метод вывода перед первым вызовом (в одном месте проекта):


                import React from 'react';
                import es6x from 'es6x';
                
                es6x.setOutputMethod(React.createElement);
                

                Особенности пакета es6x


                • размер в сжатом виде около 2 кб
                • шаблоны кешируются — во время первого исполнения создается кеш, который используется при повторных вызовах
                • решена проблема пробельных символов внутри шаблонов, которой страдает jsx:

                return <div>
                    {'some text'}
                    {' '}
                    <b>strong</b>
                    {' '}
                    <i>emphase</i>
                </div>
                

                В примере выше, в jsx требуется добавлять уродливую кострукцию {' '} между словами "text", "strong" и "emphase" а в es6x этого не потребуется:


                return es6x `<div>
                   ${'some text'}
                   <b>strong</b>
                   <i>emphase</i>
                </div>`;
                

                Производительность


                es6x поддерживает кеширование, благодаря чему, при повторном вызове с тем же шаблоном не происходит парсинга и вызов происходит намного быстрее. Повторный вызов по результатам тестирования в 10 раз быстрее первого (в случае универсального парсинга в json, в случае парсинга для react разница меньше — менее чем в 2 раза). Так же я производил сравнение с конкурентным пакетом t7 при парсинге для react. Результаты:


                jsx-выход: 15683 ops/sec ±1%
                es6x: 11187 ops/sec ±1%
                t7: 10253 ops/sec ±1% (не поддерживает многих плюшек jsx)


                То есть падение производительности около 30%. Что оказалось меньше, чем я ожидал. Объясняется тем, что метод createElement достаточно тяжелый.


                Пользуйтесь, сообщайте мне о багах. Всем спасибо за внимание.

                Комментарии (0)

                  Let's block ads! (Why?)

                  Как повысить Open Rate на 50%: советы и кейс от SendPulse

                  Email рассылки хорошо работают на привлечение и построение доверительных отношений с клиентами. В этом канале продвижения маркетологи анализируют не одну метрику, среди которых и Open Rate. Эта метрика показывает, открывают ли ваши письма читатели. Советы о том, как не потратить силы и средства впустую, делая рассылки, с кейсом клиента SendPulse, читайте в нашей статье.

                  image
                  Фото Ray (Flickr)

                  Как определить высокий ли у вас показатель Open Rate? Статистика компании Silverpop показывает, что в разных сферах бизнеса уровень уникальных открытий у рассылок отличается. Не существует определенной нормы, ведь у каждой отрасли свои особенности.


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

                  Теперь давайте разберемся, как же повысить Open Rate ваших рассылок.

                  Сегментируйте


                  Представьте, что вы получили рассылку с приглашением на мероприятие, которое проходит в городе, далеко от вас. Даже если вы хотите на него пойти, это географически неактуально. Или предположим, после покупки телевизора в интернет магазине вам все равно приходят рассылки с рекламой телевизоров. Из этого следует, что делать одинаковые рассылки для всей базы нежелательно.
                  Open Rate писем сегментированного списка получателей на 13,07% выше, чем рассылка по неразделенной базе адресов.

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

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

                  • поведение на сайте;
                  • посещаемые страницы;
                  • данные из формы подписки;
                  • данные из CRM;
                  • история покупок;
                  • брошенная корзина и т.д.

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

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

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


                  Избегайте излишеств


                  Не передавайте эмоции через капс лок и лишние знаки препинания. Если в теме будет написано «СКИДКИ, СКИДКИ, СКИДКИ !!!!!», то у читателя может сложится впечатление, что на него орут.
                  Не используйте слова, на которые реагируют спам фильтры почтовых сервисов, назовем их условно спам словами.

                  Запомните наиболее явных из них:

                  image

                  Поработайте над темой письма


                  Тема может как заинтересовать, так и оттолкнуть.

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

                  Ограниченное предложение

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

                  Газета The New York Times: «Срок предложения истекает завтра: Экономьте 60% на безлимитном доступе».

                  image

                  Компания Godiva Chocolatier: «Остались считанные часы: бесплатная доставка на все заказы от 25$».

                  image

                  Обратите внимание, что в самом письме от Godiva Chocolatier тоже указано ограничение:

                  image

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

                  Grovemade, производитель стильных аксессуаров для техники Apple, интригует темой письма: «Ограниченная серия золотых часов».

                  image

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

                  image

                  Расскажите, что ценного в вашем письме

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

                  «9 советов, 4 выпуска и 1 модный подарок»

                  image

                  «6 травяных чаев для снятия стресса»

                  image

                  «5 трендов – не пропусти (нам особенно нравится №2)»

                  image

                  Спорим, вы уже заинтересовались, какие тренды рекомендует магазин Mud Pie?

                  image

                  Подарок

                  Статистика покупок через промо-кампании в рассылках показывает, что 50 % опрошенных раз в месяц покупают товары из промо-письма.

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

                  Выполненное обещание

                  Обманывая ожидания подписчиков, вы теряете их доверие и свою репутацию – это же настолько очевидно. Но все равно находятся компании, не брезгующие типичным спамерским подходом, когда тема многообещающая, а внутри вас ожидает пустышка. Дальше чем одноразовая накрутка Open Rate, так не заехать. Не стоит писать в теме о скидках до 70%, если вы их не предлагаете.

                  Взгляните на пример интернет-магазина Wine Anthology, который в теме письма обещает продукт по самой выгодной цене в интернете. Открывая письмо, читатель сразу видит экономию при покупке – все честно!

                  image

                  Тема: «Качество 91 уровня от Roussillon по самой низкой цене в интернете!»

                  image

                  Сплит-тестирование


                  Marketing Sherpa провели исследование о том, влияет ли день отправки на Open Rate. Его результаты показали, что не существует четкой тенденции самого успешного дня.

                  Хотя и считается, что есть наиболее оптимальное время для отправки рассылок, практика показывает противоположное. Определить его для себя можно только путем регулярного сплит-тестирования.

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

                  Кроме времени отправки, рекомендуем также протестировать открытия с несколькими темами.

                  Повторная отправка по непрочитанным


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

                  Нашему клиенту, www.apple-iphone.ru, с помощью повторной отправки удалось повысить Open Rate рассылки почти на 50%.

                  Подписчикам отправлялось вот это письмо:

                  image

                  Первую рассылку оправили с темой: «Итоги недели: дата презентации iPhone 7, ФАС против Apple и iOS 10 beta 5». Тему при повторной отправке изменили на: «Дата презентации iPhone7, ФАС против Apple и iOS 10 beta 5».

                  В результате повторная отправка добавила почти 50% к статистике открытий.

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

                  И конечно же, не забывайте о качественном и ценном контенте. Высокого вам Open Rate!

                  Комментарии (0)

                    Let's block ads! (Why?)