Насколько я понимаю, логика здесь другая: не «никому SSO не нужно», а сначала «SSO может иногда ухудшить производительность и точно увеличит кодовую базу» с последующим «…, а ещё пересмотр решения нарушит обратную совместимость: мы пообещали в документации определённые особенности внутреннего представления и теперь часть unsafe кода зависит от них».
И насчёт выкинем: SSO был до 1.0?
Я замечу, что описанная в статье строка с SSO имеет четыре варианта: Box, &str, &'static str, small string. Почти наверняка в std такое бы не появилось, это оптимизация под конкретную задачу с допущениями, которые неприемлемы для стандартной библиотеки.
Я как‐то заказал у Резонита трафарет в котором на слое паяльной пасты сделал дополнительные отверстия, не соответствующие посадочным площадкам. Прислали трафарет без этих отверстий.
Я им написал, что трафарет неправильный и пусть они бесплатно переделают. Выяснилось, что Резонит не использует по‐умолчанию слой пасты для трафаретов, а генерирует их как‐то из других слоёв, кажется, из слоя маски — и, соответственно, этих отверстий там не должно было быть и, по их мнению, всё в порядке.
После указания на то, что, во‐первых, на сайте про это не слова, но написано про герберы для трафаретов в качестве одного из трёх вариантов заказа (второй — проекты из CAD, третий — трафарет можно заказать для платы, но без деталей относительно того, на основе чего он будет создаваться), во‐вторых, слой пасты в проекте предназначен именно для трафаретов и его использование ожидается от производителя и, в‐третьих, даже если бы я хотел приложить герберы повторно при заказе трафарета по проекту платы это сделать нельзя, они признали что не правы в части невозможности при заказе трафарета для платы повторно приложить герберы, которые я уже приложил при заказе платы, всё же переделали этот трафарет и сказали, что теперь при таких заказах можно прикладывать дополнительные файлы. Но на сайте всё ещё не сказано, что при заказе трафарета для платы слой пасты будет игнорироваться — возможно, правда, теперь не можно прикладывать дополнительный файлы, а обязательно их прикладывать — пока необходимости заказывать ещё трафаретов у меня не возникало.
Попробуйте помодифицировать что‐то, не получив Undefined Behaviour. Для разумных программистов можно даже удалить все const — одной инкапсуляции достаточно.
Хочу спросить у Вас — как сохраняются разварки и поводки после воздействия лазером? Пережигает, не деформируются ли они?
Насколько я понимаю, лазер до них просто не достреливает, так что не пережигаются. Деформируются — не знаю, нас беспокоит наличие соединения кристалла с платой, а не форма проволочек. Если вскрытие неудачное, то мы смотрим, из‐за чего, так что я могу сказать, что бывали случаи, когда лаборатория пережигала проволочки, предположительно, кислотой (лазер бы выглядел по‐другому) или случайно застреливала микросхему лазером. Бывали и случаи, когда проволочки касались друг друга и их нужно было просто аккуратно отвести друг от друга — так что иногда от чего‐то деформируются. Не уверен, что от лазера.
И еще очень интересно, для чего нужно сохранить работоспособность открытого кристалла? Как это можно использовать?
Особенности испытаний на радиационную стойкость: изучение эффектов от воздействия ионизирующего излучения, которое сложно или невозможно получить на имеющихся установках, заменяется на изучение эффектов от воздействия того, что у нас есть. Например, мощные всплески гамма‐излучения (отлично пробивающие корпус) можно заменить на выстрелы лазером в видимом или ИК диапазоне (которое не пробьёт корпус) или на пачки электронов (воздействие от которых сильно ослабляется корпусом — и, главное, ослабляется в неизвестной степени).
Лазер для декапсуляции удобен, если не достреливать до кристалла. У нашей компании есть лаборатория, где производится декапсуляции, в том числе методом химического травления, причём нам требуется делать декапсуляцию без потери работоспособности. В ней стоит лазер для гравировки металла. Последовательность, насколько я знаю, обычно такая: сделать рентгеновские фотографии схемы сверху и сбоку, чтобы определить где именно находится кристалл. Частично удалить лазером корпус над или под кристаллом, не доходя до кристалла. Закончить работу уже кислотой.
Я думаю, если лазер будет портить схему (наш уж точно портит), то с канифолью этот метод тоже можно совместить, особенно если учесть отсутствие необходимости сохранять работоспособность — можно позволить себе оставлять более тонкий слой, не беспокоясь о том, что лазер убьёт микросхему. Просто оставляете немного корпуса над кристаллом, потом дотравляете канифолью, тратя меньше времени на этот этап. Вместо рентгеновских снимков прожигаете отверстие до кристалла там, где маркировки не ожидается и определяете толщину так: что‐то вроде «убрать прямоугольник над кристаллом толщиной 0,1 мм, в центре убрать ещё 0,1 мм и проверить, не показался ли кристалл, если кристалл нигде не показался, повторить процедуру (избегая центра)».
Я не сильно искал — мне нужно было сделать генерацию значений регистров для неё на LabVIEW, так что я нашёл одну какую‐то библиотеку с понятным кодом (C++ и под arduino) и переписал.
Только у нее есть проблемы с управлением фазой на низких частотах и она исключительно 3.3V.
Я не использовал её ни для чего, кроме генерации одного тактового сигнала 3,3 В, но datasheet говорит, что она может генерировать сигнал ещё и для номиналов 1,8 и 2,5 В. Её ядро, правда, согласно тому же datasheet запитать придётся минимум от 2,5 В. У неё есть какие‐то проблемы с пониженным питанием?
Если нужно управляемое тактирование для прототипов, то лучше взять какой‐нибудь из Si5351 — они дают от 8 кГц до 160 МГц и при необходимости несколько каналов. Правда, рассчитывать значения регистров для этих схем непросто, но к ним есть как документация (и программа) от производителя, так и минимум одна готовая реализации с открытым кодом.
И это объясняет индексацию по code point как именно? Вы вполне можете поступить как в Rust: индексация по code unit (в данном случае байтам), но попытка создать подстроку только с частью code point приводит к ошибке, требует предварительного преобразования строки в массив байт или требует использования unsafe и считается ошибкой программиста в случае успеха.
И вполне понятно, зачем они это сделали: так одновременно получается индексация за O(1) и при этом вы не платите в четыре раза больше байт за строку/не усложняете себе жизнь поддержкой трёх возможных размеров code unit и не занимаетесь постоянным перегоном в/из UTF-8. Реализации разных операций со строками это обычно либо совсем не усложняет, либо добавляет простые проверки на попадание на границы символов.
Сложность/невозможность работы за чужими компьютерами.
Сильно зависит от пользователя. Я использую programming dvorak с некоторыми дополнениями на компьютере и просто набираю двумя пальцами за чужими компьютерами — обычно мне не нужно что‐то долго набирать в этих случаях.
Очень сложный/неудобный набор на мобильной клавиатуре. Swipe вообще перестаёт адекватно распознавать жесты.
Зачем вообще менять раскладку мобильной клавиатуры? Всё равно десятипальцевый метод использовать не получится.
2 набора шорткатов при переключении языков РУС ↔ ENG. При использовании русского языка шорткаты остаются привязанными к QWERTY.
В своё время меня это достаточно задолбало, чтобы я нашёл способ решить проблему. Решилась она, оказывается, очень просто: я взял свой проект programming dvorak для MS keyboard layout creator и заменил в нём английские буквы на русские и также цифровой ряд. В результате получилась стандартная русская раскладка с дополнительными символами, которые были добавлены в мой проект programming dvorak, при этом всякие <C-?>/<A-?>/… стали использовать расположение английских букв из проекта, который был взят за основу.
Хотя, конечно, это хак и хорошо бы MS KLC позволял бы настроить расположение английских букв для клавиатурных сочетаний более очевидным способом.
Если речь о выделении в куче, то опять-таки разницы никакой, потому что перед данными массива хранится служебная информация (как минимум, размер выделенного блока), и базовый адрес в любом случае после выделения приходится корректировать перед использованием.
Служебная информация может хранится не только там. Или вообще сводится к количеству выделенной памяти, если аллокатор не предполагает возможности освобождения части памяти — аллокаторы бывают разные. Но все аллокаторы выдадут вам указатель на начало выделенного блока, а не указатель на служебные данные.
Я не понимаю, о чём вы.
Дополнительный код. Все отрицательные числа в нём больше, чем положительные, если вы сравниваете число, как если бы оно было беззнаковым. Многие современные компиляторы знают, что i32val >= len || i32val < 0 — это то же самое, что и (i32val as u32) >= len (при условии, что известно, что len >= 0). Вот, к примеру, результат компиляции на Rust:
use core::hint::unreachable_unchecked;
pub fn invalid_index(index: usize, len: usize) -> bool {
index >= len
}
pub unsafe fn invalid_index_i_unsafe(index: isize, len: isize) -> bool {
if len < 0 { unsafe { unreachable_unchecked() } }
index >= len || index < 0
}
pub fn invalid_index_i(index: isize, len: isize) -> bool {
index >= len || index < 0
}
Многомерных массивов может «не быть»: я не говорю о том, что язык их не поддерживает (хотя иногда и такое бывает), а о том, что способ их реализации не подходит для вашей задачи. Из языков, которыми достаточно часто пользуюсь лично я, многомерные массивы вида «один большой кусок памяти плюс набор размеров массива» (один из наиболее производительных вариантов) со всеми размерами определяемыми во время исполнения без библиотек поддерживает только LabVIEW. (Со сторонними библиотеками — все, если не считать различные DSL.)
На самом деле нет: в качестве базового адреса используется адрес на одну ячейку перед первым.
Когда писал комментарий тоже подумал о такой возможной оптимизации. А потом вспомнил, чем в C отличается массив от указателя на один элемент и решил не упоминать о ней в комментарии. В любом случае, если не при индексации, то при создании массива (включая создание срезов уже существующих массивов, а не только декремент после выделения памяти) вы платить за ненулевой начальный индекс будете.
Если мы про Python, Java и т.п. языки, отказавшиеся от поддержки беззнаковых целых, то сравнения с нулём всё равно не избежать.
В общем, для компьютера разницы нет никакой, разница есть только для людей.
У Python есть отдельная семантика для отрицательных индексов. Конкретно для него был бы другой вопрос, если бы он начинал индексы с единицы: почему в нуле дырка (или что‐то ещё более неожиданное).
У Java: нет, сравнение с нулём все ещё не нужно на большинстве машин, если вспомнить, как представляются знаковые целые в памяти.
Для компьютера разница была пока улучшения в процессоре и оптимизирующих компиляторах её не убрали.
Не во всех. К примеру, в lua первый элемент имеет индекс 1. Насколько я понимаю, причина в том, что большинство массивов — это некоторая область памяти, в которой по порядку располагаются элементы. Если первый элемент имеет индекс 0, то он расположен по адресу (начало массива + 0 ∙ размер элемента). Если 1 — то по адресу (начало массива + (1 − 1) ∙ размер элемента). Т.е. на вычисление адреса элемента нужно потратить на одну инструкцию больше.
Есть ряд схожих мелких удобств на низком уровне вроде того, что для записи в конец массива (если память уже выделена) нужно записать элемент по индексу, равному длине массива.
Или что для проверки корректности индекса, начинающегося с нуля, нужно просто сравнить его один раз с длиной массива. Для проверки корректности индекса, начинающегося с единицы, нужно ещё сравнить его с нулём.
Сейчас в большинстве случаев такие мелкие оптимизации не важны. Но не следует забывать о том, что если целевая аудитория языка привыкла к тому, что индексация начинается с нуля, то использование единицы как первого индекса увеличит количество ошибок в программах, одновременно снижая популярность языка. Для языков из комментария выше этот же аргумент работает в сторону индексации с 1.
Я не знаю, что не так с ht_clear, что она бы не скомпилировалась, но вызов memset(NULL, 0, 0) — это как минимум unspecified behaviour, которое в некоторых реализациях UB. Или UB уже по стандарту: на SO есть разбор ситуации.
Для того, чтобы обобщённый C нормально работал с отладчиком можно заменить макросы на параметризованные макросами #include. Пример: typval_encode.c.h, использование.
Плюсы такой техники:
лучше работает с отладчиком и анализаторами кода;
можно иметь намного больше параметров, не сходя с ума;
можно иметь параметры по‐умолчанию.
Минусы:
инстанцирование всегда растягивается на несколько строчек;
с помощью этой техники можно определить функции, переменные, типы, числовые константы (через enum), но нельзя макросы;
параметры для такого файла загрязняют пространство имён макросов, и при повторном инстанцировании в рамках одной единицы трансляции их приходится очищать;
продемонстрированный пример не определяет символов, которые бы использовались в иных единицах трансляции, если это требуется, то работать с .c.h файлами становится ещё менее удобно (но всё ещё не невозможно).
Я учился три курса в МГУ на химфаке, и там были философия, история России, история кафедры, ещё, кажется, экономика. Предпоследняя особенно запомнилась тем, что я пришёл на зачёт заранее (что я обычно делаю, а не с целью совершить следующее действие) и т.к. никого не было мне пришла в голову идея написать шпаргалку мелом на стене (стена была весьма светлая, но не белая). И это как‐то прокатило.
А вот собственно содержание лекций по этим предметам не запомнилось совсем.
Меня удивило, что при включении оптимизаций он не сократил весь main до одного ret — тут ни о каком lorem речи не идёт, main же ничего не возвращает, и не имеет никаких побочных эффектов, кроме выделения памяти. Именно так компилятор делает, если заменить vec! на &. Но почему‐то не если убрать vec! полностью (т.е. заменить тип xs с Vec<&'static str> на [&'static str; 3], или на &[&'static str; 3] в первом случае).
В wikipedia всё есть. И это, оказывается, конверты для серии A. Правда, в английском варианте написано немного не так: Cx это геометрическое среднее между Bx и Ax, в основном используемое для конвертов.
Это принято писать в личку — создатели хабра даже сделали так, что при использовании <C-Enter> сообщение отправится именно туда. А то заголовок поправлен, а ваше теперь бесполезное сообщение осталось.
Статье не хватает раздела про то, что про это говорит закон. Мне что‐то подсказывает, что вы не можете просто взять и поставить систему видеонаблюдения.
Насколько я понимаю, логика здесь другая: не «никому SSO не нужно», а сначала «SSO может иногда ухудшить производительность и точно увеличит кодовую базу» с последующим «…, а ещё пересмотр решения нарушит обратную совместимость: мы пообещали в документации определённые особенности внутреннего представления и теперь часть
unsafe
кода зависит от них».И насчёт выкинем: SSO был до 1.0?
Я замечу, что описанная в статье строка с SSO имеет четыре варианта: Box, &str, &'static str, small string. Почти наверняка в std такое бы не появилось, это оптимизация под конкретную задачу с допущениями, которые неприемлемы для стандартной библиотеки.
Я как‐то заказал у Резонита трафарет в котором на слое паяльной пасты сделал дополнительные отверстия, не соответствующие посадочным площадкам. Прислали трафарет без этих отверстий.
Я им написал, что трафарет неправильный и пусть они бесплатно переделают. Выяснилось, что Резонит не использует по‐умолчанию слой пасты для трафаретов, а генерирует их как‐то из других слоёв, кажется, из слоя маски — и, соответственно, этих отверстий там не должно было быть и, по их мнению, всё в порядке.
После указания на то, что, во‐первых, на сайте про это не слова, но написано про герберы для трафаретов в качестве одного из трёх вариантов заказа (второй — проекты из CAD, третий — трафарет можно заказать для платы, но без деталей относительно того, на основе чего он будет создаваться), во‐вторых, слой пасты в проекте предназначен именно для трафаретов и его использование ожидается от производителя и, в‐третьих, даже если бы я хотел приложить герберы повторно при заказе трафарета по проекту платы это сделать нельзя, они признали что не правы в части невозможности при заказе трафарета для платы повторно приложить герберы, которые я уже приложил при заказе платы, всё же переделали этот трафарет и сказали, что теперь при таких заказах можно прикладывать дополнительные файлы. Но на сайте всё ещё не сказано, что при заказе трафарета для платы слой пасты будет игнорироваться — возможно, правда, теперь не можно прикладывать дополнительный файлы, а обязательно их прикладывать — пока необходимости заказывать ещё трафаретов у меня не возникало.
Достаточно одного потока и связного списка определённого в виде
Попробуйте помодифицировать что‐то, не получив Undefined Behaviour. Для разумных программистов можно даже удалить все
const
— одной инкапсуляции достаточно.Насколько я понимаю, лазер до них просто не достреливает, так что не пережигаются. Деформируются — не знаю, нас беспокоит наличие соединения кристалла с платой, а не форма проволочек. Если вскрытие неудачное, то мы смотрим, из‐за чего, так что я могу сказать, что бывали случаи, когда лаборатория пережигала проволочки, предположительно, кислотой (лазер бы выглядел по‐другому) или случайно застреливала микросхему лазером. Бывали и случаи, когда проволочки касались друг друга и их нужно было просто аккуратно отвести друг от друга — так что иногда от чего‐то деформируются. Не уверен, что от лазера.
Особенности испытаний на радиационную стойкость: изучение эффектов от воздействия ионизирующего излучения, которое сложно или невозможно получить на имеющихся установках, заменяется на изучение эффектов от воздействия того, что у нас есть. Например, мощные всплески гамма‐излучения (отлично пробивающие корпус) можно заменить на выстрелы лазером в видимом или ИК диапазоне (которое не пробьёт корпус) или на пачки электронов (воздействие от которых сильно ослабляется корпусом — и, главное, ослабляется в неизвестной степени).
Лазер для декапсуляции удобен, если не достреливать до кристалла. У нашей компании есть лаборатория, где производится декапсуляции, в том числе методом химического травления, причём нам требуется делать декапсуляцию без потери работоспособности. В ней стоит лазер для гравировки металла. Последовательность, насколько я знаю, обычно такая: сделать рентгеновские фотографии схемы сверху и сбоку, чтобы определить где именно находится кристалл. Частично удалить лазером корпус над или под кристаллом, не доходя до кристалла. Закончить работу уже кислотой.
Я думаю, если лазер будет портить схему (наш уж точно портит), то с канифолью этот метод тоже можно совместить, особенно если учесть отсутствие необходимости сохранять работоспособность — можно позволить себе оставлять более тонкий слой, не беспокоясь о том, что лазер убьёт микросхему. Просто оставляете немного корпуса над кристаллом, потом дотравляете канифолью, тратя меньше времени на этот этап. Вместо рентгеновских снимков прожигаете отверстие до кристалла там, где маркировки не ожидается и определяете толщину так: что‐то вроде «убрать прямоугольник над кристаллом толщиной 0,1 мм, в центре убрать ещё 0,1 мм и проверить, не показался ли кристалл, если кристалл нигде не показался, повторить процедуру (избегая центра)».
Я не сильно искал — мне нужно было сделать генерацию значений регистров для неё на LabVIEW, так что я нашёл одну какую‐то библиотеку с понятным кодом (C++ и под arduino) и переписал.
Я не использовал её ни для чего, кроме генерации одного тактового сигнала 3,3 В, но datasheet говорит, что она может генерировать сигнал ещё и для номиналов 1,8 и 2,5 В. Её ядро, правда, согласно тому же datasheet запитать придётся минимум от 2,5 В. У неё есть какие‐то проблемы с пониженным питанием?
Если нужно управляемое тактирование для прототипов, то лучше взять какой‐нибудь из Si5351 — они дают от 8 кГц до 160 МГц и при необходимости несколько каналов. Правда, рассчитывать значения регистров для этих схем непросто, но к ним есть как документация (и программа) от производителя, так и минимум одна готовая реализации с открытым кодом.
И это объясняет индексацию по code point как именно? Вы вполне можете поступить как в Rust: индексация по code unit (в данном случае байтам), но попытка создать подстроку только с частью code point приводит к ошибке, требует предварительного преобразования строки в массив байт или требует использования
unsafe
и считается ошибкой программиста в случае успеха.И вполне понятно, зачем они это сделали: так одновременно получается индексация за O(1) и при этом вы не платите в четыре раза больше байт за строку/не усложняете себе жизнь поддержкой трёх возможных размеров code unit и не занимаетесь постоянным перегоном в/из UTF-8. Реализации разных операций со строками это обычно либо совсем не усложняет, либо добавляет простые проверки на попадание на границы символов.
Сильно зависит от пользователя. Я использую programming dvorak с некоторыми дополнениями на компьютере и просто набираю двумя пальцами за чужими компьютерами — обычно мне не нужно что‐то долго набирать в этих случаях.
Зачем вообще менять раскладку мобильной клавиатуры? Всё равно десятипальцевый метод использовать не получится.
В своё время меня это достаточно задолбало, чтобы я нашёл способ решить проблему. Решилась она, оказывается, очень просто: я взял свой проект programming dvorak для MS keyboard layout creator и заменил в нём английские буквы на русские и также цифровой ряд. В результате получилась стандартная русская раскладка с дополнительными символами, которые были добавлены в мой проект programming dvorak, при этом всякие
<C-?>
/<A-?>
/… стали использовать расположение английских букв из проекта, который был взят за основу.Хотя, конечно, это хак и хорошо бы MS KLC позволял бы настроить расположение английских букв для клавиатурных сочетаний более очевидным способом.
Служебная информация может хранится не только там. Или вообще сводится к количеству выделенной памяти, если аллокатор не предполагает возможности освобождения части памяти — аллокаторы бывают разные. Но все аллокаторы выдадут вам указатель на начало выделенного блока, а не указатель на служебные данные.
Дополнительный код. Все отрицательные числа в нём больше, чем положительные, если вы сравниваете число, как если бы оно было беззнаковым. Многие современные компиляторы знают, что
i32val >= len || i32val < 0
— это то же самое, что и(i32val as u32) >= len
(при условии, что известно, чтоlen >= 0
). Вот, к примеру, результат компиляции на Rust:Многомерных массивов может «не быть»: я не говорю о том, что язык их не поддерживает (хотя иногда и такое бывает), а о том, что способ их реализации не подходит для вашей задачи. Из языков, которыми достаточно часто пользуюсь лично я, многомерные массивы вида «один большой кусок памяти плюс набор размеров массива» (один из наиболее производительных вариантов) со всеми размерами определяемыми во время исполнения без библиотек поддерживает только LabVIEW. (Со сторонними библиотеками — все, если не считать различные DSL.)
Когда писал комментарий тоже подумал о такой возможной оптимизации. А потом вспомнил, чем в C отличается массив от указателя на один элемент и решил не упоминать о ней в комментарии. В любом случае, если не при индексации, то при создании массива (включая создание срезов уже существующих массивов, а не только декремент после выделения памяти) вы платить за ненулевой начальный индекс будете.
У Python есть отдельная семантика для отрицательных индексов. Конкретно для него был бы другой вопрос, если бы он начинал индексы с единицы: почему в нуле дырка (или что‐то ещё более неожиданное).
У Java: нет, сравнение с нулём все ещё не нужно на большинстве машин, если вспомнить, как представляются знаковые целые в памяти.
Для компьютера разница была пока улучшения в процессоре и оптимизирующих компиляторах её не убрали.
Не во всех. К примеру, в lua первый элемент имеет индекс 1. Насколько я понимаю, причина в том, что большинство массивов — это некоторая область памяти, в которой по порядку располагаются элементы. Если первый элемент имеет индекс 0, то он расположен по адресу (начало массива + 0 ∙ размер элемента). Если 1 — то по адресу (начало массива + (1 − 1) ∙ размер элемента). Т.е. на вычисление адреса элемента нужно потратить на одну инструкцию больше.
Есть ряд схожих мелких удобств на низком уровне вроде того, что для записи в конец массива (если память уже выделена) нужно записать элемент по индексу, равному длине массива.
Или что для проверки корректности индекса, начинающегося с нуля, нужно просто сравнить его один раз с длиной массива. Для проверки корректности индекса, начинающегося с единицы, нужно ещё сравнить его с нулём.
Сейчас в большинстве случаев такие мелкие оптимизации не важны. Но не следует забывать о том, что если целевая аудитория языка привыкла к тому, что индексация начинается с нуля, то использование единицы как первого индекса увеличит количество ошибок в программах, одновременно снижая популярность языка. Для языков из комментария выше этот же аргумент работает в сторону индексации с 1.
Я не знаю, что не так с
ht_clear
, что она бы не скомпилировалась, но вызовmemset(NULL, 0, 0)
— это как минимум unspecified behaviour, которое в некоторых реализациях UB. Или UB уже по стандарту: на SO есть разбор ситуации.Т.е. её нельзя использовать на пустых таблицах.
Для того, чтобы обобщённый C нормально работал с отладчиком можно заменить макросы на параметризованные макросами
#include
. Пример: typval_encode.c.h, использование.Плюсы такой техники:
Минусы:
.c.h
файлами становится ещё менее удобно (но всё ещё не невозможно).Я учился три курса в МГУ на химфаке, и там были философия, история России, история кафедры, ещё, кажется, экономика. Предпоследняя особенно запомнилась тем, что я пришёл на зачёт заранее (что я обычно делаю, а не с целью совершить следующее действие) и т.к. никого не было мне пришла в голову идея написать шпаргалку мелом на стене (стена была весьма светлая, но не белая). И это как‐то прокатило.
А вот собственно содержание лекций по этим предметам не запомнилось совсем.
Меня удивило, что при включении оптимизаций он не сократил весь
main
до одногоret
— тут ни о каком lorem речи не идёт,main
же ничего не возвращает, и не имеет никаких побочных эффектов, кроме выделения памяти. Именно так компилятор делает, если заменитьvec!
на&
. Но почему‐то не если убратьvec!
полностью (т.е. заменить тип xs сVec<&'static str>
на[&'static str; 3]
, или на&[&'static str; 3]
в первом случае).В wikipedia всё есть. И это, оказывается, конверты для серии A. Правда, в английском варианте написано немного не так: Cx это геометрическое среднее между Bx и Ax, в основном используемое для конвертов.
Это принято писать в личку — создатели хабра даже сделали так, что при использовании
<C-Enter>
сообщение отправится именно туда. А то заголовок поправлен, а ваше теперь бесполезное сообщение осталось.Статье не хватает раздела про то, что про это говорит закон. Мне что‐то подсказывает, что вы не можете просто взять и поставить систему видеонаблюдения.