Pull to refresh
12
0
Дмитрий Разумихин @radium

Разработчик

Send message

@Kaspersky_Lab, а как подобные уязвимости вляют на безопасность Kaspersky OS? Насколько я знаю, эта ОС заточена на контроль потоков данных на уровне архитектуры ядра, но как она позволяет бороться с чисто аппаратной возможностью получить неавторизованный доступ к защищённым данным?

Спасибо за ответ. Он подтвердил мою позицию.

Вопрос: все типы данных C# делятся на две группы по два типа (итого 4), назовите их, а также укажите сходства и различия между группами и между типами в группе.

Любой корректный вопрос по C# должен быть отражён в спецификации языка. Если такого отражения нет в спецификации, то это не более чем творческое прочтение предметной области.

Так вот согласно спецификации действительно существует две основные группы типов - это типы-значения (value types) и ссылочные типы (references types): Value types and reference types are the two main categories of C# types.
Хорошо, смотрим как можно сгруппировать типы-значения. В документации есть ответ на этот вопрос:
A value type can be one of the two following kinds: 1) a structure type 2) an enumeration type. Хорошо, берём ссылочные типы. С ними не так всё радужно, документация гласит, что C# has many built-in reference types.. Можно погрузится глубже и в параграфе 8.2.1 прочитать что A reference type is a class type, an interface type, an array type, a delegate type, or the dynamic type..
Ну т.е. их как минимум 4.

Всё что не находит подтверждения в спецификациях является личным субъективным переосмыслением, которое к инженерии не имеет никакого отношения.

Например можно ответить, что ссылочные типы делятся на классы и интерфейсы.
Или что они делятся на те, которые известны в compile time и dynamic типы, работа с которыми поддерживается в рантайме.

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

Ссылки на пруфы:

Вся статья отчаянно напомнила "Хроники лаборатории". Сжечь подстанцию - done. Не хватило только перегонки фикуса в спирт солярку.

О, да.


Код.


Intel Core i5-7440HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=5.0.101
  [Host]     : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
  DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT

|                                 Method |       Mean |     Error |    StdDev | Ratio | RatioSD |
|--------------------------------------- |-----------:|----------:|----------:|------:|--------:|
|          System_Convert_ToBase64String |  51.039 ms | 0.4572 ms | 0.4276 ms |  1.00 |    0.00 |
|           BaseN_Base64Convert_ToString | 162.071 ms | 0.9066 ms | 0.7571 ms |  3.17 |    0.03 |
|             System_Base64_EncodeToUtf8 |   2.416 ms | 0.0266 ms | 0.0236 ms |  0.05 |    0.00 |
|                              NaiveLoad |   6.463 ms | 0.0337 ms | 0.0316 ms |  0.13 |    0.00 |
|                                AvxLoad |   1.649 ms | 0.0187 ms | 0.0175 ms |  0.03 |    0.00 |

Настораживает отсутствие валидации входных данных. Это must have для практического использования.

Вы использовали EncodeToUtf8 или EncodeToUtf8InPlace? Можете показать код этого теста?

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


Encode (gist)


|                                 Method |      Mean |    Error |   StdDev | Ratio | RatioSD |
|--------------------------------------- |----------:|---------:|---------:|------:|--------:|
|          System_Convert_ToBase64String |  51.32 ms | 0.549 ms | 0.514 ms |  1.00 |    0.00 |
|           BaseN_Base64Convert_ToString | 164.16 ms | 1.372 ms | 1.283 ms |  3.20 |    0.04 |
|           BaseN_Base32Convert_ToString | 185.88 ms | 1.935 ms | 1.810 ms |  3.62 |    0.04 |
| Wiry_Base32Encoding_Standard_GetString | 108.34 ms | 1.035 ms | 0.968 ms |  2.11 |    0.03 |
|       SimpleBase_Base32_Rfc4648_Encode | 131.39 ms | 1.979 ms | 1.851 ms |  2.56 |    0.05 |
|                  Albireo_Base32_Encode | 184.59 ms | 1.801 ms | 1.685 ms |  3.60 |    0.05 |

Decode (gist)


|                               Method |        Mean |     Error |   StdDev | Ratio | RatioSD |
|------------------------------------- |------------:|----------:|---------:|------:|--------:|
|      System_Convert_FromBase64String |    86.81 ms |  0.619 ms | 0.579 ms |  1.00 |    0.00 |
|          BaseN_Base64Convert_ToBytes |   180.61 ms |  1.902 ms | 1.588 ms |  2.08 |    0.02 |
|          BaseN_Base32Convert_ToBytes |   200.32 ms |  1.687 ms | 1.408 ms |  2.30 |    0.02 |
| Wiry_Base32Encoding_Standard_ToBytes |    56.67 ms |  0.510 ms | 0.477 ms |  0.65 |    0.01 |
|     SimpleBase_Base32_Rfc4648_Decode |   104.86 ms |  1.144 ms | 1.070 ms |  1.21 |    0.02 |
|                Albireo_Base32_Decode | 1,485.12 ms | 10.363 ms | 9.694 ms | 17.11 |    0.17 |

Полный лог: gist

Можно не накапливать ошибку «плывя» по времени. Для этого нужно заложиться на источник текущего времени. Правда тут много подводных камней — см. habr.com/ru/post/146109

Дело в том, что если решать задачу на разного рода sleep-ах / delay-ях — мы отвязаны от текущего времени и будем накапливать ошибку:
00:00.00
00:01.00
00:02.01
00:03.01
...
00:58.42
00:59.42
01:00.43
...
02:13.99
02:15.00 <--- 14.99 + накопленная погрешность
02:16.00
02:17.01


А если привязаться к реальному времени, то мы будем «болтаться» около реального значения с некоторой, естественной для не-RTOS операционки, погрешностью.
00:00.12
00:01.15
00:02.07
00:03.09
...
00:58.14
00:59.19
01:00.04
...
02:13.18
02:14.23
02:15.11
02:16.14


Так что погрешность погрешности — рознь.

Подход привязки к реальному времени я использовал в продакшене при реализации микширования звука нескольких голосовых звонков: звуковые потоки от нескольких абонентов плавают друг относительно друга, но они все подтягиваюся к реальному времени и взаимная погрешность не нарастает.
В этом фрагменте
    var needSleepMs = sleepMs - watch.ElapsedMilliseconds;
    if (needSleepMs > 0 && watch.ElapsedMilliseconds <= sleepMs) 
        return (int) needSleepMs;
    return 0;

можно убрать сравнение watch.ElapsedMilliseconds <= sleepMs, так как если watch.ElapsedMilliseconds будет больше sleepMs, то needSleepMs будет меньше нуля, что уже отсекается условием needSleepMs > 0.

По сути нам надо вернуть неотрицательное значение. Код
    var needSleepMs = sleepMs - watch.ElapsedMilliseconds;
    if (needSleepMs > 0) 
        return (int) needSleepMs;
    return 0;
делает именно это. А дальше его можно сократить до return needSleepMs > 0 ? (int)needSleepMs : 0;.

Если условие инвертировать, то желаемое поведение (получение неотрицательного значения) станет ещё более явным: return needSleepMs < 0 ? 0 : (int)needSleepMs;

И второй момент — Stopwatch.StartNew() возвращает уже запущенный экземпляр и делать watch.Start() не обязательно.

По видео, опубликованному полицией, видно, что женщина появилась "из ниоткуда". Примерно 1 секунда от момента визуального контакта до удара.
https://www.youtube.com/watch?v=Cuo8eq9C3Ec

Рекомендация использовать X-префиксы устарела в 2012 году с выходом RFC6648.

Creators of new parameters to be used in the context of application
protocols:

1. SHOULD assume that all parameters they create might become
standardized, public, commonly deployed, or usable across
multiple implementations.

2. SHOULD employ meaningful parameter names that they have reason to
believe are currently unused.

3. SHOULD NOT prefix their parameter names with «X-» or similar
constructs.
Если мы говорим о мейнстриме (C++/C#/Java), то общая практика состоит в избегании применения не ASCII символов в коде. До сих пор бывают проблемы с кодировкой исходников, что приводит к нежелательным последствиям. А ещё можно представить, что потом эти названия полезут в некое публичное API. А это накладывает дополнительное требование поддержки не ASCII-символов на все инструменты, которые с этим API работают, будь это линкеры для библиотек или OData/REST кодогенераторы для WebApi. Слишком большая проблема для ровного места :)
нихрена не понял откуда она и что берёт
Т.е. функция была сложна и непонятна?
логика работы (то, что функция должна была делать) перенесена в тело цикла
Т.е. тело цикла и функции, в котором он находится, стало ещё более сложным и непонятным? А в чём профит Вашего действия?
О, пасхалочка.

if len(args) == 2 && args[1] == string(x[0:2]) {
	os.Stdout.Write(x[2:])
	return 0
}


Для наглядности приведу один из реальных кусков такой работы.

        private void MakeWorkflow(WorkAndRestInputArgumentsBase arguments,
            IList<DriverActivityFullRecord> records,
            IList<DriverSpecificConditionRecord> driverSpecificConditionRecords)
        {
            List<DriverActivityFullRecord> filteredDublicateDAFR;
            List<DriverActivityInterval> driverActivityIntervals;
            IList<TimeRange> ferryOrTrainCrossingIntervals;
            MakeWorkflow_Part1(arguments as WorkAndRestInputArgumentsEuropean, records, driverSpecificConditionRecords,
                out filteredDublicateDAFR, out driverActivityIntervals, out ferryOrTrainCrossingIntervals);

            if (driverActivityIntervals.Count <= 0 || filteredDublicateDAFR.Count <= 0)
                return;

            bool isINSPTransportation;
            List<TimeRange> weeks;
            List<TimeRangeWithDriverActivityIntervals> weeksWithActivityIntervals;
            List<RestTimeInfo> recreations;
            List<WorkWeekRests> workWeekRests;
            GenericRange<DateTime> dataRange;
            MakeWorkflow_Part2(arguments as WorkAndRestInputArgumentsEuropean, driverActivityIntervals,
                                       filteredDublicateDAFR, ferryOrTrainCrossingIntervals,
                                       out isINSPTransportation,
                                       out weeks,
                                       out weeksWithActivityIntervals,
                                       out recreations,
                                       out workWeekRests,
                                       out dataRange);

        }
Это смотря как пользоваться. На прошлой работе был коллега, который писал длинный метод, а затем бездумно выделял куски кода и делал Extract Method. Получал методы с кучей параметров, из которых половина — out и ref (речь о C#). Поддерживать Это было невозможно.
у вас может теряться или дублироваться час в UTC
Такие скачки происходят как раз для локального времени, так как оно определено как смещение от времени UTC. Реальная проблема заключается в том, что не все правила перевода сохраняются в базах времени. Бывают ситуации, когда перевод из UTC в локальное время может быть выполнен неправильно для достаточно старых дат (несколько лет назад), что может искажать, например, отчёты.

Вообще, чтобы описать конкретный момент во времени необходимо три величины: дата/время + оффсет + название тайм зоны.
По первым двум параметрам вопросов нет, а зачем название тайм зоны?

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

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity