• За что я не люблю Go
    0
    Вывод: горутина может повесить всю программу.

    Не совсем так. Если N горутин, где N равно GOMAXPROCS (обычно — количеству ядер CPU), будут заняты долгими/бесконечными вычислениями без какой-либо коммуникации с другими горутинами, I/O, вызовов системных функций, etc. — то кроме них другие горутины выполняться не будут пока эти вычисления не закончатся. Так работает кооперативная многозадачность.

  • Еще один закон Яровой: депутат предложила разрешить полиции отслеживать местоположение детей при помощи геолокации
    +2

    Если родители хотят отслеживать местоположение телефона ребёнка — у них и так есть такая возможность, без необходимости привлекать полицию, используя штатные сервисы сотовых операторов и/или мобильные приложения и/или доступ к аккаунту google (в случае андроида) ребёнка.


    А законы, расширяющие полномочия органов в плане слежки и/или цензуры без суда и следствия "ради детей", как все уже могли увидеть на примерах предыдущих законов, используются почти исключительно для блокирования любых угроз текущей власти, и только в самую последнюю очередь для чего-то полезного населению, включая детей.

  • Будущее борьбы с преступностью заключается в изучении родословных деревьев
    0

    Скорее всего баг, отпишитесь на https://habr.com/feedback/

  • Будущее борьбы с преступностью заключается в изучении родословных деревьев
    +3

    Это не так уж принципиально отличается от ситуации, когда люди заливают свои фоточки в соц.сети и отмечают на них всех знакомых — они при этом точно так же сдают местоположение этих знакомых в конкретный момент времени.

  • Уязвимости Киевстара: 1) разбор предыдущего поста про пароли + 2) инфо о покупках, проходящих через сервисы Киевстара
    +22

    Бизнес понимает только один язык: прибыли и убытки. Поэтому, если нам хочется повышать безопасность используемых устройств, приложений и сервисов, необходимо разговаривать с бизнесом на понятном ему языке: если на официальном сайте не указан способ связи по вопросам безопасности (пусть даже это обычный support@) либо в ответ на сообщение по этому каналу связи не последовало адекватной реакции (подтверждения получения в течении нескольких рабочих дней и исправления проблемы в течении месяца) — необходимо в обязательном порядке делать full disclosure, вне зависимости от последствий для бизнеса (а для защиты от последствий для исследователя публиковать анонимно).

  • ADB vs Spy Cam & Mic
    +2

    Давно написали, для старых андроидов это XPrivacy, для новых XPrivacyLua, но для его работы нужен рут и Xposed Framework.

  • За что я не люблю Go
    0

    Вызов time.Now() это сискол. Хотя конкретно его заоптимизировали так, что, по-моему, сейчас он работает без реального системного вызова. В любом случае я не настолько хорошо знаю внутренности Go, чтобы быть уверенным в том, что его вызов не передаст управление шедулеру. Скорее всего это можно проверить эмпирически, но вряд ли это получится сделать в песочнице play.golang.org.

  • За что я не люблю Go
    0

    Как именно "посылать сообщение"? Каналы, мьютексы — всё это передаст управление шедулеру.

  • За что я не люблю Go
    0

    Ну, во-первых у меня результаты немного другие:


    // GOMAXPROCS=1
    2 calc init
    2 calc done 887459712
    0 calc init
    0 calc done 887459712
    1 calc init
    1 calc done 887459712
    // GOMAXPROCS=2
    2 calc init
    0 calc init
    2 calc done 887459712
    1 calc init
    0 calc done 887459712
    1 calc done 887459712

    А во-вторых тест не очень корректный, потому что fmt.Println это I/O, что даёт возможность шедулеру передать выполнение другой горутине, так что в теории есть возможность увидеть 3 init подряд даже при GOMAXPROCS=1, но это вовсе не означает, что горутины выполнялись параллельно. Надо заменить fmt.Println на что-то без I/O, но вряд ли это получится сделать корректно — по сути, мы пытаемся получить последовательность выполнения операций в разных горутинах без использования каких-либо примитивов синхронизации горутин (потому что они все передадут управление шедулеру горутин). Вот пример https://play.golang.org/p/7jelh_pOBav но он может глючить по вышеупомянутой причине.

  • В 2018 мы наконец стали воспринимать всерьез время, проведенное за смартфоном
    +3

    1/15. Соц.сетями кроме хабра не пользуюсь вообще, мессенджеры на телефоне запускаю только когда часов 6+ собираюсь находится не возле компа, email читаю на компе, какие-то звуки телефон издаёт исключительно при входящих звонках/смс, будильнике/таймере, плюс раз в сутки напоминалка одной-двух игр. Мне действительно не комфортно забывать телефон дома, но это связано с желанием иметь возможность позвонить когда мне это потребуется плюс иметь доступ к Keepass, а не с потребностью проверять входящие сигналы.


    На мой взгляд корень проблемы вовсе не в телефоне, а в соц.сетях.


    Что касается мессенджеров, то во время работы телефон нужно переворачивать/отключать звук, и проверять входящие раз в 2-3 часа (на компе ровно то же самое, чтобы сосредоточиться вполне нормально выключать звук в мессенджере на несколько часов) — разумеется, если работаешь не менеджером, им как раз надо постоянно быть на связи, по крайней мере в рабочее время.

  • За что я не люблю Go
    0

    Это не так. Планировщик управление у горутины сам не отбирает, он это может сделать только тогда, когда горутина вызывает определённые операции (чтение/запись каналов, I/O, time.Sleep, etc.). Если горутина занята числодробилкой и ничего такого не вызывает, то она отлично "поставит колом" свой поток, и если таких горутин наберётся GOMAXPROCS штук то они заблокируют выполнение всех других горутин. Пример: https://play.golang.org/p/1gaiQVBpood (раскомментируйте строку с runtime.GOMAXPROCS чтобы увидеть разницу).

  • Бизнес, я люблю тебя
    +2

    Отвечу за автора, если что не так — она меня поправит. Суть не в веселье а-ля "пир во время чумы". Суть в том, что позитивное отношение просто более конструктивно и эффективно.


    Все описанные гадости будут происходить вне зависимости от того, нравится Вам это или нет — и Вы не можете это контролировать, "выключить" такое поведение окружающих Вас людей и сделать их "хорошими". Даже если долго подбирать себе компанию/коллектив можно уменьшить количество таких гадостей в своём окружении, но свести их к нулю вряд ли получится. А вот что Вы можете контролировать — так это своё собственное отношение к происходящему.


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

  • За что я не люблю Go
    0

    Я не знаю Kotlin, так что не могу сравнивать, но я не вижу что именно сложно контролировать в Go. Единственное, чего в Go нет — это внешнего контроля времени жизни горутины, т.е. одна горутина не может убить другую либо гарантированно получить какой-то сигнал при завершении другой. Всё это не является проблемой если корректно проектировать горутины (причём речь действительно о проектировании, а не о корректности/сложности реализации — с реализацией обычно проблем не возникает).


    Когда мы запускаем горутину необходимо чётко понимать её жизненный цикл и как именно мы будем гарантировать отсутствие подвисания и/или утечки горутины. Обычно с этим неплохо помогает использование context — необходимость явно передавать его почти всем функциям первым параметром несколько раздражает чисто в плане синтаксиса/стиля, но по факту штука очень полезная и удобная.


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


    • закрытие канала как способ сделать broadcast неопределённому количеству получателей,
    • использование select для неблокирующей операции с каналом,
    • использование nil-каналов в select для временного отключения отдельных case-ов,
    • ну и собственно использование самого select в отдельной горутине в качестве event loop или менеджера группы других горутин.
  • Почему валидации email регуляркой недостаточно. Проверка MX-записей с примерами на PHP и Ruby
    0

    Google обычно банит не сам, а используя информацию сторонних сервисов вроде spamhaus.org. При корректной настройке своего SMTP (включая reverse DNS, SPF, etc.) и рассылке легальных писем а не реального спама обычно это проблема решаемая.

  • За что я не люблю Go
    0

    На самом деле всё не настолько идеально, и я не уверен, что приставка go вместо co несёт глубокий смысл. Многозадачность бывает кооперативная и вытесняющая. В языках с yield/await она кооперативная, в Go — тоже. Тем не менее, на Go этот код писать значительно проще, потому что программисту вручную нет необходимости об этом задумываться в 99.99% случаев (а в оставшихся случаях он может вызвать runtime.Gosched).


    Помимо этого далеко не все языки реализуют кооперативные M:N, во многих там 1:N, а это значит, что любая функция, которая просто слишком долго что-то вычисляет в цикле начинает фатально мешать работе других. В результате, несмотря на формальное сходство, async/await действительно заметно проигрывает горутинам.


    Дополнительным фактором в Go являются каналы, аналог которых далеко не всегда прилагается к async/await в других языках (частично потому, что в 1:N это не так критично), и которые сильно упрощают безопасную коммуникацию между горутинами.

  • За что я не люблю Go
    0
    То есть, свои библиотеки вы пишете сразу заведомо безопасными с полностью future-proof API?

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

  • За что я не люблю Go
    0

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


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

    Если у Вас в проектах практикуется ревью, то кто-то автоматически лопатит мегабайты изменений чтобы что-то найти… но только в той части кода ваших проектов, который написали вы сами… но ведь проект так же содержит много кода, который написали не вы, нередко этого стороннего кода в проекте даже больше, чем вашего собственного, причём код этот вы получили бесплатно, на условиях as is и без каких-либо гарантий. Единственная причина, по которой такое отношение (ревью только собственного кода) имеет смысл — компании наплевать на безопасность (или, скажем мягче, у компании недостаточно ресурсов на безопасность), и по факту её волнуют только критичные баги, которые дешевле и быстрее обнаружить на ревью собственного кода.


    Библиотека обычно ничего такого страшного не делает

    Речь о том, что в библиотеках код более общего назначения, который содержит избыточный для вашего проекта функционал. Это значит, что для реализации этого избыточного функционала библиотека выделяет больше памяти для хранения данных нужных этому функционалу, выполняет больше логики в коде для поддержки этого функционала, и, в результате, жрёт больше ресурсов и работает медленнее. Насколько — зависит от конкретной библиотеки. Для многих библиотек это может быть не критично, но полно примеров проектов, в которых накопилось очень много такого "избыточного" кода, и которые дико тормозят и/или требуют дикое количество ресурсов, хотя сами не делают ничего достаточно сложного, чтобы оправдать это. На практике эта цена становится заметна либо при подключении ненужных тяжёлых библиотек вроде упомянутого Вами ORM, либо при бездумном подключении библиотек на каждый чих (что и является темой текущего обсуждения).


    Если же использовал, то фичи не бесполезные, и сэкономили вам время.

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

  • За что я не люблю Go
    0

    Цена библиотек вовсе не в килобайтах и времени компиляции. Если разрабатывается прототип — цена библиотек нулевая. Но в нормальных проектах каждая зависимость создаёт дополнительные риски и увеличивает нагрузку на поддержку проекта.


    Библиотеки надо отслеживать (как минимум на предмет выхода новых версий, исправляющих проблемы с безопасностью), их надо обновлять (что нередко требует внесения изменений в свой код), в проектах где важна безопасность код библиотек нужно хотя бы проглядывать перед добавлением плюс смотреть изменения при обновлениях, если возникают проблемы (а они всегда возникают, даже с отлаженными за 10 лет библиотеками) то их решение обходится намного дороже чем исправление бага или добавление фичи в своём коде (нужно потратить время на коммуникацию с автором библиотеки, если он оперативно фикс не выпустит, то нужно самим вникнуть в код библиотеки — которая довольно большая и содержит много ненужного текущему проекту — и пофиксить самостоятельно, после чего либо ждать пока автор примет PR, либо делать свой форк, в случае форка появляется дополнительная нагрузка на подтягивание в него обновлений из основного репо, etc.).


    Помимо этого использование избыточно функциональных библиотек нередко приводит к трате лишних ресурсов на выполнение ненужного этому проекту кода, что отрицательно сказывается на скорости его работы и требованиям к ресурсам (RAM/CPU). Ещё одна проблема связана с тем, что быстро подключив навороченную библиотеку мы нередко добавляем в проект "бесплатные" фичи — то, что проекту не нужно, но что мы получили вместе с библиотекой (возвращаясь к примеру с конфиг-файлом такой фичей является обновление конфигурации при изменении файла на лету), что тоже удорожает поддержку (не нужные, но реализованные фичи приходится поддерживать) и в целом ведёт проект в сторону bloatware.


    Цена библиотек достаточно высока. Она однозначно является приемлемой если библиотека решает достаточно сложную задачу, но для задач, которые можно самостоятельно решить в 20 строк — использование сторонних библиотек это просто вредительство.

  • За что я не люблю Go
    0
    Свои строки, свои конфиги, своё всё… Где-то такой паттерн я уже встречал…

    Мимо, никто в Go не делает свои строки, очень много есть в стандартной библиотеке, свой парсер yaml/ini тоже никто в своём уме писать не станет. Но и ради leftpad тоже никто стороннюю библиотеку подключать не будет.


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

    Это не так. Опенсорсные библиотеки (а мы ведь о них говорим, да?) в основной массе и есть типичный home made код. Причём, как правило, более универсальный, функциональный и сложный, чем нужно для текущего проекта, что зачастую с лихвой перекрывает "протестированность и проверенность временем" и приводит к тому, что работает это менее надёжно, чем своя минималистичная реализация.


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


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


    В качестве конкретного примера, в моём текущем проекте (50k строк) подключены 22 библиотеки, из них ровно половина это либо наши собственные опенсорсные, либо дополнения стандартной библиотеки Go (из golang.org/x/…). Из оставшихся 11 часть это (относительно) официальные библиотеки (драйвер DB, SDK сервисов вроде AWS, Stripe, etc.), без них остаётся 6, из которых только одна достаточно тривиальная, без которой можно было бы обойтись. При этом в этих 50к строк есть ровно один настоящий велосипед на 1600 строк (по ряду причин пришлось сделать свою очередь сообщений, и перед тем как решиться писать велосипед я честно неделю старался заюзать существующий NATS Streaming Server, и до сих пор не рад, что пришлось таки написать этот велосипед).


    Условно говоря, если проблему можно решить в 20 строк кода, то никто ради этого библиотеку подключать даже не подумает — библиотека тупо обойдётся дороже. А если Вы не в состоянии написать эти 20 строк без багов, и этим оправдываете необходимость подключения библиотеки…

  • Почему валидации email регуляркой недостаточно. Проверка MX-записей с примерами на PHP и Ruby
    +1

    Это незначительное улучшение UX (которое легко может стать ухудшением, если ожидание результатов MX-запроса будет блокировать отправку формы юзером). К реальной валидации email данная фича имеет очень слабое отношение.

  • За что я не люблю Go
    0
    Если есть библиотека для Х, не надо писать Х руками. Даже если это падлефт.

    А вот это действительно антипаттерн в Go.


    Есть языки, в которых этот X написать самостоятельно — только нарываться на лишние проблемы. Потому что очень легко сделать не очевидные ошибки, потом придётся их долго фиксить, и, через годик фиксов, мы получим небольшого монстрика, с местами не очевидным кодом, но зато корректно работающего… и, учитывая, что ровно такого же монстрика мы могли получить ещё год назад просто взяв стороннюю библиотеку — выбор очевиден.


    Но в Go — это не так. В большинстве случаев когда нужно решение мелкой проблемы, пусть даже типовой, быстрее реализовать его самостоятельно, в частном виде необходимом текущему приложению. Код при этом получится сразу примерно такой же, как в сторонней библиотеке, он будет вполне простой, очевидный и с минимумом ошибок (зачастую в сторонней библиотеке ошибок будет больше, потому что она — библиотека общего назначения и делает больше, чем наше частное решение). В этой ситуации выбор тоже вполне очевиден, и он отличается от предыдущего случая: простое пишем сами, сложное подключаем библиотеками.

  • Почему валидации email регуляркой недостаточно. Проверка MX-записей с примерами на PHP и Ruby
    0

    А смысл? Если юзер указал некорректный домен, то отправленное письмо не придёт никуда — оно вообще не отправится дальше вашего собственного SMTP, который вас банить не должен. Подозреваю, что проблему вызвала попытка отправлять почту через SMTP gmail или подобного сервиса… ну, тут скорее ССЗБ и проблема решается использованием собственного SMTP, а не валидацией MX.

  • Альтернативы LastPass. Сравнительная оценка шести парольных менеджеров
    0

    А чего просто не положить файл с базой Keepass в каталог, который синхронизируется с google drive любой доступной утилитой, ничего не знающей про Keepass? У меня так лежит файл в каталоге дропбокса.

  • Альтернативы LastPass. Сравнительная оценка шести парольных менеджеров
    0

    А какие плагины нужны? BTW, вообще сама идея плагинов, особенно не от автора оригинального приложения, для менеджера паролей — меня немного напрягает.

  • Мой однострочный клиент Dropbox под Linux
    0

    Когда я последний раз (несколько месяцев назад) проверял, то в www-client/firefox — да, звук есть, а вот в www-client/firefox-bin — увы, без apulse его нет. К сожалению, там был довольно слабый комп, 2GB RAM, и собрать firefox из исходников там уже нереально.

  • За что я не люблю Go
    +1

    Думаю, здесь очень тонкая грань, между главной фичей того же раста, и аналогичными фичами Go — и то и другое предназначено для того, чтобы защитить программиста от его же ошибок, и то и то можно обойти через unsafe (если уверен, что умнее компилятора). Где провести эту грань — вопрос сугубо индивидуальный, множество программистов считает, что даже строгая типизация уже "за гранью" и что не надо считать их идиотами и мешать им складывать строки с числами.

  • За что я не люблю Go
    0

    Если Вам нужен очень умный самообновляющийся конфиг, то всё делается ровно так же, как я описывал — просто вместо тупой структуры с конфигурацией мы передаём в функцию инициализации библиотеки объект с методами, соответствующими интерфейсу Config. Библиотека получает значения конфига через вызов методов этого объекта в тот момент, когда они ей нужны, а откуда этот объект их берёт и каким образом обновляет на лету — библиотеке не важно. Суть остаётся ровно та же самая: мы можем передать библиотеке объект конкретного типа возвращённый функцией DefaultConfig (работающий через чтение/парсинг/перечитывание дефолтного файла с конфигурацией), а можем передать объект любого другого типа с теми же методами (напр. тестовый мок, который содержит прошитые в тесте значения конфигурации и изменяет их в момент, когда это нужно тесту).

  • За что я не люблю Go
    0
    Только библиотека знает, валидный ли файл конфига или нет. Как вы это сделаете «еще до инициализации библиотеки»?

    Вы мой пример кода понять пытались вообще? Похоже, что нет. Ладно, попробую объяснить на пальцах, без кода:


    1. Дано: есть некая библиотека, достаточно сложная, чтобы ей мог понадобиться собственный конфиг-файл. Тем не менее, хочется избежать создания жёсткой связи между библиотекой, которая может оказаться частью любого приложения выполняющегося в любых условиях, и конкретным конфиг-файлом на диске.
    2. Чтобы разорвать эту связь, мы модифицируем функцию-конструктор/инициализатор библиотеки так, чтобы она принимала параметром структуру, описывающую её конфигурацию, вместо того, чтобы самостоятельно считывать и парсить конкретный конфиг-файл. Таким образом, ответственность за считывание и парсинг конфиг-файла переносится на вызывающий код, обычно это main() конкретного приложения, знающего условия в котором оно выполняется, и решающего, откуда и как получить конфигурацию для этой библиотеки.
    3. Тем не менее, предполагая, что большинству приложений подойдёт подход по умолчанию, заключающийся в считывании конфигурации из конкретного файла, мы добавляем в библиотеку отдельную, опциональную, независимую вспомогательную функцию, которая умеет исключительно считать этот конфиг-файл и вернуть структуру с конфигурацией, необходимую для инициализации библиотеки.
    4. В результате, main() имеет возможность проинициализировать библиотеку в два шага: сначала вызвав вспомогательную функцию для считывания конфиг-файла, и потом передав структуру с конфигурацией в функцию инициализирующую библиотеку. На обоих шагах могут возникнуть ошибки, которые main() может обработать по своему разумению.

    Помимо прочего, такой подход крайне рекомендуется для упрощения тестирования библиотеки, т.к. тест сможет легко подсовывать библиотеке разные структуры с конфигурацией, без необходимости создавать/изменять конфиг-файл(ы) на диске. Это и есть типичный пример тех "разных условий, в которых может выполняться библиотека", в которых безусловное чтение конфиг-файла может оказаться неуместным.

  • За что я не люблю Go
    0

    Никто не в силах помешать делать глупости или писать код бездумно. ЯП может просто способствовать более правильному отношению либо потакать менее правильному. Смысл — зачем это делается именно так — я пояснил. Конкретная реализация — как сделано сейчас, или как в будущем будет сделано через handle/check — не имеет принципиального значения, пока сохраняется изначальный смысл. Придумаете более классную реализацию — welcome, сейчас как раз идёт обсуждение handle/check, и у Вас есть реальный шанс повлиять на дизайн языка.

  • За что я не люблю Go
    0
    В вашем примере, если мы в последней строчке падаем, то хочется об этом знать.

    Какую строку Вы назвали "последней"? Последняя создаёт someThing, но дальше Вы пишете опять про конфиг, так что я несколько запутался. Если Вы говорили таки про строку с someThing, то там никто не падает, вызов some.New() в этом примере не может завершиться с ошибкой — это довольно типично для простых конструкторов. Если бы там могла возникнуть ошибка (напр. если он как-то проверяет переданный конфиг на валидность), то он просто вернул бы someThing, err.


    если не смогли, но произошла ошибка парсинга, то взять дефолтный конфиг

    Это не имеет значения в рамках дискуссии, но брать дефолтный конфиг может иметь смысл при отсутствии конфиг-файла, но ни в коем случае не при ошибке парсинга — если файл был кем-то написан, то это сделано потому, что дефолтный конфиг не подходит, так что в этом случае надо падать с ошибкой.


    Если либа за меня решает, что делать ей с ошибкой "на своём уровне", то я никак не могу принять решение там, где это действительно нужно.

    Да, но в моём примере этой проблемы нет — именно по этой причине формирование структуры с конфигом отделено от инициализации библиотеки, чтобы Вы смогли сами обработать ошибку чтения конфига любым образом ещё до инициализации библиотеки.

  • «Яндекс» объяснил, почему удалил из поисковой выдачи официальный сайт Telegram
    +5

    Это с одной стороны. А с другой — если Яндекс начнёт фильтровать так, как этого хотят чиновники, он довольно быстро превратится во второй Спутник, с тем же уровнем посещаемости.

  • «Яндекс» объяснил, почему удалил из поисковой выдачи официальный сайт Telegram
    +3

    Может они просто ещё один реестр завели, специально для поисковиков? Они ведь любят заводить разные реестры…

  • За что я не люблю Go
    0

    На то есть разные причины. Я лично стараюсь такие ответы не давать, так что можете задать такие критикующие вопросы мне, если, конечно, Вам интереснее получить конкретные ответы, нежели просто продолжать критиковать ради самого процесса.


    Конкретнее по упомянутым вариантам ответов:


    • "А вот Пайку виднее" — я на авторитеты никогда не ссылаюсь, но понимаю, почему нередко отвечают именно так. Есть определённые идеи, до которых многие просто ещё не доросли. Это не понты и не взгляд свысока, это просто факт. И касается он всех, абсолютно точно включая меня, и, я полагаю, и Пайка тоже. Есть идеи, которые рождаются раньше "своего" времени, из-за чего они оказываются проигнорированы и забыты. Моё личное мнение — множество таких идей появилось лет 30 назад, в OS Plan9, потом в OS Inferno и языке Limbo. Часть этих идей, к сожалению, так и не стали популярны до сих пор, хотя процесс идёт, иногда криво реализованные, но они проникают в современные OS, ЯП и утилиты. Я лично думаю, что дело не столько в том, что эти идеи появились слишком рано, сколько в том, что их авторы абсолютно не занимались их популяризацией. Go это первый представитель части этих идей, который стал популярен (и да, произошло это именно благодаря жёсткой раскрутке его гуглом, а не благодаря его техническому совершенству — в этом плане он на старте заметно проигрывал предыдущим разработкам). Но я бы не стал винить гугл в том, что он сильно пиарит Go — тут скорее мы сами виноваты в том, что чаще всего без такого пиара не в состоянии заметить даже очень классные вещи. Так вот, извините за длинное предисловие, суть ответа "Пайку виднее" в том, что за некоторыми особенностями Go стоят именно те идеи, до понимания которых многие ещё не доросли, но идеи от этого менее правильными не становятся, поэтому иногда нужно просто делать как делают взрослые, и, со временем, станет понятно зачем и почему это делается именно так. Да, такой ответ раздражает, но учитывайте, что для того, чтобы ответить как-то более осмысленно, отвечающему самому надо сначала дорасти до этих идей, плюс уметь внятно объяснять другим то, что понял сам.
    • "Зато мне не надо каждый год изучать новые фичи языка" — это вполне валидный ответ, как по мне. Мне категорически не нравится мелькание технологий, которое сейчас происходит на фронте, а до этого происходило под виндой. Я предпочитаю использовать более стабильный стек — мне есть что непрерывно учить помимо нового синтаксиса ЯП и что делать помимо переделывания старого кода под новые требования ЯП.
    • Насчёт остальных ответов согласен.
  • За что я не люблю Go
    0

    Суть в том, что нужно ручками сделать хоть что-то в том месте, где надо обработать ошибку. У меня есть сниппеты, которые вставляют такие конструкции. А ещё можно ошибку тупо загасить приняв её в _ вместо переменной. Но и подчёркивание, и комбинацию для сниппета надо набрать. А значит — задуматься, какой из типичных сниппетов или подчёркивание подходит для обработки текущей ошибки. Что и требовалось. Не важно, сколько кнопок нужно нажать на клавиатуре, важно что их в принципе нужно нажать, и перед этим задуматься, какие именно.


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

  • За что я не люблю Go
    0

    Вы не поняли, DefaultConfig возвращает не имя файла с конфигом, а значение содержащее сам конфиг. Откуда это значение получено — из файла, или из другого места — библиотеке дела нет. Использовать DefaultConfig или что-то другое — решает вызывающий код (т.е. main, которые единственный знает текущий контекст выполнения, откуда брать конфиги, куда писать логи, и как подключиться к БД).


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


    Например, если для библиотеки является штатной ситуацией работа без конфига (точнее, с использованием дефолтного конфига прошитого в самой библиотеке), и отсутствие в системе /etc/библиотека.yml это типичная ситуация, то DefaultConfig() может вообще игнорировать все ошибки и возвращать nil, который библиотека трактует как "взять дефолтный конфиг". Как по мне — это немного грязно, DefaultConfig стоит хотя бы вывести в лог все ошибки кроме отсутствия файла.


    Но в более типичном/общем случае это делается немного иначе, просто не в одну строку:


    someConfig, err := some.Defaultconfig()
    if err != nil {
        // мы в main(), тут log.Fatal можно
        log.Fatalf("failed to load config: %s", err)
    }
    someThing := some.New(someConfig, log, db)
  • За что я не люблю Go
    0

    Вторая паника будет добавлена к описанию первой, а в остальном никакой разницы, одна паника или две: https://play.golang.org/p/Of3KiMh4Tdg — пока не вызвали recover() паника продолжит раскручивать стек и выполнять defer-ы.

  • За что я не люблю Go
    0

    Да, конечно, defer вызывается при любом выходе из функции, хоть return хоть panic.

  • За что я не люблю Go
    0

    То, что кто-то это делает — не повод считать что это хорошо. Библиотека на то и библиотека, что она не знает, и не должна навязывать конкретный контекст своего выполнения. Всё взаимодействие библиотеки с внешней средой — получение конфига, логирование, доступ к БД — правильнее оформлять через DI, причём принимать все эти зависимости библиотека должна как интерфейсы.


    Даже если в 99% случаев использования данная библиотека действительно должна тупо читать свой конфиг из файла /etc/библиотека.yml, то она должна предоставить в своём публичном API вспомогательную функцию DefaultConfig(), которая считает этот файл и вернёт значение, подходящее для передачи DI-параметром основному конструктору/инициализатору этой библиотеки. В этом случае эти 99% кода будут содержать что-то вроде:


    something := some.New(some.DefaultConfig(), mylog, mydb)
  • За что я не люблю Go
    –1

    Суть фразы "Подход Go подталкивает к обработке ошибок, а не на отсылку их выше в надежде, что кто-нибудь разберется." в том, что нужно в каждой конкретной точке задуматься, как именно здесь нужно обработать ошибку.


    Да, очень часто её нужно просто прокинуть наверх, но, тем не менее, хоть это и самый частый вариант, делать его вариантом "по умолчанию" (как очень часто используют исключения) это плохая идея, именно потому, что позволяет вообще не задумываться об обработке ошибок до самого последнего момента. И да, если разработчик будет механически везде вставлять if err != nil { return err } то это будет ровно то же самое — он не задумывается об обработке ошибок, и просто тупо набирает бессмысленный код. Тем не менее, сама необходимость этот код набирать, и потом читать на ревью — увеличивает вероятность, что кто-нибудь всё-таки задумается, насколько этот код корректен в случае ошибки конкретно в этом месте.


    Конечно, всем хочется набирать меньше тупого шаблонного кода, но нельзя это делать ценой потери такого полезного качества языка как подталкивание программистов задумываться о корректной обработке ошибок. Более детально почитать про это можно в описании нового синтаксиса обработки ошибок в Go2 через check/handle.

  • Альтернативы LastPass. Сравнительная оценка шести парольных менеджеров
    0

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