У вас, кажется, в обработчике TIMER1_COMPA_vect в случае frame_counter=20 ничего не происходит. Но я, собственно, не за этим.
Для реализации подобных конечных автоматов можно из любопытства попытаться применить идею из https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html . С помощью нее можно писать код в императивном стиле, вместо явной обработки состояний:
#define BEGIN_COROUTINE static int32_t state = -1; switch(state) { case -1:
#define YIELD do { state = __LINE__; return; case __LINE__: ; } while(0);
#define END_COROUTINE }
ISR(TIMER1_COMPA_vect) {
static uint8_t cur_pos_num;
static int8_t i;
BEGIN_COROUTINE
for (;;) {
for (cur_pos_num = 0; cur_pos_num < 6; ++cur_pos_num) {
for (i = 9; i >= 0; --i) {
set_posi_sig();
YIELD;
if (i == numbers[cur_pos_num]) {
set_nego_sig();
} else {
set_zero_sig();
}
YIELD;
}
for (i = 0; i < 20; ++i) {
set_zero_sig();
YIELD;
}
}
}
END_COROUTINE
}
Если под номер состояния выделять большой int расточительно, то можно каждый раз явно передавать в YIELD какое-то уникальное число:
#define YIELD(s) do { state = s; return; case s: ; } while(0);
Практическая целесообразность под большим вопросом, но по-моему довольно интересный трюк.
Вряд ли Fuchsia будет очень бысрой. Там все слишком изолированно и асинхронно. Например, драйвер сетевой карты работает с одном процессе (не в ядре), а релиазация протокола TCP/IP — в другом (тоже не в ядре). Файловая система в третьем, и так далее. Ядро, по сути, лишь предоставляет примитивы межпроцессной коммуникации. Упор на бесопасность и изоляцию, за что скорее всего придется заплатить производительностью.
Но вы серьезно думаете, что разработчик с десятилетним стажем, работавший хотя бы по 1.5 года на каждом месте, успешно в течение десяти лет обманывал всех, что он не умеет писать код?
Не обязательно обманывал. Мог заниматься какой-то ерундой все эти 10 лет. Если у кого-то опыт в 10 лет, это не значит, что у него высокий уровень. Может он достиг какого-то приемлемого для своей прошлой работы уровня, но это не значит, что этот уровень устроит мою команду. Причем крутость работодателя тоже ни о чем не говорит. Даже в хваленой корпорации добра таких личностей более чем хватает. И даже на уровнях выше сеньора я таких людей там видел.
Для чего нужны все эти алгоритмы обхода деревьев на собеседовании? Он что, каждый день будет писать эти деревья или алгоритмы сортировки в прод?
Цель алгоритмического собеседования — вовсе не проверить, насколько вы хорошо знаете алгоритмы обхода деревьев. Алгоритм выступает лишь в роли контекста. Цель собеседования — получить представление об общем уровне вашей «соображалки», оценить коммуникативные навыки, стиль мышления, и заодно проверить навыки перевода идей из головы в код.
Но конечно сложно поспорить, что часто они действительно вырождаются в проверку, умеете ли вы писать обходы деревьев. Тут уж зависит все от собеседователя. Поэтому я понимаю общее недовольство алгоритмическими собеседованиями, но я в корне не согласен с критикой типа «я ж не буду писать сортировку каждый день, зачем вы меня ее спрашиваете». Я поддерживаю критику вроде «зачем вы меня заставляете решать задачки чтобы тупо посмотреть, решил я ее или нет, и докапываетесь до неважных деталей, вместо того, чтобы оценивать мои общие мыслительные способности в процессе собеседования».
В статье слишком много ложной информации про жизнь в Калифорнии, поэтому не могу пройти мимо.
В Сан-Франциско — 9 404 долларов США в месяц
Сложно в это поверить, по личному опыту зарплаты сильно выше, чем 112 тысяч в год. Особенно в крупных компаниях. Если это данные с glassdoor, то скорее всего они не включают акции (RSU), и вообще они сильно там занижены. В зависимости от компании, опыта специалиста и умения себя продать, годовой доход software engineer колеблется с среднем в интервале от 120 до 400 тысяч в год. Медиана, я думаю, где-то в районе 150-200 тысяч. Чтобы увидеть, сколько получают в крупных компаниях, рекомендую использовать levels.fyi вместо glassdoor.
(вычитаем из зарплаты 28% федерального и 28% подоходного налога штата).
Это ложная информация. Налог в штата в Калифорнии в среднем около 9% (он прогрессивный). Федеральный налог тоже прогрессивный. Просто наберите в Гугле «california income tax calculator» и введите годовой доход в долларах.
Например, если ввести 112858 долларов в год (=9404 в месяц, как в статье), то все налоги в сумме получатся около 30,5%. Итого чистыми в месяц у вас будет около 6500 долларов в месяц, что по курсу 63 рубля за доллар составляет 409500 рублей в месяц.
Этот расчет подтвержается личным опытом. Когда я пять лет назад работал джуниором в стартапе, то моя зарплата как раз была в точности 112 тысяч в год. Чистыми примерно столько и получалось в месяц.
делим зарплату на 2,7 — во столько раз стоимость жизни тут выше, чем в Москве
Бесспорно, цены на жилье и услуги в окрестностях СФ действительно очень высокие. Однако, цены на товары (автомобили, электроника, ...) могут быть и ниже московских. Поэтому простым делением на коэффициент сложно что-то посчитать.
StampedLock будет эффективнее ReentrantReadWriteLock за счёт того, что в случае успеха оптимистичной блокировки (fast path) вообще не происходит обновления разделяемых переменных, в то время как ReentrantReadWriteLock даже в лучшем случае выполняет как минимум один CAS.
По-моему, тут нельзя использовать StampedLock в оптимистическом режиме. В него можно оборачивать только чтение полей, но не произвольный код.
long stamp = sl.tryOptimisticRead();
int ret = buf.get(offset);
if (!sl.validate(stamp)) {
// lock and re-read (slow path)
}
return ret;
Если писатель пришел после того, как мы вызвали tryOptimisticRead(), но до того, как мы вызвали validate(), то buf.get() и buf.put() могут быть вызваны одновременно, что может быть проблемой, в зависимости от внутренней реализации класса ByteBuffer. Если бы вместо buf.get() и buf.put() были бы явное чтение/запись из массива, не было бы проблем.
Поэтому лучше не выпендриваться использованием низкоуровневых примитивов синхронизации и использовать обычный мьютекс.
Можно добавить в список: лексический анализатор Питона выдает два специальных токена INDENT и DEDENT, которые обозначают увеличение и уменьшение уровня отступа, соответсвенно. Было бы логично их тоже считать за токены.
тогда требования к выравниванию структуры в целом (а они обычно у компилятора есть даже для упакованных структур)
Я всегда считал, что у упакованных структур нет требований к выравниванию. В этом, в общем-то, и весь их смысл. Если есть сомнения/паранойя, можно вставить в код
Но формально нарушение выравнивания является undefined behavior, и существуют архитектуры, где это фатально.
Здесь нет никакого нарушения выравнивания. У упакованных структур выравнивание всегда равно единице, поэтому нарушить его невозможно. В этом весь смысл упакованных структур.
Работает это не только на x86 и ARM. Если платформа не поддерживает невыровненные обращения к памяти, то для чтения/записи поля из упакованной стрктуры компилятор вставит соответствующие инструкции.
Вот весь пост — прямо классическая иллюстрация причины, скрывающейся за правилом: никогда не парсить бинарные данные с помощью приведения к типу указателя на __attribute__((packed)) структурки.
Приведенное вами «правило» необоснованно по изложенной выше причине. Упакованные структуры — весьма практичный способ разбора бинарных данных.
YCM это clang зависимый (с точки зрения C/C++) плагин
Да, я знаю. В моем проекте кто-то уже проделал основную работу по интеграции YCM и я пытался использовать этот готовый конфиг. Но что-то он не справлялся.
Нет, вот с «все кнопки как в Vim» это очень не так. Далеко не все, и не сказать чтобы «как в Vim». Скорее: «некоторые кнопки примерно как Vim».
Согласен, что не «прям все». Но я каких-то супер-продвинутых функций vim не использую, поэтому особой разницы не замечаю. Просто привык работать с командами перемещения/редактирования/поиска и модальному интерфейсу, которые работают без проблем. Если ваши запросы сильно выше, то наверное у вас будет другой опыт.
В Калифорнийской мотошколе нас учили, что совсем параллельно небезопасно ехать — лучше, чтобы оставалось пространство сбоку для маневра (для объезда препятствия, например). Рекомендуют «diamond formation» при групповой езде. Один, например, едет спереди и левее, а другой сзади и правее, но дистанцию между мотоциклами при этом можно держать меньше, чем просто при езде за машиной.
Калифорнийский мотоциклист с двухмесячным стажем на связи. Спасибо за статью, ваше красочное описание асфальтовой болезни мотивировало меня наконец купить мотоштаны.
Мои пять копеек: если стоите первым на светофоре и загорелся зеленый, посмотрите по сторонам, прежде чем ехать.
Либо я пропустил, либо тема навигации в большом проекте не раскрыта. Сколько ни пробовал разных плагинов для переключения между файлами, везде есть какие-то проблемы или тормоза. Теги тоже не очень хорошо работают. На прошлой работе пытался настроить YouCompleteMe, но он либо зависал, либо не находил нужное (огромный проект на C++).
В студенческие годы у меня тоже был вим с кучей плагинов и настроенных конфигов, и он вполне справлялся со студенческими проектами. Но сейчас я обычно использую IntelliJ/PyCharm/CLion с Vim-плагином. Все кнопки как в Vim, только еще есть полноценный IDE и никаких плясок с бубнами. Выбрал шрифт, цвета по вкусу, сочетания клавиш и поехали.
CLion, правда, на прошлой работе я в итоге выкинул. Он жутко тормозил даже на моей 54-ядерной рабочей станции со 128 ГБ памяти. В итоге я установил IntelliJ Community Edition и использовал его как текстовый редактор без функций IDE. Все равно удобдней, чем Vim с плагинами.
Все-таки это не совсем свертка в традиционном понимании этого слова. Свертка — это линейная операция: значение клекти вычисляется как взвешенная сумма ее окрестности. Иными словами, влияние каждого соседа суммируется независимо от других соседей.
А здесь в качестве «ядра» выступает произвольная булева функция от 9 переменных. Линейных булевых функций от девяти переменных существуется всего лишь 2^10, в то время как количество всех функций от 9 переменных — 2^512.
Не очень понятное решение. Это довольно редкий случай, когда нужны _сразу_ несколько переменных одного типа. Да и даже в том случае, может быть более читаемо объяивить каждую переменную на своей строке. Да и если захочется сделать указание типа опциональным, то будет странно.
У вас, кажется, в обработчике
TIMER1_COMPA_vect
в случаеframe_counter=20
ничего не происходит. Но я, собственно, не за этим.Для реализации подобных конечных автоматов можно из любопытства попытаться применить идею из https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html . С помощью нее можно писать код в императивном стиле, вместо явной обработки состояний:
Если под номер состояния выделять большой int расточительно, то можно каждый раз явно передавать в YIELD какое-то уникальное число:
Практическая целесообразность под большим вопросом, но по-моему довольно интересный трюк.
Цель алгоритмического собеседования — вовсе не проверить, насколько вы хорошо знаете алгоритмы обхода деревьев. Алгоритм выступает лишь в роли контекста. Цель собеседования — получить представление об общем уровне вашей «соображалки», оценить коммуникативные навыки, стиль мышления, и заодно проверить навыки перевода идей из головы в код.
Но конечно сложно поспорить, что часто они действительно вырождаются в проверку, умеете ли вы писать обходы деревьев. Тут уж зависит все от собеседователя. Поэтому я понимаю общее недовольство алгоритмическими собеседованиями, но я в корне не согласен с критикой типа «я ж не буду писать сортировку каждый день, зачем вы меня ее спрашиваете». Я поддерживаю критику вроде «зачем вы меня заставляете решать задачки чтобы тупо посмотреть, решил я ее или нет, и докапываетесь до неважных деталей, вместо того, чтобы оценивать мои общие мыслительные способности в процессе собеседования».
Либо вы получаете меньше 100 тысяч в год, либо я хочу знать ваши секретные методы ухода от налогов :)
Сложно в это поверить, по личному опыту зарплаты сильно выше, чем 112 тысяч в год. Особенно в крупных компаниях. Если это данные с glassdoor, то скорее всего они не включают акции (RSU), и вообще они сильно там занижены. В зависимости от компании, опыта специалиста и умения себя продать, годовой доход software engineer колеблется с среднем в интервале от 120 до 400 тысяч в год. Медиана, я думаю, где-то в районе 150-200 тысяч. Чтобы увидеть, сколько получают в крупных компаниях, рекомендую использовать levels.fyi вместо glassdoor.
Это ложная информация. Налог в штата в Калифорнии в среднем около 9% (он прогрессивный). Федеральный налог тоже прогрессивный. Просто наберите в Гугле «california income tax calculator» и введите годовой доход в долларах.
Например, если ввести 112858 долларов в год (=9404 в месяц, как в статье), то все налоги в сумме получатся около 30,5%. Итого чистыми в месяц у вас будет около 6500 долларов в месяц, что по курсу 63 рубля за доллар составляет 409500 рублей в месяц.
Этот расчет подтвержается личным опытом. Когда я пять лет назад работал джуниором в стартапе, то моя зарплата как раз была в точности 112 тысяч в год. Чистыми примерно столько и получалось в месяц.
Бесспорно, цены на жилье и услуги в окрестностях СФ действительно очень высокие. Однако, цены на товары (автомобили, электроника, ...) могут быть и ниже московских. Поэтому простым делением на коэффициент сложно что-то посчитать.
По-моему, тут нельзя использовать StampedLock в оптимистическом режиме. В него можно оборачивать только чтение полей, но не произвольный код.
Если писатель пришел после того, как мы вызвали tryOptimisticRead(), но до того, как мы вызвали validate(), то buf.get() и buf.put() могут быть вызваны одновременно, что может быть проблемой, в зависимости от внутренней реализации класса ByteBuffer. Если бы вместо buf.get() и buf.put() были бы явное чтение/запись из массива, не было бы проблем.
Поэтому лучше не выпендриваться использованием низкоуровневых примитивов синхронизации и использовать обычный мьютекс.
www.youtube.com/watch?v=Q-i1XZc8ZwA
fuchsia.googlesource.com/fuchsia/+/refs/heads/master/src/connectivity/wlan/lib/common/rust/src/big_endian.rs
В основном протоколе все поля в little endian, но иногда попадаются big endian из верхних слоев.
Я всегда считал, что у упакованных структур нет требований к выравниванию. В этом, в общем-то, и весь их смысл. Если есть сомнения/паранойя, можно вставить в код
перед тем, как делать reinterpret_cast.
Работает это не только на x86 и ARM. Если платформа не поддерживает невыровненные обращения к памяти, то для чтения/записи поля из упакованной стрктуры компилятор вставит соответствующие инструкции.
Приведенное вами «правило» необоснованно по изложенной выше причине. Упакованные структуры — весьма практичный способ разбора бинарных данных.
А мне кстати собеседование понравилось, но я люблю алгоритмы. Люди были крайне вежливы.
Самописная херня была очень прикольная кстати (OS Fuchsia). Опыт пускай и не переносится напрямую, но все равно я многому интересному успел научиться.
В моем случае разница получилась всего лишь в 30%, но да, 50-60% вполне может быть, если гугловский офер был изначально низкий.
Пока мое наименее любимое место работы в Долине, но помойкой все-таки не стал бы называть.
Да, я знаю. В моем проекте кто-то уже проделал основную работу по интеграции YCM и я пытался использовать этот готовый конфиг. Но что-то он не справлялся.
Согласен, что не «прям все». Но я каких-то супер-продвинутых функций vim не использую, поэтому особой разницы не замечаю. Просто привык работать с командами перемещения/редактирования/поиска и модальному интерфейсу, которые работают без проблем. Если ваши запросы сильно выше, то наверное у вас будет другой опыт.
Мои пять копеек: если стоите первым на светофоре и загорелся зеленый, посмотрите по сторонам, прежде чем ехать.
В студенческие годы у меня тоже был вим с кучей плагинов и настроенных конфигов, и он вполне справлялся со студенческими проектами. Но сейчас я обычно использую IntelliJ/PyCharm/CLion с Vim-плагином. Все кнопки как в Vim, только еще есть полноценный IDE и никаких плясок с бубнами. Выбрал шрифт, цвета по вкусу, сочетания клавиш и поехали.
CLion, правда, на прошлой работе я в итоге выкинул. Он жутко тормозил даже на моей 54-ядерной рабочей станции со 128 ГБ памяти. В итоге я установил IntelliJ Community Edition и использовал его как текстовый редактор без функций IDE. Все равно удобдней, чем Vim с плагинами.
А здесь в качестве «ядра» выступает произвольная булева функция от 9 переменных. Линейных булевых функций от девяти переменных существуется всего лишь 2^10, в то время как количество всех функций от 9 переменных — 2^512.