4. Не совсем уверен, что корректно делать Select в одном треде, а обрабатывать SelectionKey в другом (ClientHandler). Мне кажется keys, они валидны только до следующей операции select, посему обрабатываться должны в том же треде.
5. Ваш сервер не обрабатывает отсоединение клиентов. Именно тут начнутся танцы с бубном. Наперед скажу, что не гарантируется, что для каждого отвалившегося клиента селектор вернет key.isValid()=false. Поэтому дисконнект нужно делать по IOException.
Кроме того, есть клиенты, которые при потере связи не пошлют TCP CLOSE-WAIT, и на сервере они останутся висеть бесконечно долго. Timeout возникнет только, если в буфере есть что послать клиенту. Поэтому чтобы такого не произошло, нужно пинговать клиента.
1. SocketChannel.read() в общем не гарантирует Вам, что будет прочитанно именно 16 байт. Хотя это и маловероятно, но зависит от низлежащих сетевых протоколов, и полагнаться на это не стоит. Теоретически сетевой пакет может быть раздроблен на два. Поэтому надо читать в цикле, пока ByteBuffer не будет заполнен.
2. Точно также SocketChannel.write() не гарантирует, что все будет записано — зависит от состояния буфера. В общем случае пакеты нужно писать циклически и удалять, когда remaining=0. Если буфер заполнен, селектор автоматически не будет возвращать writeable-ключи до тех пор, пока данные из буфера не прососутся по каналу.
3. Несмотря на то, что buffer — это val, он будет создаваться каждый раз, как мы что-то читаем. Лучше его создать наверху один раз, используя при этом ByteBuffer.allocateDirect()
Агрессивные рекламные кампании в моде. Не так давно на Oracle.com на странице business middleware видел крупный баннер: «While IBM delivers the past Oracle delivers the future». ИЧХ, они на 100% правы.
Недостаток ArrayList в том, что он оперирует объектами, и для примитивов его использовать очень неэффективно, хотя в реальной жизни это часто требуется. Вот пара библиотек, которые оперируют коллекциями из примитивов:
Основой всех систем являются две сущности: состояния и операции. Состояния обычно описываются структурой данных: иерархической, реляционной и т.д. Операции — это действия над данными, т.е. то, что изменяет состояние. Основная проблема всех времен и народов — как максимально локализовать данные и код, который оперирует с этими данными, в отдельные и независимые куски (свободные от нелюбимых side-effects). Отсюда берет начала куча парадигм программирования.
В частности инкапсуляция в ООП дает неплохую изоляцию: методы внутри объекта оперируют только с состояниями этого объекта. Но у него есть определенные проблемы, например расширить функциональность объекта типа «список» можно только при помощи наследования. Операции, затрагивающие изменения состояний многих объектов, требуют сложных архитектурных решений. И пр…
Функциональное программирование практически полностью отделяет мясо (код) от костей (данных). Структура данных содержится отдельно и как правило содержит методы, позволяющие сделать выборку и изменить состояние. Над выборкой вычисляется некая сложная функция, а затем состояние изменяется в соответствии с результатом. Функциональным языком можно считать используемый всеми SQL. Преимущество функционального подхода в работе с данными в том, что инъектировать свой код в структуру данных проще, чем осуществлять ее итеративный обход, дергая данные по одному. Структура сама знает как себя эффективно обходить.
Тем не менее ФП было бы несправедливо называть отдельной и независимой парадигмой. Скорей это некий метод или прием, который может использоваться для перехода от императивного стиля описания к декларативному.
Проекты, зависящие от гуру создаются от элементарной лени и жадности начальства. Основная опасность гуру состоит в том, он не гнушается работы. Очень быстро он овладевает технической стороной проекта, занимает в разработке лидирующее положение и все архитектурные решения проходят через него. Затем, видя неэффективность остальных разрабочиков на фоне гуру, начальству приходит блестящая идея сэкономить на них, и команду сокращают.
После этого начальство, живя припеваючи, постепенно начинает отстраняться от дела. Постепенно вся техническая сторона и весь процесс разработки становится в полной ответственности этого гуру. Начальство теперь интересуют только требует сроки сдачи и коммерческая сторона. Еще бы! Иметь такую золушку: даешь задание, а через некоторое время — результат без лишних проблем.
Но и это еще не все. Постепенно гуру начинают сплавлять часть менеджерской работы. Клиент начинает консультироваться напрямую с ним, он начинает сам делать коммерческие предложения, реализовывать собственные идеи. Начальство требует лишь отчетность в цифрах. И очень скоро собственные притязания гуру берут верх и он просит начальство поделиться с ним результатом своей работы. Если начальство неадекватное и плещет руками «да кто ты такой! у нас нет незаменимых!», то развязки бывают печальные. Вплоть до того, что гуру уводит клиентов и разработчиков и открывает свое дело.
Самым лучшим вариантом разрешения подобных проблем является система поощрений ввиде акций собственной компании. Это во-первых, связывает человека с компанией, а во-вторых, сильно мотивирует его. Поэтому в штатах технический директор — практически всегда один из акционеров. Вывод: не надо жадничать! Если Вы зависите от человека — поделитесь с ним.
P.S. был случай, когда шеф повару одного очень известного в городе ресторана сделали более выгодное предложение и он решил уйти. И владелец ресторана, чтобы удержать его, отдал ему 20% своего бизнеса. И если бы он не поделился и заменил повара, ресторан скатился бы во второсортную харчевню каких сотни.
P.P.S. я не имел ввиду тех «гуру», которые слабали кучу одному им понятного быдлокода и твердят, что теперь от них зависит все.
Да, Alloy был мой любимый laf, тока ему антиалайсинга шрифтов не хватало. Да, стоит демку с .jnlp или аплетом сунуть, чтобы сразу его можно было «пощупать». И спасибо за старания.
При чрезмерном злоупотреблении рудиментарными тестами наступает момент, когда поддержка самих тестов становится многократно сложнее самого кода. Это когда Вы делаете изменение в одном месте в коде, и перелопачиваете 50 тестов.
Возможно это мое imho, но основную проблему Scala я вижу в излишней математичности. Язык кажется сложным, потому что он пестрит математическими выражениями. Практически каждый элемент требует знаний и навыков теоретико-множественного исчисления, тогда как программисты больше склонны к алгоритмическому мышлению и далеко не все имеют математическое образование. А основные понятия языка и методы определены в его API, поэтому учить Scala — это не только учить язык, но и все, что идет под scala._. В итоге язык становится оторванным от реальности и представляющим исключительно академический интерес теоретикам программирования, использующим его как площадку для своих паттернов.
Проблема резко усугубляется перегрузкой операторов. Разработчики языка не могут жить спокойно, чтобы лишний раз не наполнить какую-нибудь закорючку сакральным смыслом, вместо того, чтобы написать имя метода на христианском английском. Тем же самым грешат писатели библиотек. В итоге смысл кода становится абсолютно не ясным, если перед глазами нет соответствующего ScalaDoc. Апогей подобного маразма — это тот самый знаменитый Lift.
Синтаксический полиморфизм языка приводит к тому, что целью становится краткость написания взамен понятности.
Еще одна особенность — это повсеместное использование DSL в библиотеках. Хорошо это или плохо — тема отдельного разговора.
Если сравнивать Scala с Groovy, то последний, обладая схожими возможностями, при этом являясь динамическим, т.е. «недоязыком», покрывает Scala в удобстве использования, потому как более-менее пытается следовать Java-way. Сравните, например, внешне скрипт на Gradle и на т.н. «Simple Build Tool»… ;)))
Где-то я видел, что коментарий в коде должен отвечать на вопрос «зачем?», но не на вопрос «как?». Последнее должно быть понятно из кода. Моделирование не есть плохо. Нужно лишь, чтобы модель не была вселенски универсальной и не выходила из области задачи.
Автор упускает огромную группу людей — либюзеров, которые для достижения результата не заморачиваются, а подключают либу мегов на N-цать, зато в которой есть Tuple2 для возвращения двух значений функции. Они не изобретают, они пользуются чужими изобретениями и паттернами. Таких большинство.
Вторыми по списку идут быдлокодеры. Они всегда решают задачу влоб теми нехитрыми средствами, которые осилили овладеть. В итоге код дублируется, триплируется, функционал смешивается в кашу, и наступает момент, когда любое изменение влечет за собой гору отвалившегося функционала. И чтобы изменить что-то, надо перелопатить код в 10 местах.
Третья активно нарастающая группа — это быдлотестеры. Они не понимают для чего нужны тесты, но знают, что TDD — это модно. Поэтому пишут тесты абсолютно для всего — даже геттеров и сеттеров.
А изобретателей-«нубов» на самом деле осталось очень мало. Честь им и хвала! Все должны через это пройти.
P.S. Есть и психологическое объяснение статьи: когда автор был нубом, он работал за идею (интерес). Когда же он повзрослел, он тупо стал работать за деньги. Поэтому все идейные вещи ему стали казаться глупыми: платят не за идею, а за результат, поэтому че напрягаться?
Почему-то автор не упомянул, что китайский технологический бум во многом обязан отсутвию всяких ограничений на патенты. Пока америкосы судятся, Китайцы штампуют и продают. Вы заказываете штамповку продукта в Китае, а через некоторое время они уже собирают свои аппараты на вашей схеме. И тем не менее Вы получаете преимущество перед ними и конкурентами на один цикл производства, первым выбросив на рынок инновационный продукт. После этого разработки становятся достоянием всех (посредством реверс-инжиниринга, шпионажа и т.д.). А дальше история повторяется. Поэтому ваши вклады в разработку должны окупаться в течение одного цикла производства. У условиях постоянного устаревания продукции это наиболее естественно.
С другой стороны, в современная экономика ориентирована уже не столько на продукты, сколько на сервисы. Китайцы тоже штампуют аппараты не хуже айфона. Только покупают все-равно айфоны, потому как индустрия Эпл не ограничивается одними телефонами.
Решение простое: отменить патентное законодательство, и общество очень быстро найдет другие методы регулирования. В законодательном порядке контролировать только имплементацию идеи, но не саму идею. Например, если Вы произвели копию айфона или «позаимствовали» чужой код, то Вас вправе засудить. Если же Вы реализовали весь функционал айфона на собственной платформе, или написали собственную реализацию алгоритма сжатия mp3, то это ваше право.
Симпатичный LaF. Чем-то напоминает Alloy. Вставьте пожалуйста на сайт онлайн демо например с SwingSet2.
А для Graphics2D самая лучшая на сей момент библиотека — JavaFX :)
Отлично! Очень понравилась ваша идея использовать DSL для задания лейаута. Сам использую MigLayout (считаю его полностью удовлетворяющим любые потребности), но его проблема в читабельности. Интересно было бы приготовить подобный DSL для MigLayout.
Хоть Oracle и ассоциируется с одноименной БД, но у него есть другие не менее серьезные продукты. Middleware от Oracle действительно отличное: особенно все, что касается BPM и ESB. Продукты IBM Websphere даже близко не подошли по функционалу к линейке от Oracle. Я бы назвал даже лучшим на сегодняшний день решением.
Оракловские БД-решения начинают быть выгодными в использовании только начиная с определенного объема (сложность решения + денежный оборот), когда компания может позволить себе в комплекте с лицензиями содержать администратора. Большинство же проектов не используют и половины функционала этой БД и вполне могли бы обойтись более дешевыми решениями. Но, чаще всего Oracle выбирают потому что: а) деньги не свои, б) есть откат, в) я ничего другого не знаю.
На Scala есть знаменитый Lift. Впринципе, разрабатывать еще быстрее, чем на Play, если ты разработчик этого самого Lift )) Для новичков же настолько неудобоварим, что заморачиваться даже не стоит. Как впрочем и практически любая либа на scala, пестрящая закорючками и DSL-ями.
Вы лукавите. Причины почему компании предпочитают аутсорсинг всего две:
1. Возможность получить откат
2. В офшоре или неаршоре цены меньше
> авторы пишут, что все компании, которые хотят выжить в условиях глобальной конкуренции, скоро перейдут на модель глубокой и узкой специализации
Отчасти правы, отчасти лукавят. Посмотрите на гигантов типа Google. Очень узкая специализация! Проглатывают рынки и другие компании как орехи. Авторы намекают на то, что для мелких сошек в будущем еды на рынке не останется, им придется выживать, делясь баблом с другими.
Вообще реально дела обстоят не так красиво, как написано. Рекрутинговые компании надут вам кого угодно, только не специалиста. Происходит это потому, что в крутых спецах они просто не заинтересованы: их не продать по адекватной цене (клиент привык смотреть на цену, а не на крутость). Более того, спец. претендует на место как минимум архитектора или тимлида, где клиент предпочитает видеть своего человека.
Если же целиком отдать разработку на аутсорсинг, то очень быстро провайдер начнет вить из клиента веревки, заламывая цену и мотивируя тем, что переход на другого провайдера/систему вам обойдется дороже.
Так что, фиг его знает. Аутсорсинг поможет, когда занятость непостоянна. Если же имеется постоянный объем работы, лучше нанимать специалистов в компанию.
Не совсем понял Ваше высказвание про сеть и байты. Сериализация структур данных — отдельная задача, не связанная с их представлением в памяти машины. Формат и протокол передачи между терминалами на данном уровне OSI четко согласуется и иногда стандартизируется в RFC.
Кроме того, десериализация строк в формате (int)(array) реализовывать в разы проще и надежнее, чем NULL-ending, т.к. буфер нужной длины резервируем сразу.
Про парсинг строк неизвестной длины: здесь Вы путаете концепт строки и символьного потока. Строка — это объект в памяти фиксированной и заранее известной длины, допускающий доступ к любому символу по смещению. Поток — объект неизвестной длины, допускающий в общем случае только последовательный посимвольный доступ. Конечные автоматы работают именно с символьными потоками.
Видимо Керниган и Ричи в свое время тоже мыслили о строках исключительно как о символьных потоках.
Отсутствие наличия бозона Хиггса воодушевит физиков совсем по другой причине. Срочно потребуется новая теория, на проверку которой будут необходимы суммы с 9 нулями…
4. Не совсем уверен, что корректно делать Select в одном треде, а обрабатывать SelectionKey в другом (ClientHandler). Мне кажется keys, они валидны только до следующей операции select, посему обрабатываться должны в том же треде.
5. Ваш сервер не обрабатывает отсоединение клиентов. Именно тут начнутся танцы с бубном. Наперед скажу, что не гарантируется, что для каждого отвалившегося клиента селектор вернет key.isValid()=false. Поэтому дисконнект нужно делать по IOException.
Кроме того, есть клиенты, которые при потере связи не пошлют TCP CLOSE-WAIT, и на сервере они останутся висеть бесконечно долго. Timeout возникнет только, если в буфере есть что послать клиенту. Поэтому чтобы такого не произошло, нужно пинговать клиента.
2. Точно также SocketChannel.write() не гарантирует, что все будет записано — зависит от состояния буфера. В общем случае пакеты нужно писать циклически и удалять, когда remaining=0. Если буфер заполнен, селектор автоматически не будет возвращать writeable-ключи до тех пор, пока данные из буфера не прососутся по каналу.
3. Несмотря на то, что buffer — это val, он будет создаваться каждый раз, как мы что-то читаем. Лучше его создать наверху один раз, используя при этом ByteBuffer.allocateDirect()
trove.starlight-systems.com/
pcj.sourceforge.net/
В частности инкапсуляция в ООП дает неплохую изоляцию: методы внутри объекта оперируют только с состояниями этого объекта. Но у него есть определенные проблемы, например расширить функциональность объекта типа «список» можно только при помощи наследования. Операции, затрагивающие изменения состояний многих объектов, требуют сложных архитектурных решений. И пр…
Функциональное программирование практически полностью отделяет мясо (код) от костей (данных). Структура данных содержится отдельно и как правило содержит методы, позволяющие сделать выборку и изменить состояние. Над выборкой вычисляется некая сложная функция, а затем состояние изменяется в соответствии с результатом. Функциональным языком можно считать используемый всеми SQL. Преимущество функционального подхода в работе с данными в том, что инъектировать свой код в структуру данных проще, чем осуществлять ее итеративный обход, дергая данные по одному. Структура сама знает как себя эффективно обходить.
Тем не менее ФП было бы несправедливо называть отдельной и независимой парадигмой. Скорей это некий метод или прием, который может использоваться для перехода от императивного стиля описания к декларативному.
После этого начальство, живя припеваючи, постепенно начинает отстраняться от дела. Постепенно вся техническая сторона и весь процесс разработки становится в полной ответственности этого гуру. Начальство теперь интересуют только требует сроки сдачи и коммерческая сторона. Еще бы! Иметь такую золушку: даешь задание, а через некоторое время — результат без лишних проблем.
Но и это еще не все. Постепенно гуру начинают сплавлять часть менеджерской работы. Клиент начинает консультироваться напрямую с ним, он начинает сам делать коммерческие предложения, реализовывать собственные идеи. Начальство требует лишь отчетность в цифрах. И очень скоро собственные притязания гуру берут верх и он просит начальство поделиться с ним результатом своей работы. Если начальство неадекватное и плещет руками «да кто ты такой! у нас нет незаменимых!», то развязки бывают печальные. Вплоть до того, что гуру уводит клиентов и разработчиков и открывает свое дело.
Самым лучшим вариантом разрешения подобных проблем является система поощрений ввиде акций собственной компании. Это во-первых, связывает человека с компанией, а во-вторых, сильно мотивирует его. Поэтому в штатах технический директор — практически всегда один из акционеров. Вывод: не надо жадничать! Если Вы зависите от человека — поделитесь с ним.
P.S. был случай, когда шеф повару одного очень известного в городе ресторана сделали более выгодное предложение и он решил уйти. И владелец ресторана, чтобы удержать его, отдал ему 20% своего бизнеса. И если бы он не поделился и заменил повара, ресторан скатился бы во второсортную харчевню каких сотни.
P.P.S. я не имел ввиду тех «гуру», которые слабали кучу одному им понятного быдлокода и твердят, что теперь от них зависит все.
Проблема резко усугубляется перегрузкой операторов. Разработчики языка не могут жить спокойно, чтобы лишний раз не наполнить какую-нибудь закорючку сакральным смыслом, вместо того, чтобы написать имя метода на христианском английском. Тем же самым грешат писатели библиотек. В итоге смысл кода становится абсолютно не ясным, если перед глазами нет соответствующего ScalaDoc. Апогей подобного маразма — это тот самый знаменитый Lift.
Синтаксический полиморфизм языка приводит к тому, что целью становится краткость написания взамен понятности.
Еще одна особенность — это повсеместное использование DSL в библиотеках. Хорошо это или плохо — тема отдельного разговора.
Если сравнивать Scala с Groovy, то последний, обладая схожими возможностями, при этом являясь динамическим, т.е. «недоязыком», покрывает Scala в удобстве использования, потому как более-менее пытается следовать Java-way. Сравните, например, внешне скрипт на Gradle и на т.н. «Simple Build Tool»… ;)))
Автор упускает огромную группу людей — либюзеров, которые для достижения результата не заморачиваются, а подключают либу мегов на N-цать, зато в которой есть Tuple2 для возвращения двух значений функции. Они не изобретают, они пользуются чужими изобретениями и паттернами. Таких большинство.
Вторыми по списку идут быдлокодеры. Они всегда решают задачу влоб теми нехитрыми средствами, которые осилили овладеть. В итоге код дублируется, триплируется, функционал смешивается в кашу, и наступает момент, когда любое изменение влечет за собой гору отвалившегося функционала. И чтобы изменить что-то, надо перелопатить код в 10 местах.
Третья активно нарастающая группа — это быдлотестеры. Они не понимают для чего нужны тесты, но знают, что TDD — это модно. Поэтому пишут тесты абсолютно для всего — даже геттеров и сеттеров.
А изобретателей-«нубов» на самом деле осталось очень мало. Честь им и хвала! Все должны через это пройти.
P.S. Есть и психологическое объяснение статьи: когда автор был нубом, он работал за идею (интерес). Когда же он повзрослел, он тупо стал работать за деньги. Поэтому все идейные вещи ему стали казаться глупыми: платят не за идею, а за результат, поэтому че напрягаться?
С другой стороны, в современная экономика ориентирована уже не столько на продукты, сколько на сервисы. Китайцы тоже штампуют аппараты не хуже айфона. Только покупают все-равно айфоны, потому как индустрия Эпл не ограничивается одними телефонами.
Решение простое: отменить патентное законодательство, и общество очень быстро найдет другие методы регулирования. В законодательном порядке контролировать только имплементацию идеи, но не саму идею. Например, если Вы произвели копию айфона или «позаимствовали» чужой код, то Вас вправе засудить. Если же Вы реализовали весь функционал айфона на собственной платформе, или написали собственную реализацию алгоритма сжатия mp3, то это ваше право.
А для Graphics2D самая лучшая на сей момент библиотека — JavaFX :)
Оракловские БД-решения начинают быть выгодными в использовании только начиная с определенного объема (сложность решения + денежный оборот), когда компания может позволить себе в комплекте с лицензиями содержать администратора. Большинство же проектов не используют и половины функционала этой БД и вполне могли бы обойтись более дешевыми решениями. Но, чаще всего Oracle выбирают потому что: а) деньги не свои, б) есть откат, в) я ничего другого не знаю.
1. Возможность получить откат
2. В офшоре или неаршоре цены меньше
> авторы пишут, что все компании, которые хотят выжить в условиях глобальной конкуренции, скоро перейдут на модель глубокой и узкой специализации
Отчасти правы, отчасти лукавят. Посмотрите на гигантов типа Google. Очень узкая специализация! Проглатывают рынки и другие компании как орехи. Авторы намекают на то, что для мелких сошек в будущем еды на рынке не останется, им придется выживать, делясь баблом с другими.
Вообще реально дела обстоят не так красиво, как написано. Рекрутинговые компании надут вам кого угодно, только не специалиста. Происходит это потому, что в крутых спецах они просто не заинтересованы: их не продать по адекватной цене (клиент привык смотреть на цену, а не на крутость). Более того, спец. претендует на место как минимум архитектора или тимлида, где клиент предпочитает видеть своего человека.
Если же целиком отдать разработку на аутсорсинг, то очень быстро провайдер начнет вить из клиента веревки, заламывая цену и мотивируя тем, что переход на другого провайдера/систему вам обойдется дороже.
Так что, фиг его знает. Аутсорсинг поможет, когда занятость непостоянна. Если же имеется постоянный объем работы, лучше нанимать специалистов в компанию.
Кроме того, десериализация строк в формате (int)(array) реализовывать в разы проще и надежнее, чем NULL-ending, т.к. буфер нужной длины резервируем сразу.
Про парсинг строк неизвестной длины: здесь Вы путаете концепт строки и символьного потока. Строка — это объект в памяти фиксированной и заранее известной длины, допускающий доступ к любому символу по смещению. Поток — объект неизвестной длины, допускающий в общем случае только последовательный посимвольный доступ. Конечные автоматы работают именно с символьными потоками.
Видимо Керниган и Ричи в свое время тоже мыслили о строках исключительно как о символьных потоках.