• Книга о том как правильно должен работать программист?

    un1t
    @un1t
    Чед Фаулер "Программист фанатик"
    Джоэл Спольски "Джоэл о программировании"
    Роберт Мартин "Идеальный программист"
    Том ДеМарко, "Вальсируя с Медведями: управление рисками в проектах по разработке программного обеспечения"
    Том ДеМарко "Человеческий фактор. Успешные проекты и команды"
    Роберт Гласс "Факты и заблуждения профессионального программирования"
    Игорь Савчук "Отъявленный программист. Лайфхакинг из первых рук"
    Питер Сейбел "Кодеры за работой. Размышления о ремесле программиста"
    Хант Эндрю, Томас Дэвид "Программист прагматик"
    Ответ написан
    1 комментарий
  • В каких случаях лучше использовать фрагменты, а в каких активити?

    @YuryBorodkin
    Android dev
    по своему опыту, использую фрагменты только в виде DialogFragment. Все.
    На счет передачи данных между активити - Parcelable чрезвычайно удобен. Либо класс сериализовать в жсон. Либо перегнать его в byte[]->Base64 строка->передать ч/з интент->Base64>new String();
    Да и некий bus для app-wide notifications нужен для любого мало мальски большого приложения... через него тоже можно данные гонять.
    Ответ написан
    3 комментария
  • В каких случаях лучше использовать фрагменты, а в каких активити?

    @alaershov
    Android-developer
    Если возникает требование закрыть полностью родительский экран, то стоит задуматься о том, что это, на самом деле, отдельный экран. Единственный легитимный случай, когда можно закрыть части родительского экрана - это диалог.
    Пердавать данные между Activity приложения, действительно, не всегда удобно. Однако поддержка такой связи между экранами позволит вам, например, открывать экран карты из совершенно другого места (например, Push-уведомления, или вообще другого приложения), используя тот же самый протокол, Extras в Intent. Это принцип организации Android-приложения. Слабо связанные между собой экраны-модули приложения. Для того, чтобы уйти на какой-то экран специально с целью вернуть оттуда данные, есть механизм startActivityForResult.
    Ответ написан
    4 комментария
  • Как добавить в БД (hibernate) элемент с внешним ключом без выборки для него объекта (по id)?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Если у тебя нет каскадирования при сохранении для BEntity.a, то тебе достаточно будет инициализировать объект класса AEntity с указанным id, большего для связывания и не требуется.

    Как вариант - в BEntity добавить поле aId, а BEntity.a сделать немодифицируемым:
    @Column(nullable = false)
        private Long aId;
    
        @ManyToOne
        @JoinColumn(name = "a_id", nullable = false, insertable = false, updatable = false)
        private AEntity a;


    В таком случае ты сможешь добавлять связь без заполнения поля. Связанная будет загружаться из БД при запросе, но не будет изменяться при сохранении, хотя это легко решается присвоением нового значения aId в сеттере a.

    Но ИМХО, если это всё делается в контексте REST-сервисов, то объект класса AEntity в объекте класса BEntity должен быть полностью заполнен.
    Ответ написан
    3 комментария
  • Как добавить в БД (hibernate) элемент с внешним ключом без выборки для него объекта (по id)?

    @guras256
    "легального" способа я не знаю и вряд ли он есть. смысл Jpa в том, что ты работаешь в объектной модели, а не с sql запросами.
    ты можешь присылать запрос с фронтенда в виде:
    {
      "name": "some name",
      "a": {
        "id": 1
      }
    }

    и все будет хорошо работать

    так же рекомендую сделать связь unidirectional, то есть поместить в A
    @JsonIgnore
        @OneToMany(mappedBy = "a")
        private List<BEntity> bs;


    в общем зависит от целей и необходимостей.
    Если ты хочешь получать именно id, то ты просто используешь инструмент не по назначению, бери myBatis и пиши sql.

    А если хочешь упороться, поставь transient поле в класс BEntity и перекладывай из него в AEntity -_- :
    @Entity
    @Table(name = "b")
    public class BEntity {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @ManyToOne
        @JoinColumn(name = "a_id", nullable = false)
        @JsonIgnore
        private AEntity a;
    
        @Transient
        private Long aEntityId;
    
        @Column(name = "name", nullable = false)
        private String name;
    }
    
    // получаешь ответ с фронденда:
    BEntity b = getBEntity();
    // Создаешь AEntity
    AEntity a = new AEntity();
    // запихиваешь в нее нужный id из транзаент поля
    a.setId(b.getAEntityId());
    //засовываешь А в Б
    b.setA(a);
    // можно сохранять


    но это вариант из разряда идиотизма

    в общем спрашивай, если будут еще вопросы
    Ответ написан
    5 комментариев
  • Насколько весомым является влияние знания регулярных выражений на трудоустройство PHP developer?

    Denormalization
    @Denormalization
    junior:
    /(.*)/
    middle:
    /[^a-c]+([y-z]+?)/
    senior:
    (?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*))*)?;\s*)
    Ответ написан
    5 комментариев
  • Какой лучший алгоритм для поиска оптимального пути через определённые точки?

    tsarevfs
    @tsarevfs
    C++ developer
    Очень похоже на динамику. Можно попробовать построить граф (полный?) из ключевых точек. Предпосчитать расстояние между вершинами по карте (A*).
    Далее вы либо можете либо просто придумать хитрые веса для ребер на основе длинны и рейтинга достопримечательностей в инцидентных вершинах. В этом случае нужен путь максимального веса.
    Иначе надо искать путь максимального веса с ограничением на длину. Наверняка люди не захотят обходить весь город. Вроде бы по ссылке описывается что-то подобное.
    Ответ написан
    3 комментария
  • Как настроить прозрачную kerberos-аутентификацию на Tomcat?

    sergey-gornostaev
    @sergey-gornostaev Автор вопроса, куратор тега Tomcat
    Седой и строгий
    Отвечу сам себе. Затык у меня возник потому, что одного Windows Authentication How-To мало. Кроме описанного в нём, нужно ещё в $CATALINA_HOME/<app-base>/<app-name>/WEB-INF/web.xml написать
    <security-constraint>
        <display-name>All users</display-name>
        <web-resource-collection>
          <web-resource-name>All requests</web-resource-name>
          <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <role-name>*</role-name>
        </auth-constraint>
      </security-constraint>
    
      <security-role>
        <description>All users</description>
        <role-name>*</role-name>
      </security-role>
    
      <login-config>
        <auth-method>SPNEGO</auth-method>
      </login-config>

    так как без авторизации не будет аутентификации. Кто бы мог догадаться. Valve, кстати, вписывается в $CATALINA_HOME/<app-base>/<app-name>/META-INF/context.xml в предельно элементарной форме
    <Valve className="org.apache.catalina.authenticator.SpnegoAuthenticator" />

    Но и это ещё не всё. Нужен ещё источник данных о пользователях - Realm. Я вписал его в $CATALINA_HOME/conf/server.xml в секцию host
    <Realm className="org.apache.catalina.realm.JNDIRealm"
                   connectionURL="ldap://pdc.domain.local:389"
                   alternateURL="ldap://bdc.domain.local:389"
                   connectionName="CN=tomcat,OU=Services,DC=domain,DC=local"
                   connectionPassword="qwerty"
                   referrals="follow"
                   userBase="OU=someou,DC=domain,DC=local"
                   userSearch="(sAMAccountName={0})"
                   userSubtree="true"
                   roleBase="OU=Security Groups,DC=domain,DC=local"
                   roleName="name"
                   roleSubtree="true"
                   roleSearch="(member={0})" />

    Потом я, правда, столкнулся с категорическим нежеланием 7-го tomcat'а общаться с 2012-ыми контроллерами домена. Пришлось пока SPNEGO заменить на FORM. Но в целом рецепт рабочий.
    Ответ написан
    1 комментарий