Blog head img
blame-canada (dude 2017-11-18 00:09:46 Общее)

https://pianokafe.com/

sadsad



https://solmire.com/midi-info/1308100/32381-blame-canada-mid.html

ACID + SOLID = Немного теории (dude 2017-11-14 06:20:18 Программирование)

1) ACID  

Требования , которые предъявляются СУБД (как транзакционной системе) по обеспечению целостности данных.

Atomicity - минимальная операция (транзакция)

Consistency - согласованность. Связанные данные в разных таблицах/колонках  должны изменяться взаимозависимо. В БД реализуется транзакицями. Семнтическая связь контролируется программистом.

Isolation - параллельные транзакции не влияют на результат друг друга.

Уровни изоляций:

    Read Uncommitted - Allows dirty reads. Транзакции чтения не блокируются. Транзакции изменения - блокируются друг другом. 

    Read Committed - Does not allow dirty reads. Либо Транзакции Чтения/Записи блокируют друг друга, либо СУБД отслеживает версии данных

    Repeatable read -  If a row is read twice in the same transaciton, result will always be the same. Читающая транзакция блокирует данные для чтения, многократно считанные строки будут одинаковыми.

    Serializable - Performs all transactions in a sequence. Полная изоляция транзакций друг от друга.

Durability - проблемы на нижнем уровне (железо, ОС) не влияют на свойства транзакции. В случае проблем транзакция должна быть rollback.

2) SOLID 

(подробно здесь: http://blog.byndyu.ru/p/blog-page.html)

Single responsibility - объект имеет одно предназначение (ответственность) и инкапсулирует её в классе.

чем меньше в нём ответственности тем реже его надо будет менять.

В идеале - должно быть не более одной причины для изменения класса

Open-closed - проектировать класс такими образом, чтобы его можно было легко использовать (расширять)

без изменения самого класса. На деле реализуется через реализацию интерфейсов и IoC.

Liskov substitution - дочерние классы могут быть заменены базовыми классами.(не изменяют логики базовых классов)

Interface segregation - Толстые интерфейсы необходимо разделять на маленькие и специфические. Чтобы наследники (клиенты) не содержали кучу ненужного функционала

Dependency inversion

(подробно здесь: http://sergeyteplyakov.blogspot.ru/2014/11/di-vs-dip-vs-ioc.html)

IOC - Inversion of Control - общее понятие. Говорится о том , что фремворк вызввает определенные точки лоступа у нашей библиотеки

DI - Dependency Injection - Внедрение зависимостей - механизм передачи классу его зависимостей (обхектов,к оторые он использует). Передаются рализации интерфейсов через конструктор, метод или проперти

DIP - Dependency Inversion Principle - это принцип проектирования, который говорит, что классы должны зависеть от высокоуровневых абстракций. Это значит, что зависимости с более высокоуровневыми классами надо реализовывать через Внедрение зависимостей (реализация интерфейса). Реализация низкоуровневых объектов может быть задана явно (ArrayList и Hashmap например)

test (dude 2017-10-26 21:24:09 Общее)

test

https://www.youtube.com/watch?v=x59f9A1l0ao&list=PLAFD5B210501A00AB

Самоучитель игры на фортепиано, Зимина О.П., Мохель Л.В.

http://www.klex.ru/i5y

про теорию музыки (dude 2017-10-18 19:23:02 Общее)

про теорию музыки

https://www.youtube.com/watch?v=dlCUvz6V_QA&feature=youtu.be

митап (dude 2017-10-13 20:12:53 Общее)

митап

https://www.meetup.com/progmsk/events/244168046/?rv=ea1&_af=event&_af_eid=244168046&https=on

ODFToolkit (dude 2017-09-13 21:27:17 Программирование)

Вот интересно:

У org.odftoolkit.simple.style.Font  не работает метод setSize у уже существующх стилей.
При добавлении строк в таблицу , криво отрабатывают методы  appendRows и insertRows


Было  бы здорово как то это поправить и закинуть в апач репозиторий.

сайт с рецептами (dude 2017-09-08 21:45:31 Еда)

http://andychef.ru/recipes/cheese-mango/

Отображение запросов Hibernate к СУБД (dude 2017-09-02 18:24:09 Программирование)
На днях в очередной раз достали огромные запросы с параметрами
select * from person where type in(?, ?, ?)

гугление показало следующие варианты лечения

1) Логирование через Log4j
это самый правильный и нативный способ отображения значений в очереди
https://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-log4j/
 результат
Hibernate: INSERT INTO mkyong.stock_transaction (CHANGE, CLOSE, DATE, OPEN, STOCK_ID, VOLUME)
VALUES (?, ?, ?, ?, ?, ?)
13:33:07,253 DEBUG FloatType:133 - binding '10.0' to parameter: 1
13:33:07,253 DEBUG FloatType:133 - binding '1.1' to parameter: 2
13:33:07,253 DEBUG DateType:133 - binding '30 December 2009' to parameter: 3
13:33:07,269 DEBUG FloatType:133 - binding '1.2' to parameter: 4
13:33:07,269 DEBUG IntegerType:133 - binding '11' to parameter: 5
13:33:07,269 DEBUG LongType:133 - binding '1000000' to parameter: 6
Очевидные недостатки: огромные логи и очередь не собрана.
2) через перехватчик p6spy
популярное решение, перехватывать обращения к бд и логировать их
https://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-solution/

результат - собранный sql запрос. удобен для отладки jpa очередей
insert into mkyong.stock_transaction (CHANGE, CLOSE, DATE, OPEN, STOCK_ID, VOLUME)
values (10.0, 1.1, '2009-12-30', 1.2, 11, 1000000)

недостатки: Сложность настройки (установка на вэбсервер).
Потратив пару часов времени я выяснил что для Wildfly p6spy не поддерживает xa-datasource (который используется менеджером транзакций в JTA). В glassfish такая поддержка есть. Предложенные варианты проксирования через обычный datasource, полагаю, не заработают в рамках JTA.

3) писать логи запросов средствами СУБД.
В моём случае это PostgreSQL. Лог выходит в виде:

LOG:  execute <unnamed>: select referenceb11_.label as col_0_0_, referenceb8_.label as col_1_0_, person3_.gender as col_2_0_, count(distinct assignment1_.person_id) as col_3_0_ from orgstruct.staff_unit staffunit0_ left outer join orgstruct.assignment assignment1_ on staffunit0_.id=assignment1_.staff_unit_id and ( assignment1_.removed is null or assignment1_.removed = 'false') left outer join orgstruct.assignment_to_operation assignment2_ on assignment1_.id=assignment2_.assignment_id and ( assignment2_.removed is null or assignment2_.removed = 'false') inner join person.person person3_ on assignment1_.person_id=person3_.id left outer join person.specialty_diplom specialtyd4_ on person3_.id=specialtyd4_.person_id and ( specialtyd4_.removed is null or specialtyd4_.removed = 'false') inner join orgstruct.departament_actual departamen5_ on staffunit0_.department_id=departamen5_.id inner join orgstruct.departament departamen6_ on departamen5_.id=departamen6_.departament_actual_id and ( departamen6_.removed is null or departamen6_.removed = 'false') left outer join classifier_other.post post7_ on staffunit0_.post_id=post7_.id left outer join classifier.reference_book referenceb8_ on post7_.post_level_id=referenceb8_.id left outer join classifier.reference_book referenceb9_ on post7_.post_category_id=referenceb9_.id inner join classifier.reference_book_set_reference_books referenceb10_ on referenceb9_.id=referenceb10_.reference_book_id inner join classifier.reference_book_set referenceb11_ on referenceb10_.set_id=referenceb11_.id where post7_.civil_sign=true and (staffunit0_.removed is null or staffunit0_.removed=false) and (assignment1_.removed is null or assignment1_.removed=false) and staffunit0_.start_date<=$1 and (staffunit0_.end_date>=$2 or staffunit0_.end_date is null) and  not (exists (select staffunitc13_.id from orgstruct.staff_unit_closed staffunitc13_ where (staffunitc13_.reason_id=$3 and staffunitc13_.close_date<=$4 or staffunitc13_.reason_id=$5 and staffunitc13_.close_date<=$6 or staffunitc13_.reason_id=$7 and staffunitc13_.close_date<=$8 or staffunitc13_.reason_id=$9 and staffunitc13_.close_date<=$10 and staffunitc13_.open_date>$11) and staffunitc13_.staff_unit_id=staffunit0_.id)) and (assignment2_.operation_id in ($12 , $13)) and assignment2_.assignment_date<=$14 and (assignment2_.assignment_date is null or assignment2_.vacation_date>$15) and specialtyd4_.learning_year_end=2016 and (specialtyd4_.retraining_sign=true or specialtyd4_.upgrading_sign=true) group by referenceb11_.id , referenceb8_.id , person3_.gender
DETAIL: parameters: $1 = '2016-12-31', $2 = '2016-12-31', $3 = '8214', $4 = '2016-12-31', $5 = '1080', $6 = '2016-12-31', $7 = '1081', $8 = '2016-12-31', $9 = '1079', $10 = '2016-12-31', $11 = '2016-12-31', $12 = '1084', $13 = '1085', $14 = '2016-12-31', $15 = '2016-12-31'

Что тоже не является склеенной очередью.

В качестве решения : взял лог из субд (пункт 3) и написал программку которая посдтавляет значения в очередь с ?
Тоже самое можно сделать и с логом из log4j (пункт 1)

как-то так.
PS: надо посомтреть на внутренности jdbc драйвера. Может есть возможность заставить его как-то скидывать собранные запросы, не в буферизированные логи (log4j) на сразу в какйнибудь слушающий поток....
Концепт алгоритма авторизации (dude 2017-08-12 04:53:38 Общее)
1) берём sessionId
2)  делаем password+sessionid
3) md5 от этого отправляем на сервер
4) сервер делает тоже самое но с паролем в базе. если результаты совпадают - авторизация пройдена. пароль можно хранить в базе в md5

плюсы:  передача пароля в закрытом виде. нет возможности перехвата пароля
минусы: не защищает от перехвата sessionId и подстановки его в браузер

следующий этап - авторизация по открытым и закрытым ключам. так-же не спасает от подмены sessionId.

От подмены может спасти постоянно обновляющийся авторизационный ключ:

клиент хранит в яваскрипте/в куки/в кэше (в браузере) md5 от пароля.
при каждом запросе, или раз в минуту, клиент запрашивает на сервере рандомный открытый ключ, цепляет его к своей md5, делает ещё раз md5 и отправляет на сервер. при неуспешной авторизации - сессия закрывается.
подменённая сессия проживёт не больше минуты....