Константин Белкин @cbelkin
Человек, который пишет какие-то программы.
Информация
- В рейтинге
- Не участвует
- Откуда
- Москва, Москва и Московская обл., Россия
- Работает в
- Дата рождения
- Зарегистрирован
- Активность
Специализация
Mobile Application Developer
Middle
SWIFT
iOS development
Потому что в подвале статьи об этом написано.
Зашёл почитать про уязвимости - прочёл о том, что в любом ПО возможны ошибки. Спасибо за информацию. До этого, конечно, никто об этом не догадывался. Можно тогда ещё упомянуть, что у домашней микроволновки тоже есть баги в коде (что по меркам автора является ещё более защищённой ОС).
Статья и так небольшая, но примерно её половина это описание примитивных вещей, не требующих разъяснения для аудитории хабра.
Прошивка не верифицируется на этапе загрузки, так как является самой первой программой запускающейся при включении устройства. Верифицируются только последующие этапы: загрузчик iBoot и ядро XNU.
Да, уязвимость на DFU не исправляется с обновлением iOS, так как код прошивки имеет особый статус и не может быть обновлён после записи на устройство. Но уязвимость уже несколько лет как исправлена. Начиная с прошивки на A12 этот способ атаки не работает. Об этом не сказано.
Ещё и сама статья не помечена как перевод в заголовке. Можно было просто так и написать в заголовке «Реклама курсов iOS разработки» без всякой ерунды на целую статью.
По-умолчанию отладочные символы не включаются компилятором в сборку (что в Java, что в C++). Для этого используется отдельный флаг -g. Автор его явно не использовал (было бы странно). Ассертов тут нет. А для того, чтобы применить оптимизацию в C++, необходимо передать соответствующие флаги (можно использовать специальные флаги, которые включают в себя группы оптимизаций: O1, O2, O3), в противном случае компилятор не производит существенных изменений в исходный код.
Для того, чтобы выкинуть неиспользуемый код необходимо задать флаг O2 и выше. Автор это сделал в части тестов, однако не учёл каким образом оптимизировался код.
Если судить по написанному, то автор явно не использовал сборщики, а передавал флаги напрямую. Понятие дебаг/релиз применимо только к сборщикам (Make, Gradle, CMake и т.д.). Так что переключаться никуда не получится.
Ссылки:
isocpp.org/files/papers/N3690.pdf — страница 185
clang.llvm.org/docs/LanguageExtensions.html#c-14-runtime-sized-arrays
clang.llvm.org/compatibility.html#vla
В контексте статьи не имеет значения. В C++ там просто будет какой-то мусор размерностью int. Поэтому UB тут вполне defined.
Так и будет. Clang при применении оптимизации O2 и O3 даже не вызовет эту функцию. Это полностью компрометирует предложенные результаты и всю статью целиком.
Не как угодно. Это определяется стандартами и спецификацией компилятора. Люди, программирующие на C знают, что будет делать компилятор при применении определенных флагов.
В C это возможно начиная с C99, а в C++ начиная с C++14. Последние версии clang имплементируют стандарт C++14 в полном виде (так заявлено в документации).
Самое обычное выделение памяти под динамический массив в C++. Объявляется указатель на участок памяти, где будет располагаться массив не указателей, а целочисленных значений. В данном случае, конечно, new использовать было совсем не обязательно, т.к. размер необходимого массива нам заранее известен (в данном случае ваш пример с кодом приведен корректно). Но это никак не зависит от того глобальная переменная или локальная. Зависит от того, известна нам размерность или нет.
new говорит о выделении динамической памяти, а это всегда только куча, если не применены оптимизации компилятора. Указатели тут не при чем.
Кэш != стек. Помещение данных в стек не гарантирует его кэширование процессором.
В данном случае векторизовывать нечего, т.к. представленный в тесте цикл не параллелится.
Современные компиляторы уже достаточно развиты, чтобы оптимизировать такие простые циклы. Корректнее было бы сравнить полноценную программу на Java (чтобы хотя бы несколько сот классов было) и аналогичный нативный. Я уверен, что картина была бы совсем другая.
Поскольку в этом тесте запуск самой JVM и её инициализация вынесены за скобки,
вполне вероятно, что в конечном итоге процессором будет выполнен примерно одинаковый код. Плюс ещё сюда кэш, как уже говорилось. Плюс ещё сюда особенности работы эмулятора (если использовался эмулятор).
Кроме того входной тестовый поток достаточно небольшой, что можно часть времени считать погрешностью и переключением контекстов ОС.
Замеры времени производятся внутри контекста JVM, поэтому не совсем ясно насколько эффективно машина распределяет время между таймерами и полезной нагрузкой в процессе работы.
Вполне очевидно, что полноценный код с кучей Java классов будет медленнее аналогичного нативного. И тут не нужно никаких сравнений. Это аксиома. Просто потому что у нативный код не зависит от рантайма JVM.
Если в компании поощряется креативность (к работнику прислушиваются) и выделяют время на самостоятельные исследования вопроса (не спрашивают каждые 5 минут «Скоро уже?») — тогда у человека со временем появляется ощущение, что он может самостоятельно принимать решения, за которые не будет стыдно и его не выгонят (растёт).
Если человек прошёл собеседование, значит он уже не откровенный бездельник и какая-то база и желание развиваться у него есть (либо проблема в собеседованиях).
У вас в компании одни переводчики работают?
Пятая публикация автора за сегодняшний вечер. Все статьи на разные темы. Невероятная многогранность и разносторонняя развитость автора вызывает зависть.
Возможно в каких-то ситуациях такой подход и может выполнить роль предохранителя, но главным образом фантомные типы используют для разгрузки рантайма от лишних проверок, делегируя эту задачу компилятору.
Кроме этого, в статье приведены неудачные примеры, демонстрирующие отсутствие понимания культуры программирования на Swift.
1) Пример с User и Product. Для сравнения двух бизнес объектов не требуется в явном виде сравнивать их идентификаторы. Достаточно лишь унаследовать протокол Equatable и сравнивать объекты напрямую. При желании можно переопределять дефолтный алгоритм сравнения (если не требуется сравнение по всем полям структуры).
Проверка произойдет также на уровне компилятора и не даст собрать неверный код.
2) Пример с fetch. Для методов получения бизнес объектов из хранилища, также вместо идентификатора обычно передаётся объект целиком, либо используется специальный класс для задания параметров поиска NSPredicate.
Проверка тоже на уровне компилятора — никаких проблем.
3) Пример с HealthKit. Тут всё просто. Проблема из ничего. Для проверки возможности скастить единицу измерения у этого же класса есть специальный метод is(compatibleWith:) developer.apple.com/documentation/healthkit/hkquantity/1615508-is
Это конечно райнтайм, но зато без замусоривания кода лишними абстракциями.
Поэтому к такому способу жонглирования типами нужно подходить очень избирательно.
И кстати Generics во всем цивилизованном мире зовутся обобщениями (обобщенными типами), а не универсальными типами.
Поэтому я бы не стал приобщать представленные примеры к «Обычным знаниям тэгов и свойств».
Такой же смысл я вижу и в этой статье. У меня нет особой потребности часто заходить на спецификацию по HTML. А тем более читать её вдоль и поперёк — всё равно забудется. Когда мне доводится смотреть исходники чужих HTML страниц, то я редко вижу подобные решения. Поэтому скорее всего забывается даже у фронтенд разработчиков. Но я пишу в первую очередь о своих ощущениях. Что-то я видел раньше, что-то нет. Но вот наткнулся на статью, освежил информацию и взял на заметку. И вот как раз зашёл и почитал в спецификации по интересующим меня пунктам.
Проблемы с совместимостью, из представленных примеров, я увидел только у первого пункта. Атрибут loading не поддерживается браузерами Safari и Firefox. В остальном всё должно работать. Конечно, при условии, что вы не ориентируетесь на версии браузеров десятилетней давности. Но, как по мне, это уже неприлично.