Как стать автором
Обновить
2
0

Пользователь

Отправить сообщение

В моём мироощущении есть "программисты", а есть "люди, работающие программистами", и эти множества пересекаются не всегда. Формально, и те и те могут быть профессионалами (в том смысле, что работают на должности программиста и зарабатывают этим на жизнь). Но у первых программирование это неотъемлемая часть жизни, которая всегда при них, а у вторых - программирование это просто работа на работе (как пример, возьмём маляра Васю; а работе он маляр, стены красит, а как придёт домой - то он уже не маляр, а просто Вася; работу он на работе оставляет). Вот у них так же с программированием. При этом, люди из первой категории могут программистами и не работать (и себя таковыми всерьёз не считать), но при этом быть на голову круче многих из "людей, работающих программистами".

Это я к тому, что на вопрос из заголовка статьи ответить в принципе не получится, потому что понятие "программист" очень уж само по себе неоднозначное.

Прямо очень-очень похоже на планировщик моей мечты, который давно хочу запилить, да всё руки никак не доходят. Фостера я, правда, не читал, но примерно так себе идеальный личный план и представляю. Максимально минималистично, чтобы всё плоским списком, и чтобы быстро, одним кликом, менять статусы. Однако, лично мне совершенно не заходит необходимость в регистрации и привязка к стороннему ресурсу. Делиться своими планами в мои планы не входит. Хочется, чтобы такая штука могла работать локально (хотя бы опционально).

Люди, бывает, очень небезопасные вещи делают, "и ничего". Сорри за оффтопик, но я знаю дома, которые сгорели из-за плохой проводки (алюминий с медью на скрутке). И знаю людей, у которых так же сделано, но они на это говорят - "всегда так было, и ничего". И с печными трубами знаю немало похожих историй (произошедших в т.ч. с родственниками и соседями). Я даже думаю, что в чём-то понимаю психологию этих людей, но сам к такому подходу к жизни не готов.

А касательно смартфона, то именно потому, что смартфон "рядом с подушкой" (условно, всегда под рукой), высока вероятность заметить возгорание вовремя. Да и изолировать его в таком случае не такая большая проблема, как горящий электрокар у дома. Машину, даже если заметим вовремя, потушить не сможем, огонь с ненулевой вероятностью перекинется на дом. А если в целом говорить, то обилие Li-ion аккумуляторов в жилом помещении меня тоже, пусть и не сильно, но тревожит. Давно хочу соорудить какой-нибудь металлический ящик (или что-то в этом духе) для хранения аккумуляторов хотя бы от электроинструмента, но всё руки никак не доходят. И хранить всё это дело, в идеале, лучше в отдельном отапливаемом помещении типа хозблока, а не в жилом доме. Хуже от этого точно не станется.

А по факту можно и на широкоугольник снять, если не стоит задача снять лицо крупным планом.

Да, можно. Но у меня при чтении этого места статьи сложилось впечатление, что там имеется в виду именно крупный план, да и картинки на это указывали. Я бы не стал тут придираться.

начинающий фотограф возьмёт объектив 85мм, фотоаппарат с кропом 1.6 и получит ЭФР 136мм

Начинающий фотограф, наверное, знает про кроп. Не прямо же с чтения этой статьи он фотографом стать решил и техники накупил. Я, будучи когда-то начинающим, про кроп знал, и объектив покупал с его учётом, на 50 мм.

Да, хорошее замечание. Всё так. Но на практике-то расстояние всегда будет меняться (если мы в контексте портретной съёмки находимся, да и не только). Обычно ведь шириком издалека портреты крупным планом не снимают. Фотограф, меняя один объектив на другой, будет брать такое расстояние, чтобы объект примерно одинаковую площадь кадра занял. Так что, с точки зрения фотографа, наверное, действительно можно сказать, что дело в объективе, хотя формально это и не совсем так.

Хорошая статья. Правильные вещи написаны, и показано всё очень наглядно. Спасибо. А вот про фотографирование девчонок, тут всё не так однозначно. Многим при съёмке объективом 85 мм и выше кажется, что на фотках они словно бы лишний вес набрали ) Наверное, это не должно быть удивительным, учитывая, что человек сам себя привык в зеркале на аналог 50 мм видеть. Я даже слышал такое мнение, что моду на похудение в 20 веке запустило в большой степени именно распространение фотографии (уже не знаю, насколько правда, но что-то в этом есть).

Да, действительно, пришлось перечитать аж пару раз. Сформулировано там как-то очень неудачно, от обратного "согласно экспертизе Национальной ассоциации противопожарной защиты (NFPA) и Министерства транспорта США подобная статистика более чем в 10 раз превышает средний показатель возгораний среди автомобилей с ДВС". Так что про тесловскую статистику признаю, был неправ.

Авто с ДВС тоже горит или от физического повреждения, или от неправильной эксплуатации. Но там всё сильно проще в плане контроля. Допустим, если повредился и потёк бензопровод - заметишь заранее, по запаху. Да и в целом, у меня сложилось впечатление, что бензиновые автомобили если и загораются, то обычно в дороге. Успеваешь хотя бы авто покинуть. А электричка скорее загорится ночью, на зарядке, пока ты спишь и не ждёшь плохого. Ладно ещё, если в городе на парковке, но рядом с домом - это страшно. По какой причине загорелась? Да пусть даже и повреждение аккумуляторов, но как его определить-то, на ранней стадии? Ехал по дороге, стукнул днищем о каменюку, и вроде кажется, что ничего не повреждено. Как точно убедиться? А ведь и брак тоже бывает, который не сразу проявится. Один элемент коротнёт, этого достаточно, там их тысячи ячеек в сборке, гореть пойдёт лавинообразно. В общем, не знаю, как это точнее словами выразить, но мне хочется, чтобы моя безопасность по возможности зависела от меня, а не от независящих от меня обстоятельств, сорри за каламбур.

Огонь, в прямом смысле ) Я давно присматриваюсь к электрокарам - живу загородом, в своём домике, и, теоретически, электрокар был бы удобен. Ставил бы его заряжаться на ночь. Но вот статистика по возгораниям удручает. Была информация, что, по подсчётам самой Теслы за период 2012-20, у них вероятность возгорания оказалась выше в 10 раз, чем у авто с ДВС за тот же период. А горящий литий он такой, потушить самому невозможно. Сгорит, если что, и машина, и гараж, и дом, и я. Страшновато, пока к такому не готов )

Налоги очень удобно платятся в личном кабинете налоговой. Одним платежом, без бумажек и реквизитов. Кстати, хороший пример того, как оно может быть нормально сделано.

Что касается QR-кода и телефона, так для этого сомнительного удобства на телефоне ведь приложуху банка иметь обязательно. Многие из моих знакомых (и сам я тоже) считают это не слишком хорошей идеей. И поэтому очень раздражают ситуации, когда mobile first, и какая-нибудь нужная фича только в приложении и есть, а на сайте - нет.

Вроде как словарный запас сам по себе не очень сильно должен влиять, если только он не совсем уж мизерный. Я сразу для интереса раз десять тест прошёл, и результаты были от 92 баллов (в первый раз) до около 83 (худший результат), причём от раза к разу баллы немного снижались. При одинаковом словарном запасе. Т.е. это, грубо говоря, как раз фантазия на рандомные слова со временем понижалась.

Лампы нескольких цветовых температур в одной люстре, к сожалению, визуально смотрятся некрасиво.

Удивительно, до чего разное бывает восприятие. Не представляю, как можно жить с лампами 6000К. Поставил везде 4000К - самое то. Как с 2700К жить, тоже не представляю (разве что в ночниках оно к месту).

Мало потребляющие долгоиграющие девайсы предпочитаю как раз на батарейках.

  • Они квази-вечные. Никакой аккум-пакет в нём не помрёт, искать новый аналогичный не нужно будет. Сколько бы лет не прошло, взял девайс, вставил батарейку, и он снова работает.

  • Заменить батарейку - дело нескольких секунд. Поменял и забыл. А заряжать - это целый процесс, на который нужно время, контроль, свободная зарядка. Вокруг и так уже перебор устройств, требующих постоянной зарядки.

  • Нет литий-ионного аккума - нет литий-ионных проблем. Он не вздуется вдруг, не бахнет в процессе зарядки. Всерьёз отслеживать состояние аккумулятора в таких девайсах часто нереально, это не условный телефон, который в кармане всегда. Тут вообще можно зачастую забыть, что девайс существует и свою работу выполняет (до момента, пока батарейка не сядет).

  • Если девайс мобильный (рекордер, например), то и тут батарейки зачастую удобнее, их можно взять запасных и моментально поменять если что, а коли забыл взять - легко купить на месте, если не совсем уж в диких местах находишься.

Насколько я помню, как раз на NES аппаратного скроллинга нет, он только на SNES появился. На NES есть только слой статичного фона. И параллакс там достигается весьма интересными хаками. Например, если мне не изменяет память, есть метод, когда ловится прерывание от видеоконтроллера по началу развёртки каждой новой строки, и в этот короткий момент перенастраиваются регистры, отвечающие за смещение тайлов фона. Таким образом, двигая фон в нужные моменты по мере вывода кадра, и получается эффект движения разных по высоте полос фона с разной скоростью. Одна из самых красивых реализаций - в моей любимой игре Ninja Ryukenden III. И, кстати, очень обидно, что в ремастере "Ninja Gaiden Trilogy", вышедшем на SNES, эту механику просто поломали, и параллакса в третьей части игры там нет вовсе, хотя, казалось бы...

Меня просто вот эта фраза зацепила

Embedded сфера к сожалению (по крайней мере в России) очень консервативна с плохой точки зрения - древние деды-руководители будут вам доказывать, что RTOS это фигня, надо делать "по старинке" через конечные автоматы, динамически выделять память в куче нельзя, и так далее.

Я считаю, что именно в embedded здоровый консерватизм бывает особенно полезен. Поэтому и привёл пример, как иногда бывает, когда "древних дедов-руководителей" нет, а решения принимают молодые и прогрессивные, несущие модные технологии, идеи и паттерны, но зачастую не понимающие, что и зачем они на самом деле делают. Ну действительно, зачем в условном устройстве с тремя кнопками и двумя светодиодами несколько десятков потоков? Да, как таковая РТОС тут действительно не при чём, но она дала возможности "прострелить себе ноги". В момент принятия решений не оказалось в наличии оппозиции в виде "древних дедов", и парни сделали, как их учили в их книжках/курсах - берём ОС, на каждую задачку по потоку, разруливаем всё семафорами, применяем модных паттернов побольше. И в итоге, очень простую вещь закодировали очень сложно, а потом сами мучались от этой сложности. Не оказалось того, кто сразу, посмотрев на всё это, сказал бы - но ребята, это же простая задача, давайте решим её просто.

И где условная гарантия, что такие люди не будут плодить баги и т.п. при работе в стиле "Мегацикла"

Люди всегда будут плодить баги, как без этого. Но будут плодить заметно меньше, потому что будут лучше представлять, что и в каком порядке в программе происходит. Просто взглянешь на главный цикл, и сразу видишь последовательность действий программы. Искать ошибки, если они возникнут, станет на порядок проще, хотя бы потому, что весь цикл можно по шагам пройти в отладчике, видя всю причинно-следственную цепочку. А если всё навёрнуто на потоках, когда энкодеры читаются в одном потоке, кнопки в другом, светодиоды мигают в третьем и четвёртом, и чёткой последовательности отработки всего этого нет, то попробуй разберись, почему нажатия иногда пропускаются, периоды мигания плавают, и вообще, почему иногда какая-то жесть творится (а, так это ещё несколько неочевидных потоков, которые запускаются из тех что уже запущены, и что-то ещё там своё непонятное делают, а у одного из них ещё и стек переполняется, затирая стек другому, поэтому в определённый момент при определённом порядке отработки потоков, который нарочно фиг повторишь, всё падает, и т.п).

Не так важно, используется RTOS или нет, но важно, как всё организуется. Из практики. Были несколько проектов, без оси. Всё крутилось в главном цикле, всё выполнялось последовательно. Работало. В новом поколении устройств внедрили РТОС, и проекты переписали. Каждый чих - отдельным потоком, и вроде всё красиво, в теории. А а по факту, работает криво-косо. Потоки вразнобой, рандомно задерживают друг друга из-за необходимости синхронизации. Эту самую синхронизацию местами забывают добавить. Чёткую временную диаграмму выдержать сложно. Период какой-то операции неправильный? Пытаются лечить задержками. Задержку у одного потока поменяли - временная диаграмма подвинулась, остальное уехало. Боль, вечные замечания от заказчика, вечная поддержка, доработка костылями. Проект переусложнённый, новички пугаются. Или, что ещё хуже, начинают считать, что это норма. Наконец это надоело уже, и переписали по-классике. Основной поток, в нём цикл, в нём последовательно выполняются функции-задачи. Отдельные потоки - только для действительно независимых, фоновых задач, не связанных напрямую с прикладным функционалом. Кучи потоков теперь нет, временная диаграмма стала чёткой и понятной, синхронизация не нужна, кода стало в два раза меньше, ресурсов процессора потребляется меньше, что и как делает проект стало наконец-то понятно человеку, впервые открывшему код. Ну и замечания, которые до этого годами копились и висели, вгоняя разработчиков в депрессию, вдруг тихо и мирно пропали.

Есть такое. Постоянно сталкиваюсь с тем, что новички, да и не только новички, к сожалению, не понимают разницы компиляции и линковки. Часто бывает, что видя при сборке проекта ошибку "unresolved reference", не могут понять, что это не ошибка компиляции, а просто библиотеку не подключили нужную. Или в имени функции при вызове ошиблись. В итоге, тратят на решение подобных, казалось бы, простых проблем, слишком много времени, зачастую совершая при этом какие-то рандомные действия. От IDE отказываться никто не призывает, наоборот, фичами IDE нужно пользоваться во всю, если они облегчают рутинную работу, но всё-таки нужно же знать, как работает твой инструмент. И было бы здорово, если бы обучение языку начиналось именно с этого - сначала пишем файл исходника и вручную вызываем для его сборки компилятор, затем добавляем ещё файлов и учимся делать простой мейк-файл, а уже затем переходим в IDE. Тогда и действия IDE уже не будут восприниматься как сложная и непонятная магия. Наверное.

Одна из лучших, если не самая лучшая, книга о программировании из всех, что я прочитал. Не только о Си и плюсах, там много очень глобальных вещей, в том числе о подходе к разработке. Никакой воды, всё из практики, всё с объяснением почему и как. Недавно перечитывал, и в очередной раз поражался, насколько вещи, там описанные, актуальны до сих пор. Большинство граблей, на которые наступают коллеги по работе, там расписаны. Так что пытаюсь по мере сил рекламировать в коллективе сию книжку.

2–Не допускать всяческих магических чисел в коде. Это уничтожает читаемость кода. Все константы надо определять в перечисления заглавными буквами.

В целом всё так, но про "все константы" это наверное зря. Я не раз встречал код, авторы которого слишком буквально понимали правило "не допускать чисел в коде". Константами там было задано вообще всё, включая 1 и 0. Это был код а-ля

x = (y >> TEN) & ONE;

Это хуже читается, искать баги становится сложнее, ведь каждую такую константу нужно проверять, а на самом ли деле ONE равно 1, а вдруг автор совсем не то имел в виду.

Ещё один пример - когда константами забиваются значения битов/полей в регистре. Да, это отличное правило, и в общем случае ему очень желательно следовать. Но, опять-таки, на практике встречается код с огромным количеством таких констант в h-файле, скажем, драйвера, а в его си-файле по факту в паре регистров пара битов проверяется, и всё. Когда осознаёшь, что кода могло бы быть в разы меньше, а сам он был бы сильно проще и понятнее, категоричность суждений снижается, и понимаешь, что правила правилами, но в отдельных случаях правильнее, как ни странно, может оказаться от них отступить. И проверить нужный бит явно, в комментарии указав, что именно мы тут делаем и в каком пункте даташита об этом говорится. Работа поддерживающего программиста станет проще в разы.

35--Для синтаксического разбора регистров использовать объединения вкупе с битовыми полями.

Крайне спорно. Когда работаешь в рамках одной платформы - да, удобно. Но у битовых полей большое количество подводных камней.

Когда пишешь что-то (потенциально) мультиплатформенное, или, не дай бог, протокол обмена, то битовые поля - это боль. Сталкивался со случаем, когда в протоколе обмена битовым полем была описана большая структура. И всё ожидаемо поломалось, когда в какой-то момент обмениваться пришлось с новой системой, с другим порядком байтов. В тот раз несколько дней потратили на ручной "переворот" битовых полей. И теперь в том протоколе две структуры - одна для BE, другая для LE, что, конечно же, не очень здорово из-за дублирования кода.

Ещё эпичный случай. Искали трудноуловимый баг в коде. Нашли, что неверно пишется значение в поле структуры. Было там примерно следующее:

state.result = SOME_ERROR_CODE;

При этом, SOME_ERROR_CODE равно двум, поле bar имеет тип int, но в результате записи там почему-то оказывается ноль. Почему? А потому что автор объявил поле так:

int result: 1;

В тот момент ему хватало двух значений для кода результата, но в какой-то момент ему понадобились ещё коды, он их добавил, а битов для поля не добавил. С точки зрения языка, тип поля - int, IDE показывает, что тип поля - int, число 3 в int влезает, компилятор не ругается. Так этот баг в итоге и остался на какое-то время незамеченным.

14–Если переменная это физическая величина, то в суффиксе указывать размерность (timeout_ms). Это увеличивает понятность кода.

Вот это прям очень хорошее правило. Очень-очень. Постоянно по жизни сталкиваюсь с параметрами функций и полями, где передаётся время, а размерность нигде не указана. И комментарий даже есть, но там написано - "время того-то того-то", а про единицы - ни слова. Правильно названные сущности могут уменьшить необходимость в комментариях до минимума, это верно.

15–Все Си-функции должны всегда возвращать код ошибки. Минимум тип bool или числовой код ошибки. Так можно понять, где именно что-то пошло не так. Проще говоря, не должно быть функций, которые возвращают void. 

А вот тут я снова не согласен. Не надо так делать. Если вы пишете ответственный код, то функция, возвращающая код ошибки, обязывает вас его всегда проверять. Если автор библиотеки или драйвера сделал все свои функции возвращающими значение, даже когда это не нужно, то юзер вашей библиотеки будет либо игнорировать коды возврата (возможно, формально нарушая при этом конкретные стандарты кодирования) либо действительно проверять, даже когда это не нужно, что сильно увеличит размер кода и сильно снизит его читаемость из-за кучи ненужных if-ов и return-ов.

Вот вы, например. часто проверяете, что там printf вернул? Многие и не знают даже, что он что-то возвращает. Таких примеров множество.

Представим, что мы написали библиотеку для растровой графики. Там есть функция gfxInit(). Должна ли она возвращать код результата? Скорее всего да, должна, ведь инициализация может пройти неудачно, скажем, из-за нехватки памяти, из-за аппаратных причин (железо нужное на шине не нашли), и т.п. В этом случае, очевидно, ПО должно как-то отреагировать на критический сбой. А должны ли возвращать ошибку функции навроде gfxPutPixel() или gfxDrawLine()? Моё мнение - нет. Не нужно заставлять программиста, использующего ваш интерфейс, засорять свой чистый и понятный код отрисовки графики бесполезными проверками. Код станет нечитаемым адищем, а пользы для дела - ноль. Гораздо полезнее в подобных случаях (когда подсистема/библиотека может "отвалиться" в процессе работы) создать отдельную функцию для получения текущего состояния - и вот её уже можно будет вызывать периодически (один раз за такт в главном цикле работы, например), чтобы узнать, всё ли там в порядке.

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность