Pull to refresh
29
2.1
Send message

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

Если выйти тёплым летним вечером под звёздное небо, то мы ощутим как «повеет холодом» сверху.

Это субъективное  ощущение «повеет холодом» означает объективное резкое  увеличение теплопотерь с поверхности кожи за счёт усиления излучения в сторону холодного чёрного звёздного неба.

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

Такое же ощущение «повеяло холодом» возникает в квартире зимой если подойти вплотную к холодному стеклу окна.

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

Нет. Ощущение холода возникает от того, что излучение извне не приходит, а не от того, что мы начинаем куда-то сильнее излучать.

При охлаждении воздуха в слое травы водяной пар конденсируется на тонкой холодной траве в виде росы или инея (при отрицательных температурах).

Трава здесь не при чём, пар конденсируется на всём, просто трава торчит

Статья отмечена как сложная, но рассуждения во вступлении не очень умные. Какие такие задачи Google отличаются от обывательских, и как это проявляется в языке общего назначения? Дальше статья обещает, что в Go работа с Win32API проще, чем в С и C++, и нагло врёт. Это биндинги к тем же самым функциям, только аргументы приходится обёртывать в unsafe.Pointer(). Но потом дошёл до вот этой части

Поэтому задача как-то серьезно взаимодействовать с WinAPI (дальше чем разовый вызов какой-то функции) — всегда была, есть и будет сложной.

А разработка под Windows является отдельной специальной дисциплиной, чемпионы которой запросто могут не знать обычный C/C++ вообще и всю разработку (даже серверную) вести на инструментах WinAPI.

Что за чушь? Нет ничего сложного в Win32API. И чего такого разработчики под Windows не знают в "обычном" C ?

Ещё одно враньё статьи - это обещанная работа с Win32API «из коробки». Судя по примеру в главе "WinAPI и графический интерфейс" из коробки есть только syscall, и приходится пользоваться либами, которые спрячут преобразования типов.

Ну и так, технические придирки. Почему вы всё время ссылаетесь на CEdit, это же класс из MFC ? В Win32API этот класс окна называется "Edit". Насчёт того, что он не поддерживает добавление текста - это вы плохо искали .

Ловить в библиотечном коде InterruptedException и вызывать в обработчике interrupt() - хреновая идея. Его вообще не надо ловить. Если уж дошло до того, что блокирующую операцию хотят прервать, то её нужно прервать, и выйти из метода, внутри которого это случилось, позволив вылететь этому InterruptedException из метода. В последнем примере используется BlockingQueue, она так и делает. Не библиотечный код, а приложение должно решать, что делать в случае прерывания операции.

Вы в первом примере точно не забыли вначале скопировать j4 в k4 ?

А во втором примере точно не забыли второй if ?

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

По комментарию: не могли бы вы, пожалуйста, рассказать, какого рода вычислительная нагрузка на брокерах, что она может быть "повышенной"? Я бы предположил (в случае с Kafka), что они пишут байты на диск и отсылают байты на другие узлы кластера, то есть упираются в диск и сеть. При этом чем принципиально отличается добавление узлов Bookeeper от добавления узла Kafka? И там, и там нужна железка и процесс.

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

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

Нет никакой связи между выделенностью и упрощением

Когда SDK обращается к прокси, оно спрашивает, где находится интересующая её партиция. А SDK отвечает,что партиция находится на таком‑то узле

Наверное, хотели написать "А прокси отвечает". И вообще оно тут уже не прокси, ибо перестаёт пропускать трафик сквозь себя, это редиректор.

По стеку вызовов видно, что внутри функции TBatch::Serialize много времени тратится на лишнее копирование строки

по стеку не видно, что оно лишнее

Я правильно понимаю, что та память, на которую указывает этот string_view, может быть перезатёрта в последующих вызовах readline(), то есть строку нужно или сразу анализировать, или сразу копировать?

Давно не читал такой занятной каши.

Попробуем переписать то же самое, но «функционально» — без изменяемого состояния

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

Поехали дальше. Вставка

Так, мы можем заменить использование `.flatMap` в одном из наших первых примеров на использование `match`

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

И завершение главы

На основе вышесказанного дадим своё простое определение эффекта

никак не основывается на вышесказанном (вообще ни одного примера "эффекта" не было продемонстрировано), и само определение ни разу не добавляет понятности.

Логичность и последовательность изложения во второй главе также хромают. Непонятно к чему упомянув свёртку, к середине статьи автор таки произносит волшебное слово "хвостовая рекурсия", которое каждый функциональщик изучает раньше, чем слова "монада" и "функтор". Но, чёрт, оказывается, что хвостовая рекурсия - "не всегда это так просто", поэтому давайте перепрыгнем с примера с циклом на совсем другой пример, а заодно вывернем функции наизнанку и сделаем continuation-passing style, охренеть упростили! Когда ж вы начнёте честно говорить, что и монады, и continuation-ы появляются не от хорошей жизни, на них переходят потом, когда код получается раздутым и с повторяющимися кусками. А тут все танцы были для того, чтобы показать, что функция - это монада, спасибо, это очень важно. Наконец, автор начинает раскручивать стек своих объяснений: оказывается, хвосторекурсивную функцию можно переписать в таком виде, что она останется хвосторекурсивной, просто вместо возврата там будет exit. Хвосторекурсивность не победили.

Не совсем понял

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

Если "Брокер" - это ваша разработка, то не проще и правильнее было бы спросить у разработчиков (или посмотреть в документации), чем искать в логах?

Первая проблема во всем этом — разобраться с FIX‑протоколом. Во всем этом нам удалось успешно разобраться, с помощью статей на Хабре

Опять же, если ваш брокер интегрируется с QUIK по FIX-у, то почему бы не спросить разработчиков, что такое FIX, и какие именно поля в нём использует непосредственно ваше приложение?

Но самая главная проблема при разработке эмулятора — это сбор информации, которую мы могли бы использовать, поскольку QUIK это не наша разработка, и вся экспертиза находится у вендора. 

Но "Брокер" - вроде же ваша?

За основу нашего эмулятора QUIK был взят FIX‑движок, который обеспечивает связь со сторонними системами по FIX‑протоколу

Занятно, что сам движок вы по имени нигде не называете, кроме как в тегах статьи.

Ещё косяки

  1. В сортировке выборкой у вас сначала min, но в конце max

Ну вот, уже про тупой поиск перебором в массиве в статье прочитал. Подметил пару косяков:

  1. При описании быстрой сортировки у вас между шагами 5 и 6 отсутствует указание, что массивы тоже надо отсортировать. Рекурсия пропала. В примере кода всё норм. А, ещё не обработан случай, когда есть значения, совпадающие с pivot.

  2. При двоичном поиске в отсортированном массиве обычно возвращают индекс первого элемента, который больше заданного, то есть индекс вставки.

Сначала шло вполне приемлемое изложение теории множеств, но потом внезапно

Предположим, что гравитация нарушает полноту пространственно-временного континуума.

и на это месте я сломался. Какая ещё "полнота"? Перед этим вы под полнотой понимали свойства множеств, а тут что, из пространства выпадают точки? Переход от математики к физике получился резковат.

Первая часть статьи содержала мало нового: загрузить и исполнить байткод несложно и на .NET, и на JVM. А вот загрузка и исполнение нативного когда - это интересно: там же релокации, и вызов функций из DLL. Посмотрел генераторы шеллкода, упомянутые в статье, это мощные инструменты, очень интересные, спасибо автору, что познакомил.

Нууу противоречиво. Блокирующие вызовы с одной стороны блокируют поток выполнения на неопределённое время, с другой стороны - упрощают структуру кода, он остаётся линейным. С другой стороны, тому потоку, который заблокирован, точно есть что делать, если бы он не был заблокирован? И те же самые вопросы возникают, если брать оконные приложения. Автор с одной стороны ожидает, что когда он кликает, то приложение прореагирует, с другой стороны - не хочет видеть курсор ожидания. Ну дык курсор сменился на ожидание - это приложение прореагировало. Не очень хорошо, что заблокировался UI-поток, в нём происходит отрисовка. Но интерфейс приложения всё равно придётся заблокировать, каким-нибудь модальным диалогом, разве что добавив кнопку "Cancel".

Ну неплохо. Я вброшу пару советов:

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

  2. В коде совместно (вперемешку) используются макросы .IF и инструкции cmp, выглядит странно. Вы в начале статьи задаётесь вопросом: зачем писать на ассемблере, и даёте на него риторические ответы. Мой ответ другой: иногда нужно хакнуть или отреверсить программу, и для этого приходится читать дизассемблированный код, и чтобы его понимать, нужно натренировать глаз читать ассемблер. Для такой тренировки лучше не пользоваться макросами.

  3. Я поглядел код на гитхабе, есть странности. В процедуре отрисовки зачем-то два цикла по клеткам, достаточно было бы одного. И точно не нужно для каждой клетки вызывать CreateFontIndirectA с последующим DeleteObject, шрифт лучше проинициализровать на старте программы. С brush-ами я бы тоже посоветовал так же поступить.

  4. Процедура CalculateTileRect сделана не очень. Я бы из CalculateTileRectPos убрал бы второй параметр additionalTileSize. Тогда из CalculateTileRect можно будет сделать только два вызова CalculateTileRect, а не четыре, как сейчас, и добавлять вот этот additionalTileSize только для нижней и правой граней.

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

Извиняюсь за тупой вопрос, но вот в декомпилированном коде непосредственно перед вызовом SetEnvironmentVariableA есть цикл, в котором в строке ищется "=", чтобы разбить строку на имя переменной окружения и значение. А если этого "=" не будет, то он так и будет сканировать память, пока не повезёт?

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

описавший дифракцию и её частный случай — интерференцию

Наоборот, дифракция - частный случай интерференции

Information

Rating
1,239-th
Registered
Activity