Обновить
31
Антон Куранов@Throwable

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

13
Подписчики
Отправить сообщение
Optional не решает общей проблемы NullPointer-ов, так как само поле Optional может быть null. Кроме того Optional вводит косвенные проблемы совместимости такие как сериализация, распознавание типов полей многими фреймворками, etc… И совершенно не согласен, что код становится читаемей, хоть и чуть короче.

Глобально, null reference — это глобальная ошибка дизайна языков, которая усугубилась в Java (и еще больше в Scala), когда решили работать исключительно только со ссылками и фактически исключили value-типы.
qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake

Сейчас идет обратная тенденция включить в язык структуры (value types). Есть попытки исправить ситуацию, напр. в Kotlin явно указывается, что тип nullable, что вносит определенные сложности с использованием api джавы. Даже в саму джаву когда-нибудь планируется внести value types, но маловероятно: habrahabr.ru/post/222113/

Так что пока остается только четко документировать код и использовать @Nullable/NotNull
Может быть полезна библиотечка от Google для контрактного программирования, основанная на аннотациях: code.google.com/p/cofoja/ Работает через AnnotationProcessing или Java Agent.
Сорри, действительно. Entry у ThreadLocalMap — это WeakReference на ThreadLocal, так что ThreadLocal все-таки собирается GC. Странность реализации заключается в том, что Entry и value продолжает храниться в таблице, пока Thread не вызовет не set() для любой TheadLocal.
> Также популярным вариантом утечки является ThreadLocal переменная, которой присвоен объект из веб-приложения для потока из общего пула. В этом случае поток хранит ссылку на объект.

Это совершенно неверно. Поток нигде не хранит ссылку на объект. Внутри ThreadLocal использует структуру похожую на Map для сопоставления объекта с потоком. Сборщик мусора соберет ваш ThreadLocal и все его объекты также как обычный HashMap. При этом потоки естественно останутся нетронутыми.
Сумбурно написано о ссылочном типе-обертке. Нужно, чтобы ссылочный тип можно было въявную указывать при определении переменной: как int и Integer.

— Типы-значения могут содержать и обычные объектные поля (которые не обязаны быть рекурсивно неизменяемыми, как сами значения), и поля других типов-значений. Но: не могут содержать поля своего же типа.
Спорно, т.к. стороны это нарушает труЪ-immutability.
Поля должны давать возможность быть ссылочной оберткой типа для реализации рекурсивных структур типа бинарного дерева:
_ByValue class Node {
Node? left, right; // Синтакс C#
}

— Тип-значение не может наследовать ни классу, ни другому типу-значению, от типа-значения ничего нельзя наследовать.
Спорно. Vector3D extends Vector2D… При присваивании просходит преобразование значения:
Vector3D v3 = ...;
Vector2D v2 = v3; // OK
Vector3D v3_1 = (Vector3D) v2; // Error

— Применение рефлексии к значению.
:( А в чем проблема? Это затруднит интроспекцию структуры, и динамическое получение данных. Половина фреймворков отвалится. Представьте, что в Hibernate нужно замепить value-type как Entity или @Embeddable…

— Присвоение переменной типа-значения null.
Если у меня поле имеет value-type, я должен указывать въявную дефолтное значение? Или default value определено как default value всех его простых полей?
public Vector3D v; // дефолтное значение Vector3D(0,0,0);

— Приведение к Object или любому супертипу.
Autoboxing к ссылочной обертке???

Почему не взлетит?
— очень толстое изменение, затрагивающее работу JVM практически на всех уровнях.
— текущие API Java не заточены под использование value-types. Потребуется либо полная переработка API, либо создание нового API (RTL 2.0).
— также многие библиотеки и фреймворки не заточены под использование value-types. Это новый концепт, который может польностью нарушить работу существующего функционала.
— все уже есть в scala
Почему я проголосовал «нет» на перспективу:
— Хорошая идея — всегда видеть консистентное состояние на начало транзакции. Но этого недостаточно. Изначальная идея транзакций — чтобы параллельные вычисления выполнялись с точностью так, как бы они выполнялись последовательно, допуская единичные коллизии. MVCC такого не гарантирует — требуются блокировки (на чтение).
— Архитектура большинства систем предполагает хранение состояния в persistence storage, а оперативная память используется лишь как временная внутри одной операции. Storage уже имеет все средства транзакций, плюс ряд преимуществ как масштабируемость, отказоустойчивость, etc… Для хранения состояния в памяти есть также куча in-memory storage.

Для полноты картины реализации STM на Java:
multiverse.codehaus.org/overview.html
sites.google.com/site/deucestm/
> Автор статьи придерживается мнения, что часто лучше самому запрограммировать всё с нуля. Странно правда, что при этом он использует сервлеты, а не пишет собственное решение.

Есть разница между фреймворком и библиотекой. Чаще всего фреймворк следует принципу «don't call me, I call you», т.е. решение представляет собой конфигурацию + разрозненные куски кода, реализующие тот или иной функционал, а фреймворк — это core. Такой подход накладывает искусственные ограничения на «правильное» написание кода (так вот можно, а вот так нельзя — фреймворк не поймет), и добавляет в решение неявной «магии», при сомнительном выигрыше. При библиотечном же подходе разработчик полностью в явную контролирует все, что творится у него в рантайме, всю конфигурацию, жизненный цикл объектов, все вызовы API.

Если мне нужен сервлет контейнер, я подключаю Jetty как embedded библиотеку. Все создается и конфигурируется прямо в коде. Jetty очень хорошо «модулеризирован»: весь функционал разбит по разным jar-ам, которые можно подключать по надобности.

> Ошибочное мнение многих начинающих разработчиков — «легче написать самому, чем разобраться в том, что уже сделали другие».

Чаще всего я вижу другой подход: «будем использовать Spring, потому что все так делают». Начинающий разработчик скачивает tutorial (какой-нить Spring+Hibernate+Struts), и делает скелет приложения. Неважно, что из функционала спринга он использует пару бинов и коннекшн к базе данных, из Hibernate — две связанных таблицы, а из Struts — jsp.
Другой вопрос — сможет ли начинающий разработчик с нуля написать адекватную систему? Поэтому в техзадании требуют фреймворк, чтобы облегчить поддержку кода, т.к. фреймворк дает определенную методологию разработки («рельсы»). Реально же из начинающих разработчиков, программирующих на фреймворках, я мало видел людей, полностью понимающих основные концепты. Для большинства документация к фреймворку — это магическая книга, где чтобы сделать ту или иную вещь нужно найти заклинание и вставить его в код.

> Хороший фреймворк — это ни что инное как эсенция годами накопленного опыта разработчиков специализирующихся в этой области.

Вот здесь позвольте не согласиться. Во-первых, фреймворк — это определенная идея, обернутся в реализацию. Это совсем не значит, что эта идея, пусть даже и красивая, действительно необходима и удобна в использовании. Как правило у всех красивых идей бывает обратная сторона. И преимущества идеи с лихвой могут покрываться «побочными эффектами», вызываемыми этой идеей.
Во-вторых, создатели фреймворка занимаются исключительно фреймворком и как правило не пишут приложений, а посему далеки от реальных потребностей разработчика.
В-третьих, всегда существуют побочные эффекты, вызванные различными причинами: от «неверного» использования до конфликта jar-ов. Значительная часть усилий тратится на «я написал как надо, а у меня не работает (как я хочу)» и решение проблем самого фреймворка. Порой простую вещь сделать на порядок сложнее с фреймворком, чем на голой java.

> но в разработке веб-систем, я думаю использование фреймворков не оспаримо.
Отсюда и пошли все фреймворки и это их основное назначение.

P.S. Я не считаю фреймворки абсолютным злом. Просто перед использованием каждого из них разработчик должен задуматься над вопросами:
— какой функционал мне нужен и смогу ли я обойтись без него?
— не проще ли будет и смогу ли я написать это все без фреймворка?
— есть ли библиотеки, реализующие данный функционал?
— действительно ли преимущества фреймворка использования покроют недостатки?
Очень распространенный миф. Фреймворки призваны решать как раз простые типовые задачи. Они предлагают унифицированное архитектурное решение, определенный набор функционала, а также определенные методы разработки и тестирования, которые бывают полезны в команде не очень сильных девелоперов. И это основная почему люди привыкли использовать фреймворки — быстрый бутстрап, отсутствие заморочек с архитектурой, унифицированные методы разработки, поддержка коммьюнити.

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

Анализируя реальные задачи, с которыми я сталкивался, в 90% случаев приходил к выводу, что использование фреймворка излишне. Все делалось проще и понятнее на обычной Java. Фреймворк добавлял магии, и только сильно запутывал код.
Данный факт абсолютно никак не опровергает, что все написанное относительно DI верно. DI — это паттерн проектирования, а не фреймворк. Никто не запрещает сделать свой контекст с методами: MyContext.getBean() без всякого спринга. Работать будет также, весить на несколько тонн меньше, магии ноль — соответственно надежней и читабельней.

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

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

В реальных же проектах никто не задумывается зачем им нужен Spring. Его сразу ставят «по дефолту», потому что это модно, стильно и все так делают. Даже в проекте из четырех бинов и базы данных.
Вопрос — почему у Вас 100500 properties? Надо четко разделять пользовательские настройки и системную конфигурацию. Такие вещи как URL к базе данных, хост пользуемого вебсервиса, различные настраиваемые параметры поведения системы — это все пользовательские настройки. Их нужно выносить в отдельный файл. Конфигурация бинов и зависимостей — это чисто внутренние параметры системы. Давать клиенту менять конфигурацию будет крайне необдуманно (пустить козла в огород...). Даже если нужно поменять всего один системный параметр, для клиента это должно выглядеть как новая версия. Клиент не должен знать что там и как внутри устроено.

Groovy конфиги добавят к проекту еще over 9000 мб jar-ов для одноразового чтения десяти строчек.
> А где же находится правда? Неужели как всегда посередине?
А правда в том, что в подавляющем большинстве случаев использования спринга проще, надежнее и быстрее обойтись без него. Для связки четырех бинов и конекшна к БД IoC не нужен. Если уж пошла речь об IoC и конфигурации, мне с самого начала нравился Guice и его манера конфигурирования контекста (DSL).
Опытный кодер задаст огромное число безусловно корректных и необходимых вопросов, ответов на которые он в большинстве случаев так и не дождется. Чтобы ответить на все его вопросы нужно проводить полное исследование предметной области, на которое как правило нет ни средств ни времени. Поэтому опытный кодер, не получив очередной ответ, вполне логично предполагает «худшую» ситуацию и соответственно кодит «с запасом», насилуя код различного рода проверками, синхронизациями и сверхдизайном на все случаи жизни.
В словах автора есть определенная истина. Однако описанные ситуации возникают именно из-за отсутствия анализа требуемого функционала и случаев использования. Опытный кодер пытается сделать свою часть задачи максимально универсально, если его часть находится в отрыве от общего контекста. Отсюда и появляются и корректные блокировки и многопоточность и multicore оптипизация (а вдруг понадобится?) плюс в придачу куча трудноотловимых ошибок. В итоге получается, что джуниор, который этого всего не знает, пишет быстрее и эффективней, чем профессионал.

Agile для меня эффективен в смысле, что всегда нужно иметь что-то запускающееся. Короткие итерации гораздо лучше, чем длительные «закоды». Парное программирование не пробовал, но полностью против. Чтобы кто-то постоянно стоял над душой, когда хочется спокойно подумать, потестировать пару идей. По-моему лучше метод коротких синхронизаций.
Не чушь, а самое реальное и остроумное решение. Только трос будет тащить мангитное поле Земли. Ускорение микроскопическое, но со временем орбита начнет меняться. Где-то было подробно описано — не помню.
Когда у Вас появится «пространство хитрой конфигурации», черная дыра для полетов Вам уже не понадобится:
ru.wikipedia.org/wiki/%D0%9F%D1%83%D0%B7%D1%8B%D1%80%D1%8C_%D0%90%D0%BB%D1%8C%D0%BA%D1%83%D0%B1%D1%8C%D0%B5%D1%80%D1%80%D0%B5
Для любого движения необходимы две составляющие:
1. Источних энергии
2. Контролируемый механизм преобразования энергии в кинетическую.
Если по первому пункту изливаются бурные фантазии, второй вообще никак в статье не озвучен. А именно он является принципиальной проблемой. Бензин горит просто. ДВС — довольно сложная штука. Водород с кислородом — тоже просто понять и зажечь. Ракетный двигатель — результат десятков лет исследований, разработок и экспериментов. Цепная реакция в уране тоже очень проста для осознания. Ядерный реактор — тоже вещь достаточно нетривиальная.

Так вот, опуская фантастику черной дыры, можно отметить следующие вещи:
— излучение Хокинга еще не доказано. Есть много споров на этот счет.
— самый простой способ движения — зеркало-рефлектор, отражающий испускаемые черной дырой высоконергенические частицы и тем самым приобретая ускорение. Озвученная попытка собирать энергию куполом, аккумулировать и преобразовывать как-то по-другому просто лишена смысла.
— черная дыра указанных размеров испарится примерно за несколько минут, а не за 5 лет, и с эффектом подобно взрыву. Помешать или замедлить этот процесс не представляется возможным даже теоретически.
— для долгосрочного действия черной дыры необходима постоянная подпитка веществом. Дыра, размером с протон и массой с несколько зданий сама не будет ничего «засасывать». В нее нужно будет точно стрелять веществом из шланга, размером с тот самый протон, при этом прокачивая килограммы и тонны массы.
— тепловой спектр микроскопической черной дыры содержит исключительно высокоэнергетические частицы: от гамма фотонов вплоть до массивных ядер. Такие энергии гарантированно разрушат структуру любого вещества, из которого будет сделан рефлектор. Защитить экипаж от действия подобных энергий тоже задача не из простых.
Ну и вот ссылка на википедию по данному вопросу: ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B9_%D1%80%D0%B5%D0%B0%D0%BA%D1%82%D0%BE%D1%80
А что мешает работодателю поставить официальную зарплату в 100$, а остальное переводить черным налом?
Здесь требуется полный пересмотр всех концептов налогообложения. Кошельки в отличие от денег неподвластны мониторингу, поэтому и такие вещи как подоходный налог, НДС, уже не применимы. Это ведет непосредственно к ослаблению роли государства: оно теперь вынуждено компенсировать бюджет налогами на собственность, землю, производство. Большинство заботы о населении перейдет на плечи частных огранизаций, напр. медицина, охрана населения, страховые фонды. Финансовая деятельность компаний и людей останется вне контроля государства и не будет облагаться налогом. Тогда как любая «физическая» деятельность (работа, собственность, производство) будет жестко мониториться и облагаться налогом.
В 4.4, наконец, заменили тормозной дефолтный WebView на WebView от Chromium. Критично для тех, кто пишет на PhoneGap.
Простой вопрос: будут ли исходники, написанные на Java 8, компилироваться в target Java 7/6? В свое время переход с 1.4 -> 5.0 был достаточно болезненным по причине несовместимости байткода и затянулся на 5 лет.
> То, что мирный житель вынужден двигаться в обсуждении и докапываться до сути, тогда как мафия может просто дождаться конца дня и сделать своё дело
Странно, почему тогда именно мафию называют активной картой?

> за мирного жителя заключается в том, чтобы вести полную системорегистрацию происходящего. Конкретно – запоминать кто и что про кого сказал.
Нереально. Даже записывать пробовал. Десять человек за раунд, по минуте каждый… Кроме того, не работает.

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

> Для опытных игроков перемена подозрений без достаточного обоснования – достаточно чёткий флаг
Неа. Все плавают. Основная ошибка мафии, по которой ее можно вычислить: мафия как правило не высказывает инициативы убрать кого-то, но охотно присоединяется к чьим-то высказанным подозрениям.

> То есть игрок мафии никогда не должен заступаться за своих, иначе в случае провала попытки станет следующим.
От числа мафий напрямую зависит когда закончится игра. Прямо заступаться — нет, но перекинуть подозрения на другого можно. И если альтернативы нет и ясно, что чела линчуют, тогда естественно идти против него. Мафия играет «на стол», то есть за свою команду. Не важно когда тебя вышибут, важно, чтобы твои выиграли. Иногда даже необходимо «подставиться»: зная, что тебя уберут тупо выставить своих, чтобы отвести подозрения.

Теперь по сути. Чисто математически на первых конах вероятность мирному жителю выставить своего больше, чем в процессе. Поэтому и стратегия должна отталкиваться от предполагаемого соотношения мафий и жителей: вначале играть пассивно и собирать информацию, потом на основе нее делать активные действия. Для мафии же наоборот, неплохим ходом является сразу же выставить кого-нибудь «для придания игре активности» (например даже свою мафию), чтобы вынудить мирных жителей в невыгодных условиях принимать решения и выставить кого-нибудь еще.

Информация

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