• Практика Java - чем заняться?

    @bromzh
    Drugs-driven development
    Ну сейчас ява используется в 3-х больших областях: андроид, десктоп и веб.

    И имхо с java лучше не начинать писать под веб. Технологий там куча, везде свои фишки и тонкости.

    Начнёшь писать на JavaEE стеке, будешь (скорее всего) долго разбираться какой сервер лучше использовать, какие есть реализации API, как их подключить и использовать, будешь недоумевать, почему вдруг NullPointerException, потом увидишь, что это из-за того, что всякие зависимости EJB не внедрились, транзакции откатились, LazyLoad в моделях не работает и поля id в них не хотят сами генериться.

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

    Play 2 оооочень долго собирается, да и он больше для скалы, нежели для явы.

    Есть всякие микрофреймворки, типа спарка.

    Особняком, наверное, стоит vert.x с поддержкой кучи языков, неблокирующего IO, уже готовым к использованию глобальным Event Bus и прочими плюшками.

    Помимо этого, есть ещё огромное количество всяких фреймворков и библиотек, которые работают поверх/вместо какой-то части в вышеописанных проектах. Они могут быть несовместимыми между собой, или быть независимыми. Так что ты сможешь сам себе собрать фреймворк из запчастей.
    Также, есть фреймворки для JVM-языков, например Lift, Play 2, Spray для Scala, Grails для Groovy и т.д.

    Под андроид меньше такого разброса в технологиях, возможно проще будет начать с него.

    А десктопные приложения на яве - это обычно всякие огромные ИДЕ и майнкрафты. В одиночку всё это писать трудно, да и спрос тут меньше.

    Так что спроси себя, нужна ли тебе ява, и если нужна, то для чего. Всё-таки надо сперва определиться с направлением, а потом выбирать нужный инструмент.
    Ответ написан
    2 комментария
  • Нужна ли собственная иерархия ошибок в Java?

    @bromzh
    Drugs-driven development
    Есть 2 противоположных мнения на этот счёт, и там и там есть свои плюсы и минусы.

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

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

    @bromzh
    Drugs-driven development
    Ну это допустимо там, где нужно использовать именно такую структуру. Например, я в таком классе хранил сообщения-команды: в строковом поле - название команды, в мапе - её аргументы. Имена аргументов, их тип и количество для всех команд могут быть разными (и вложенными на несколько уровней), поэтому просто поля не подходят. При этом, вся эта штука легко (де)сериализуется. Да, если нужен нестандартный маппинг в/из JSON (или любой другой формат), придётся потрудится, но у меня такой проблемы не возникало.

    Так что просто используй там, где это реально нужно.

    PS ещё можно использовать груви и, например, Expando. Плюсы в том, что там будут настоящие поля, с доступом через точку и т.д.
    def foo = new Expando(a: 1, b: "2", c: [3, 4])
    foo.d = "value"
    foo.e = "another value"
    println foo
    
    Expando bar = [f: 5, g: "spot"]
    bar.e = foo
    println bar

    {a=1, b=2, c=[3, 4], d=value, e=another value}
    {f=5, g=spot, e={a=1, b=2, c=[3, 4], d=value, e=another value}}
    Ответ написан
    Комментировать
  • Множественное наследование не нарушает ООП?

    @bromzh
    Drugs-driven development
    Не нарушает, так как до сих пор нет единого мнения, что такое ООП и какая из его реализаций самая правильная. Даже те 4 принципа, про которые все любят говорить (инкапсуляция, наследование, полиформизм, абстракция) не являются ни исключительными для ООП (так как встречаются в любых других языках), ни необходимым набором правил, которым должен удовлетворять ОО язык, так как многие языки хоть и являются ОО, но в них могут отсутствовать наследование (прототипное ООП) и инкапсуляция в явном виде (для сокрытия внутренностей тогда используют замыкания или вообще не парятся). Полиформизм и абстракция присущи вообще всем языкам.

    Просто надо понимать, где стоит использовать множественное наследование в том или ином его варианте, где оно излишне, а где вообще не нужны объекты и классы.
    Ответ написан
    1 комментарий
  • Как заработать на javascript библиотеке?

    @bromzh
    Drugs-driven development
    Можно сделать, как тут dhtmlx.com
    Есть урезанная версия с GPL-лицензией. Все проекты, использующие эту версию должны тоже быть GPL. Если хочется больше фич и другую лицензию - плати.
    Только в приведённом примере действительно крутая и востребованная вещь, бесплатных аналогов которой нет. Если у тебя такая же ситуация - попробуй продавать, вдруг получится.
    Ответ написан
    Комментировать
  • Зачем нужны аксессоры для членов класса если эти члены можно делать публичными?

    @bromzh
    Drugs-driven development
    Используются они не совсем для инкапсуляции, ведь аксессоры её как бы нарушают.

    Используют их, чтобы была возможность запихнуть в аксессоры дополнительную логику (например, логгирование, валидация и прочие штуки), не переписывая весь код. Для доступа к полям везде пишешь setField/getField, и при необходимости, логику добавляешь в эти методы. Классы, использующие поля не меняются, а вот поведение может меняться.
    Если же поля константные/статические, то нет особого смысла делать их private, пиши public/protected и не парься.
    Ответ написан
    1 комментарий
  • Какой сервер очередей использовать?

    @bromzh
    Drugs-driven development
    Что значит "одновременно"? 5 сервов должны начать делать 1 задачу в одинаковое время? Смахивает на задачу синхронизации стрелков, которую надо реализовать через очередь сообщений.
    Ответ написан
  • WEB - приложение Java. Какой нужен стек технологий для джуна?

    @bromzh
    Drugs-driven development
    Либо путь JavaEE: JSF, JPA, EJB, JAX-RS/WS, etc
    Либо путь спринг: Spring AOP, Spring Data, Spring MVC, etc
    Хотя зачастую надо знать оба варианта. Помимо этого, всякие основы типа сервлетов, JDBC, JSP, DI, JUnit, Java Core и т.д.
    Ответ написан
    Комментировать
  • Веб-приложение написано. Что дальше?

    @bromzh
    Drugs-driven development
    .
        _______                         ________
       |       |                       |        |
       |   n   | -> site1.com ->|  |-->| uwsgi1 |-->|   |--> app1 for site1
       |   g   |                |  |   |________|   |   |
    -->|   i   | -> site2.com ->|->|    ________    |-->|--> app2 for site2
       |   n   |                |  |   |        |   |   |
       |   x   | -> site3.com ->|  |-->| uwsgi2 |-->|   |--> app3 for site3
       |_______|                       |________|

    Это примерная общая структура деплоя нескольких питоновских wsgi-приложений.

    1) Nginx ставят вперёд в основном для:
    a) отдачи статики
    b) балансировки нагрузки
    Он быстрый, надёжный, статику отдаёт лучше, чем uwsgi, плюс, можно настроить всякие https. Однако, nginx не умеет запускать питоновские приложения. Для этого он проксирует запрос на wsgi-совместимый сервер.
    2) В wsgi-сервере запускаются все доступные питоновские приложения. Uwsgi можно довольно гибко конфигурировать, посмотри оф доки. Одной из классных штук является emperor-mode: uwsgi может сканировать папку на наличие конфигов и автоматом подхватывать питоновские приложения. Обычно создаётся 1 папка, а каждое wsgi-приложение просто делает симлинк с конфигом в эту папку.
    3) Uwsgi можно запустить как через обычный tcp-сокет, так и через unix-сокет. Что ты выберешь, то и надо будет указывать в конфиге nginx
    4) Uwsgi лучше запускать через supervisord. Он позволяет перезапускать приложение при падении, гибко настраивать запуск похожих демонов, перенаправлять stdout/stderr, настраивать переменные окружения и т.д.. Опять же, смтри доки. В конфиге прописываешь, как у тебя будет запускаться uwsgi и какой конфиг/папку с конфигами uwsgi будет читать.
    5) Если сервер имеет N ядер, то имеет смысл запустить N-1 штук процессов uwsgi на разных портах/с разными sock-файлами. Тогда nginx сможет балансировать нагрузку между ними. Запускать группу процессов можно либо через супервизор, либо задав настройки в конфиге самого Uwsgi, тут как удобнее. Разница будет лишь в том, что в первом варианте при падении одного uwsgi, остальные будут жить, а во втором случае, перезапустятся все процессы uwsgi (скорее всего).
    6) Не надо описывать конфиг каждого uwsgi-сервера в nginx отдельно, для группы есть upstream.
    7) Насколько я понимаю, если питоновское приложение 1, то лучше запустить несколько экземпляров uwsgi через супервизор, если их много - запускать несколько штук uwsgi в emperor-mode.

    Я точно не помню синтаксис конфигов, но должно получиться что-то похожее на такое:
    # Конфиг supervisor:
    [program:uwsgi]
    numprocs = 3 (для 4-х ядерного серва)
    command = uwsgi --emperor /path/to/conf/dir --socket /tmp/uwsgi/uwsgi-%(process_num).sock


    Либо так:
    # Конфиг  uwsgi: /path/to/conf/default.ini
    [uwsgi]
    socket = /tmp/sockets/uwsgi-%(vassal_name).sock
    
    # Конфиг супервизора
    [program:uwsgi]
    command = uwsgi --emperor /path/to/conf/dir ----vassals-include path/to/conf/default.ini


    В любом случае, всё это дело потом легко добавляется в nginx:
    upstream backend {
        server localhost:8001;  #для tcp-сокетов
        server localhost:8002;
    
        server unix:/tmp/uwsgi/uwsgi-1.sock; # для unix-сокетов
        server unix:/tmp/uwsgi/uwsgi-2.sock;
    }
    # А потом просто проксируешь на эту штуку:
    server {
        location / {
            listen       80;
            server_name site1.com;
            proxy_pass http://backend;
        }
    }
    
    server {
        location / {
            listen       80;
            server_name site2.com;
            proxy_pass http://backend;
        }
    }


    PS Возможно, если количество питоновских приложух сопоставимо с количеством процессоров, то может будет лучше настроить так: 1 экземпляр uwsgi на 1 приложение. Но я точно не знаю, имеет ли это смысл, надо читать внимательно доки uwsgi и nginx.
    Ответ написан
    2 комментария
  • Как в API приложения разрабатываемое на Flask добавить получение большого бинарного файла?

    @bromzh
    Drugs-driven development
    Nginx
    Ответ написан
    Комментировать
  • Как реализовать хранение JSON объекта внутри JSON?

    @bromzh
    Drugs-driven development
    Кавычки экранируй
    {
        "foo": "{\"inner\": [1, true, \"val\"]}",
        "bar": 2
    }
    Ответ написан
    Комментировать
  • Аналог composer'а для python?

    @bromzh
    Drugs-driven development
    Самое простое - хранить список в файле requirements.txt (имя может быть любым, но так принято):
    Flask==0.10.1
    Flask-Admin>=1.0.0

    Версии можно указывать разнообразные, в том числе, определённые коммиты/ветки/теги из систем контроля версий.
    Установить зависимости:
    pip install -r requirements.txt --upgrade
    в папке с этим файлом

    Ещё вариант описать зависимости в setup.py, но это больше для библиотек нужно.
    Ответ написан
    Комментировать
  • Для каких проектов используется node js?

    @bromzh
    Drugs-driven development
    1) Нет. Обычный сайт - это одно короткое соединение на один запрос к серверу. Время жизни соединения ограничено одним request (пришёл запрос - соединение создалось, отдали ответ - оно умерло). Выигрыша по сравнению с обычными синхронными фреймворками нет. А так как нода - однопоточная, то может случиться так, что соединение, в котором выскочила ошибка убьёт всё приложение.
    2) Нет. Бери любой развитый MVC-фреймворк на любом языке, так легче.
    3) Для тех, где нужна асинхронность: прикрутить вебсокет-чат для готового сайта, работа с очередями сообщений (чтобы принимать их в неблокирующем режиме), рассылка уведомлений, запись в БД без блокировок, и т.д. Т.е. обычно его используют там, где надо держать много одновременно открытых соединений, каждое из которых не требует много процессорного времени, но может тормозить из-за IO.
    Ответ написан
    8 комментариев
  • Как приготовить Java SE + MVC + SWING + DependencyInjection/IoC?

    @bromzh
    Drugs-driven development
    Что значит, по всем канонам ООП? Java весьма далека от правильного ООП подхода хотя бы потому, что там не всё есть объект. Да и в рамках самой Java есть несколько разных стилей. Надо писать не по канонам, а исходя из задачи.

    1) 1, 2. Это классический MVC, с активными моделями, в которых вся бизнес-логика. При обновлении модели она оповещает все виды-слушатели. При событии во view, он вызывает оповещает контроллер, тот вызывает нужные методы модели. В вебе MVC неправильное.
    2) Зачем? Ошибка многих начинающих джавистов - использование DI там, где это не нужно. В мире JavaEE DI - частое явление, потому что там бины управляемые: сервер приложений запускает приложуху в контейнере, сам регулирует контекст и время жизни бинов, может предоставлять свои реализации API и т.д. А в свинг-приложениях ничего такого нет, программа запускается через main-метод, все реализации API включаются в итоговый jar, время жизни бинов отслеживать не надо... Вполне можно обойтись простыми конфигами + фабриками/билдерами, чтобы регулировать зависимости. Хотя если очень хочется, то вот, например.
    Ответ написан
  • Как в python передать параметр как list of objects?

    @bromzh
    Drugs-driven development
    Ты звёздочку забыл
    table = GenTable('city', 100, *field_list)
    Ответ написан
    1 комментарий
  • Какая стандартная библиотека для работы с JSON в Java?

    @bromzh
    Drugs-driven development
    Никакая. Есть набор спецификаций для работы с json - JSR-000353
    Есть несколько её реализаций. Я совeтую Gson. Он хорошо умеет работать с дженериками, и, в отличие от jackson, он не разросся в монстра, который занимается обработкой большого количества форматов. Там только json.
    Ответ написан
    Комментировать
  • Скажите пожалуйста, кто что знает про JSF?

    @bromzh
    Drugs-driven development
    JSF - он для внутренних сетевых проектов, где канал передачи данных - это локальная сеть (поэтому так мало общедоступных проектов на нём).
    Для него есть много дополнений, наборов готовых компонентов (1, 2, 3). Довольно удобно строить сложные отзывчивые интерфейсы, он сам по-себе компонентный и хорошо интегрируется с JavaEE-приложениями.

    Но для интернет-сайтов он довольно плохо подходит.
    Ответ написан
    Комментировать
  • Java Gson deserialization. Как обработать интерфейсы?

    @bromzh
    Drugs-driven development
    Пишешь свой десериализатор/адаптер типа/создатель инстанса.
    https://sites.google.com/site/gson/gson-user-guide...
    Потом регистрируешь всё это, когда создаёшь Gson объект через GsonBuilder
    Ответ написан
    Комментировать
  • Как сделать update в flask sqlalchemy?

    @bromzh
    Drugs-driven development
    Можно написать самому миграцию. Если что пойдёт не так - откатишься.
    Для фласка есть плагин (который есть обёртка над alembic)
    Ответ написан
    Комментировать