@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 типы, работа с которыми поддерживается в рантайме.
Но это всё софистика, философия, что угодно. В разработке платят не за философское прочтение спецификаций, а за технический дизайн, который решает задачи в ограниченных до уровня практической применимости рамках.
Можно не накапливать ошибку «плывя» по времени. Для этого нужно заложиться на источник текущего времени. Правда тут много подводных камней — см. 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
Если мы говорим о мейнстриме (C++/C#/Java), то общая практика состоит в избегании применения не ASCII символов в коде. До сих пор бывают проблемы с кодировкой исходников, что приводит к нежелательным последствиям. А ещё можно представить, что потом эти названия полезут в некое публичное API. А это накладывает дополнительное требование поддержки не ASCII-символов на все инструменты, которые с этим API работают, будь это линкеры для библиотек или OData/REST кодогенераторы для WebApi. Слишком большая проблема для ровного места :)
Это смотря как пользоваться. На прошлой работе был коллега, который писал длинный метод, а затем бездумно выделял куски кода и делал Extract Method. Получал методы с кучей параметров, из которых половина — out и ref (речь о C#). Поддерживать Это было невозможно.
Такие скачки происходят как раз для локального времени, так как оно определено как смещение от времени UTC. Реальная проблема заключается в том, что не все правила перевода сохраняются в базах времени. Бывают ситуации, когда перевод из UTC в локальное время может быть выполнен неправильно для достаточно старых дат (несколько лет назад), что может искажать, например, отчёты.
Вообще, чтобы описать конкретный момент во времени необходимо три величины: дата/время + оффсет + название тайм зоны.
По первым двум параметрам вопросов нет, а зачем название тайм зоны?
Если углубится, то при высоких требованиях к расчётам разницы между двух дат, в этот список можно добавить и количество добавленных високосных секунд — на данный момент 27.
@Kaspersky_Lab, а как подобные уязвимости вляют на безопасность Kaspersky OS? Насколько я знаю, эта ОС заточена на контроль потоков данных на уровне архитектуры ядра, но как она позволяет бороться с чисто аппаратной возможностью получить неавторизованный доступ к защищённым данным?
Спасибо за ответ. Он подтвердил мою позицию.
Любой корректный вопрос по 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 типы, работа с которыми поддерживается в рантайме.
Но это всё софистика, философия, что угодно.
В разработке платят не за философское прочтение спецификаций, а за технический дизайн, который решает задачи в ограниченных до уровня практической применимости рамках.
Ссылки на пруфы:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/types#821-general
Вся статья отчаянно напомнила "Хроники лаборатории". Сжечь подстанцию - done. Не хватило только перегонки фикуса в
спиртсолярку.О, да.
Код.
Настораживает отсутствие валидации входных данных. Это must have для практического использования.
Вы использовали
EncodeToUtf8
илиEncodeToUtf8InPlace
? Можете показать код этого теста?Также полезно сравнить производительность в разрезе кодирования и декодирования утилитарными методами.
Encode (gist)
Decode (gist)
Полный лог: gist
Дело в том, что если решать задачу на разного рода 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
Так что погрешность погрешности — рознь.
Подход привязки к реальному времени я использовал в продакшене при реализации микширования звука нескольких голосовых звонков: звуковые потоки от нескольких абонентов плавают друг относительно друга, но они все подтягиваюся к реальному времени и взаимная погрешность не нарастает.
можно убрать сравнение
watch.ElapsedMilliseconds <= sleepMs
, так как еслиwatch.ElapsedMilliseconds
будет большеsleepMs
, тоneedSleepMs
будет меньше нуля, что уже отсекается условиемneedSleepMs > 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
Т.е. тело цикла и функции, в котором он находится, стало ещё более сложным и непонятным? А в чём профит Вашего действия?
По первым двум параметрам вопросов нет, а зачем название тайм зоны?
Если углубится, то при высоких требованиях к расчётам разницы между двух дат, в этот список можно добавить и количество добавленных високосных секунд — на данный момент 27.