Да, что хорошо, про Яву мне говорить попроще. Действительно вызов функции может привести к очень не очевидным действиям, особенно, если у нас вызов идет через динамический контейнер (пикоконтейнер, например), еще и используя reflection. Но, эту сложность и хитрость специальным образом обертывают в предсказуемые высокоуровневые концепции, это либо библиотека-контейнер, которой надо довольно долго учится и понимать ее, либо просто стандартные концепции Явы. Это не тот беспредел, который вносит goto. Это высокоуровневый контракт, в который и выносят всю сложность этого типа. У exceptions есть схожие проблемы. Как раз основная идеология, это собрать все сложные места и вынести их в небольшое ядро и обеспечить некой предсказуемой идеологией. С goto проблема в том, что в каждом месте, где оно будет использоваться, это будет свой способ, за этим будет своя логика, свои переходы итп.
Аналогичный подход используется в многопоточных штуках всяких, когда всю многопоточную специфику уносят в ядро, где обеспечивают корректные передачи объектов, понятные контракты итп. При этом отсальной код пользуясь некоторым набором высокоуровневых правил может не заботится изза многопоточки.
В С++ ситуацию я не готов комментировать с достаточным основанием, но все же стоит сначала понять, что алгоритм должен делать и лишь потом переходить к его кодированию. Это вообще, общий совет. Сначала надо понять, что ты делаешь, а вот тогда и выяснится, что высокоуровневые примитивы лучше описывают задачу. Я не беру ситуацию низкоуровневой оптимизации, которая как понятно никогда не должна быть преждевременной.
В современных язык очень не любят goto из очень простых соображений, высокоуровневые примитивы предсказуемы. Точка входа в for, while, if предсказуема и понятна. Точка входа в for это строчка которая находится перед этим самым циклом. Да, внутри цикла переходы будут посложнее, но опять же и тут это предсказуемые и однотипные переходы. В случае с метками, никогда не поймешь откуда произошел переход на нее, пока не просмотришь ВЕСЬ код. Теряется свойство локальности, инкапсуляция кода.
Аналогичная беда есть с эксепшенами, но и там как бы контрол флоу предсказуем относительно, хоть и требует некоторого навыка, ибо он неявен. Но все равно в целом контроль над переходами остается. В случае с goto же получается полная каша, глядя на метку невозможно понять откуда на нее попробует код перескочить.
"— Но в целом компания ищет не сотрудников-мужчин либо сотрудников-женщин, а специалистов и индивидуальностей, которые выделяются на фоне большинства. Компания прикладывает усилия к достижению гендерного баланса среди работников. Например, для поощрения изучения IT девушками, Google ежегодно присуждает стипендии Фонда имени Аниты Борг."
Мне вот более интересно, как сделать, чтобы видео падало не в файл, а в виде event-ов ко мне в callback. Особенно это интересно для звука, чтобы всякие спецэффекты прикручивать прямо в realtime.
Я вот далек от олимпиадного программирования и меня всегда волновал вопрос, чем динамическое программирование отличается от банальной рекурсии с кэшированием?
На моей (сугубо корпоративной) практике основные места, где лезут баги и с которыми стоит бороться в первую очередь.
1. Интеграция. Когда оборудование или чужой, внешний код ведет себя не так, как ожидает программист. Его код работал бы верно, если бы экосистема работала бы так, как ожидает программист.
2. Многопоточка. Без комментариев, везде где есть многопоточка, есть и труднейшие баги.
3. Неправильный анализ задачи, неполная постановка задачи итп.
90%+ проблем с кодом растет ногами отсюда.
Юнит тесты крайне полезны в случае какого-то узкого нетривиального места, если какое-то в место кода раз за разом вызывает недоумение, это хороший аргумент на покрытие юнит тестом. Либо, на переписывание его в более достойный вид.
Покрывать весь код юнит тестами, это как писать комментарии на геттеры. Есть любители, наверное, но мне вот неудобно. Я, как и все, безусловно очень позитивно отношусь к тестам в целом, но вот ТДД для меня это что-то непонятное. Хотя допускаю, что в каких-то других внешних условиях, может и применимое.
Могу предложить еще одну отговорку, которая для меня имеет довольно существенно значение. Юнит тесты не эстетичны, их код всегда грязен. Заполнен моками и описаниями не того, что мы хотим проверить, а того как мы это проверяем. Ведь мы сначала долго и мучительно конструируем экосистему для объекта, а потом вызываем метод и несколько валидаций, а скорее всего примитивных ассертов. Я не видал такого и не умею соответственно делать так, чтобы юнит тесты читались бы прозрачно.
Я сам в своей практике пробовал несколько раз использовать как ТДД, так и юнит тестирование. Ни разу позитивный опыт не получил, при том функциональные и интеграционные тесты это совсем другая песня. Вот они дарят постоянную радость и действительно уверенность в своем коде. Я не понимаю идеологию юнит тестирования, подавляющее большинство ошибок возникают из-за того, что ты не знаешь, как должен вести твой код с внешними подсистемами. Собственно, багов при поддержке кода, когда код ведет себя не так как ты от него ожидаешь, их не так много и они легко ловятся и без системы юнит тестов.
Схожее у меня отношение и к комментариям, если код требует комментария, лучше переписать код. Комментированным должен быть заметный кусок функциональности, который можно использовать отдельно, не переключаясь на ньансы его пользования. Та же логика, если мы близки к конкретному коду. ни тестирование, ни комментарии не так уж нужны, код и так вполне прозрачен. А вот большие куски кода оформленные как более менее завершенный АПИ, вот они нуждаются как в тестах, так и какойто документации, комментариях итп.
Если кого-то интересуют такие вот штуки, советую почитать «Java Puzzlers». www.javapuzzlers.com/
Впрочем, уж насколько я люблю всякие необычные штуки, но все эти знания уж слишком непрактичны.
С одной стороны, проблема есть, с другой стороны ХРы способны предварительно отсеивать большинство таких кадров до технического собеседования. А так, ну что вы хотите, без такого просева подавляющее большинство неспособно цикл написать по коллекции нормально. У нас просто схожая проблема, даже очень сильный сеньор жаба девелопер, в среднем, как правило, очень сильно плавает в мультитрединге. Тех, кто освоил хотя бы базовые концепции очень небольшой процент, хотя дело то не хитрое. Видимо, на практике не очень просто востребованный навык.
Финализаторы, кстати, очень удобно использовать для логгинга для детекта ликов. Если финализатор обнаружит, что на объекте не вызван close() он может выводить в лог с-щее предупреждение. Очень удобно.
Еще бросилась в глаза подробнейшая инструкция по эксепшенам, которая приводит к одной из самых распространенной болезни в кодировании, чрезмерному увлечению троваблами, когда кидание эксепшена является рядовым возвратом из функции. И это на андроиде, где перфоманс ключевой фактор. То, что эксепшены надо корректно отрабатывать, мысль вполне понятная, и все ветки исполнения должны адекватно читаться, это тоже понятно.
Аналогичный подход используется в многопоточных штуках всяких, когда всю многопоточную специфику уносят в ядро, где обеспечивают корректные передачи объектов, понятные контракты итп. При этом отсальной код пользуясь некоторым набором высокоуровневых правил может не заботится изза многопоточки.
В современных язык очень не любят goto из очень простых соображений, высокоуровневые примитивы предсказуемы. Точка входа в for, while, if предсказуема и понятна. Точка входа в for это строчка которая находится перед этим самым циклом. Да, внутри цикла переходы будут посложнее, но опять же и тут это предсказуемые и однотипные переходы. В случае с метками, никогда не поймешь откуда произошел переход на нее, пока не просмотришь ВЕСЬ код. Теряется свойство локальности, инкапсуляция кода.
Аналогичная беда есть с эксепшенами, но и там как бы контрол флоу предсказуем относительно, хоть и требует некоторого навыка, ибо он неявен. Но все равно в целом контроль над переходами остается. В случае с goto же получается полная каша, глядя на метку невозможно понять откуда на нее попробует код перескочить.
Только я вижу тут взаимоисключающие параграфы?
Какие проблемы? Черным по белому: 420 часов в режиме ожидания, это 2.5 недели. 8)
1. Интеграция. Когда оборудование или чужой, внешний код ведет себя не так, как ожидает программист. Его код работал бы верно, если бы экосистема работала бы так, как ожидает программист.
2. Многопоточка. Без комментариев, везде где есть многопоточка, есть и труднейшие баги.
3. Неправильный анализ задачи, неполная постановка задачи итп.
90%+ проблем с кодом растет ногами отсюда.
Юнит тесты крайне полезны в случае какого-то узкого нетривиального места, если какое-то в место кода раз за разом вызывает недоумение, это хороший аргумент на покрытие юнит тестом. Либо, на переписывание его в более достойный вид.
Покрывать весь код юнит тестами, это как писать комментарии на геттеры. Есть любители, наверное, но мне вот неудобно. Я, как и все, безусловно очень позитивно отношусь к тестам в целом, но вот ТДД для меня это что-то непонятное. Хотя допускаю, что в каких-то других внешних условиях, может и применимое.
Я сам в своей практике пробовал несколько раз использовать как ТДД, так и юнит тестирование. Ни разу позитивный опыт не получил, при том функциональные и интеграционные тесты это совсем другая песня. Вот они дарят постоянную радость и действительно уверенность в своем коде. Я не понимаю идеологию юнит тестирования, подавляющее большинство ошибок возникают из-за того, что ты не знаешь, как должен вести твой код с внешними подсистемами. Собственно, багов при поддержке кода, когда код ведет себя не так как ты от него ожидаешь, их не так много и они легко ловятся и без системы юнит тестов.
Схожее у меня отношение и к комментариям, если код требует комментария, лучше переписать код. Комментированным должен быть заметный кусок функциональности, который можно использовать отдельно, не переключаясь на ньансы его пользования. Та же логика, если мы близки к конкретному коду. ни тестирование, ни комментарии не так уж нужны, код и так вполне прозрачен. А вот большие куски кода оформленные как более менее завершенный АПИ, вот они нуждаются как в тестах, так и какойто документации, комментариях итп.
www.javapuzzlers.com/
Впрочем, уж насколько я люблю всякие необычные штуки, но все эти знания уж слишком непрактичны.
Иногда возникает ощущение, что я живу в каком-то другом мире програмирования, а другие програмируют на notepad, где среда не подсвечивает поля класса, где люди руками смотрят в импорты чаще раза в месяц. Где среда на коммите не автоформатирует класс согласно общекомандному стилю и кого-то действительно волнует, что там в секции импортов сидит. У меня эта секция свернута средой и поддерживается средой. А уж про венгерскую нотацию сколько было статей, что подбирать префиксы по типу переменной (мембер, статик, локальная итп) или по классу это зло.
local.joelonsoftware.com/mediawiki/index.php/%D0%9A%D0%B0%D0%BA_%D0%B7%D0%B0%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C_%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D0%B2%D1%8B%D0%B3%D0%BB%D1%8F%D0%B4%D0%B5%D1%82%D1%8C_%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE
Еще бросилась в глаза подробнейшая инструкция по эксепшенам, которая приводит к одной из самых распространенной болезни в кодировании, чрезмерному увлечению троваблами, когда кидание эксепшена является рядовым возвратом из функции. И это на андроиде, где перфоманс ключевой фактор. То, что эксепшены надо корректно отрабатывать, мысль вполне понятная, и все ветки исполнения должны адекватно читаться, это тоже понятно.