Здравствуйте! В этой статье, я постараюсь кратко рассказать о четырёх достаточно известных способах хранения деревьев с указанием преимуществ и недостатков. На идею написать подобную статью подтолкнул не раз слышимый мною вопрос: "А как это будет в Hibernate?", то есть как реализовать какой-либо из способов хранения дерева с использованием ORM Hibernate. Сразу замечу, что данная статья не является каким-либо призывом использовать именно реляционные БД для решения задач связанных с деревьями, так как понятно что реляционные базы не заточены конкретно для целей хранения\обработки таких данных. Для иерархии подходят и используются графовые базы данных. Поэтому эта статья будет полезная тем, кому необходимо по каким-либо причинам реализовать хранение дерева именно в реляционной БД. Необходимо также отметить, что и ORM Hibernate также не содержит каких-либо готовых решений из коробки для хранения\обработки деревьев по крайней мере на данный момент, поэтому реализация таких решений практически полностью ложиться на плечи разработчика. В примерах далее для полной и целостной картины, кроме сущностей(entity), рассмотрим кратко и такие базовые операции, как получение всех потомков с уровнем вложенности, получение всех родителей с уровнем вложенности, а также операции добавления, удаления и перемещения узла в дереве. В качестве примера дерева послужит структура папок на файловой системе, которая будет отражена в таблицах(е) БД. На такие моменты, как инициализация сущности(entity) не будем акцентировать внимание, полагаю что рассматривать это не имеет смысла, так как алгоритмы обхода дерева известны и описаны во многих книгах и публикациях и будут мало кому интересны. В любом случае мои реализации обхода дерева представлены на GitHub и с ними при желании можно ознакомиться.
Пользователь
Искусство написания циклов на Python
![](https://habrastorage.org/webt/al/oe/7y/aloe7ywy_h5hyngjk6dvl0a4pcc.jpeg)
Цикл
for
— самый базовый инструмент потока управления большинства языков программирования. Например, простой цикл for
на C выглядит так:int i;
for (i=0;i<N;i++)
{
//do something
}
Не существует более изящного способа написания цикла
for
на C. В сложных случаях обычно приходится писать уродливые вложенные циклы или задавать множество вспомогательных переменных (например, как i
в показанном выше коде).К счастью, в Python всё более удобно. В этом языке есть множество хитростей, позволяющих писать более изящные циклы, которые упрощают нашу жизнь. В Python вполне можно избежать вложенных циклов и вспомогательных переменных, и мы даже можем самостоятельно настраивать цикл
for
.Эта статья познакомит вас с самыми полезными трюками по написанию циклов на Python. Надеюсь, она поможет вам ощутить красоту этого языка.
Как учить протоколы без чтения RFC: как сэкономить время при разработке
![](https://habrastorage.org/webt/g7/2o/g0/g72og0nkmjoonhewn-zkbhnil_8.png)
Если вы разрабатывает приложение, работающее по сети, или проводите отладку работы такого приложения, доскональное знание работы сетевых протоколов сильно облегчит вашу задачу. Первоисточником подобного знания являются RFC и, к счастью, они с давних времен находятся в открытом доступе. Более того, прочитать их можно даже консольных браузером links, так как кроме текста в них ничего не содержится.
Тем не менее, скорее всего большинство читателей Хабра никогда не читали полностью текст хотя бы одного RFC, даже RFC-2616. Помимо зубодробительного стиля бюрократических документов, помехой может служить языковой барьер. К тому же чаще всего нужно понять какой-то определенный аспект архитектуры протокола: длину и тип полей, код возврата, расположение внутри заголовка. Для этого вовсе не обязательно читать все от корки до корки.
Как раз для этого случая написан Protocol, довольно простое консольное приложение, написанное на Python. Оно имеет двоякое назначение.
- Предоставить разработчикам и инженерам возможность легко и просто увидеть диаграмму заголовков самых распространенных сетевых протоколов прямиком из командной строки.
- Предоставить исследователям и инженерам возможность быстро создавать ASCII диаграммы заголовков, для своих собственных пользовательских протоколов.
Обзор счётчиков Морриса
![](https://habrastorage.org/r/w780/getpro/habr/upload_files/1eb/1cb/123/1eb1cb1231d035e9320cd396eef38137.jpeg)
При реализации потоковых алгоритмов часто возникает задача подсчёта каких-то событий: приход пакета, установка соединения; при этом доступная память может стать узким местом: обычный -битный счётчик позволяет учесть не более
событий.
Одним из способов обработки большего диапазона значений, используя то же количество памяти, является вероятностный подсчёт. В этой статье будет предложен обзор известного алгоритма Морриса, а также некоторых его обобщений.
Другой способ уменьшить количество бит, необходимое для хранения значения счётчика, — использование распада. Об этом подходе мы рассказываем здесь, а также собираемся в ближайшее время опубликовать ещё одну заметку по теме.
Мы начнём с разбора простейшего алгоритма вероятностного подсчёта, выделим его недостатки (раздел 2). Затем (раздел 3) опишем алгоритм, впервые преложенный Робертом Моррисом в 1978 году, укажем его важнейшие свойства и приемущества. Для большинства нетривиальных формул и утверждений в тексте присутствуют наши доказательства — интересующийся читатель сможет найти их во вкладышах. В трёх последующих разделах мы изложим полезные расширения классического алгоритма: вы узнаете, что общего у счётчиков Морриса и экспоненциального распада, как можно уменьшить ошибку, пожертвовав максимальным значением, и как эффективно обрабатывать взвешенные события.
Подробно о PECS
Всем привет. Сегодня я хочу поговорить о принципе PECS. Понимаю, что сейчас гуру программирования и многоопытные сеньоры в очередной раз впечатали ладонь в лицо, ибо «Java Generics появились в JDK 1.5, которая вышла 30 сентября 2004 года…». Но если есть те, для кого принцип PECS остаётся туманным и непонятным, а упорное гугленье только сгущает «туман», добро пожаловать под кат, будем вместе разбираться до полного духовного просветления. Хочу сразу предупредить, что в данной заметке не рассматривается, что такое дженерики и что такое wildcard. Если вы не знакомы с данными понятиями, то перед чтением необходимо с ними разобраться.
«Почему Kotlin хуже, чем Java?»
![](https://habrastorage.org/r/w780/getpro/habr/upload_files/959/3ab/d17/9593abd17bf761ec022718bbeb7d0087.jpg)
Такой провокационный вопрос задал реддитор nenemen в сабреддите Java:
«Я думаю о том, чтобы свой следующий проект сделать на Kotlin + Spring Boot, но мощь всенародной любви к Kotlin и одновременно ненависти к Java заставляют всё это походить на какой-то культ. Поэтому хотел бы услышать аргументы «против».
Мы в FunCorp в своё время сделали именно такой выбор в пользу Kotlin. И сегодня соотношение Java/Kotlin у нас составляет примерно 20 на 80, продолжая уменьшаться при каждом удобном случае. Поэтому ответы на этот вопрос меня заинтересовали, и я стал листать секцию комментариев. Там наткнулся на реплику реддитора rzwitserloot, которая мне показалась настолько взвешенной, многосторонней и рациональной, что я захотел поделиться ей с нашей командой, а заодно и читателями Хабра.
Далее перевод его аргументов.
Программируемые NER (Named Entity Recognition) компоненты
![](https://habrastorage.org/r/w780/getpro/habr/upload_files/f37/eb6/472/f37eb6472f801592bb187cf061abed23.jpg)
В данной заметке мы продолжим говорить о NER компонентах и попытаемся определить условия, в которых нам начинает недоставать функционала стандартных компонентов и стоит задуматься о программировании своих собственных.
В подавляющем большинстве случаев для поиска пользовательских сущностей достаточно найти и настроить какой-либо уже существующий компонент, сконфигурировать или обучить его модель. Лишь иногда, в достаточно специфичных ситуациях, возможностей существующих решений оказывается недостаточным, и нам приходится начинать программировать. Но выделение ресурсов, кодирование, тесты, поддержка - все это стоит затевать лишь когда без всего этого просто не обойтись.
Реактивное программирование на Java: как, зачем и стоит ли? Часть I
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/5a2/bf4/7b8/5a2bf47b83f01bccabf86508b5a88bad.png)
Идея реактивного программирования появилась сравнительно недавно, лет 10 назад. Что вызвало популярность этого относительно нового подхода и почему сейчас он в тренде, рассказал на конференции РИТ++ 2020 эксперт и тренер Luxoft Training Владимир Сонькин.
В режиме мастер-класса он продемонстрировал, почему так важен неблокирующий ввод-вывод, в чем минусы классической многопоточности, в каких ситуациях нужна реактивность, и что она может дать. А еще описал недостатки реактивного подхода.
Вышла Java 16
Вышла 16-я версия платформы Java SE. В этот релиз попало около двух с половиной тысяч закрытых задач и 17 JEP'ов. Изменения API можно посмотреть здесь. Release notes здесь.
Уже сейчас доступны для скачивания дистрибутивы Oracle JDK и OpenJDK.
Как извлечь пользу из статической типизации
![](https://habrastorage.org/r/w780/getpro/habr/upload_files/4a3/d7a/0e8/4a3d7a0e8ea7c5cfd305f61b86daea43.jpg)
Эта статья о том, как извлечь максимум пользы из статической системы типов при дизайне вашего кода. Статья пытается быть language agnostic (получается не всегда), примеры на Java и взяты из жизни.
Управление памятью Java
![](https://habrastorage.org/r/w780/getpro/habr/upload_files/cc4/97a/9a6/cc497a9a605aa969de312739e9ed8c7b.jpg)
Это глубокое погружение в управление памятью Java позволит расширить ваши знания о том, как работает куча, ссылочные типы и сборка мусора.
API, ради которых наконец-то стоит обновиться с Java 8. Часть 3
Какие есть причины переходить на новые версии Java? Кто-то это сделает из-за новых языковых возможностей вроде выражений switch
, блоков текста или записей. Кому-то понадобятся новые интересные возможности вроде модулей или низкопаузных сборщиков мусора. Кто-то это сделает просто из-за того, что обновив версию Java, их программа станет быстрее и будет есть меньше памяти. Но есть ещё одна, не менее важная причина. Это новые API, которые позволят писать меньше кода и избежать траты времени на поиск нужной функциональности во внешних библиотеках. А в некоторых случаях сделают ваш код быстрее.
В предыдущих двух частях мы уже рассмотрели по 10 новых API, которые появились в Java 9 и более поздних версиях (часть 1, часть 2). Сегодня мы рассмотрим ещё 10.
Py4J – мост между Python и Java
![](https://habrastorage.org/webt/a4/ec/02/a4ec02uiv2tpxakenbyhtaygpxm.png)
Название Py4J можно встретить разве что в списке библиотек, используемых PySpark, но не стоит недооценивать данный инструмент, который обеспечивает совместную работу Python и Java. В этой статье будет кратко описана работа Py4J, рассмотрен пример использования и перечислены сильные и слабые стороны библиотеки. В конце будут описаны альтернативные способы связи Java и Python.
Документируй это
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/c24/f86/049/c24f86049e0d932d8c9f49f9ab51fd06.png)
Всем привет! В данной статье хотел бы рассмотреть инструменты документирования в принципиально разных подходах в разработке API, а именно для CodeFirst - инструменты Spring Rest Docs (а также его надстройки Spring Auto Rest Docs) и для ApiFirst - инструменты экосистемы Swagger(Open-Api).
Дисклеймер: В подробности холивара на тему что же лучше CodeFirst или ApiFirst я вдаваться не будут, всего лишь продемонстрирую возможную практику документации в обоих вариантах.
Размышления о Java 8 и Java 11 в ожидании Java 17
![](https://habrastorage.org/webt/ma/al/-a/maal-amz6xiu5wypq7aehqbsosa.jpeg)
В мире Java есть одна приятная особенность, которая связана с жизненным циклом версий платформы. А именно, новый релиз Java выходит каждые 6 месяцев, а каждые 3 года появляется новый LTS-релиз — версия с долгосрочной поддержкой. В настоящий момент LTS-версия платформы представлена Java 11. Поэтому многие компании переходят на неё. Это — заметное движение, так как среди его последствий можно отметить тот факт, что, с выходом в сентябре 2021 года Java 17, новые фреймворки не будут поддерживать Java 8, а в качестве минимальной версии платформы будут рассматривать Java 11.
Цель этой статьи заключается в том, чтобы рассмотреть некоторые общие базовые API Java 8 и Java 11.
Временные ряды. Простые решения
![](https://habrastorage.org/webt/l5/d1/zd/l5d1zdcxdlaicv4jpiiqxitplti.jpeg)
Привет, Хабр!
В этой статье мы рассмотрим несколько простых подходов прогнозирования временных рядов.
Материал, изложенный в статье, на мой взгляд, хорошо дополняет первую неделю курса «Прикладные задачи анализа данных» от МФТИ и Яндекс. На обозначенном курсе можно получить теоретические знания, достаточные для решения задач прогнозирования рядов динамики, а в качестве практического закрепления материала предлагается с помощью модели ARIMA библиотеки scipy сформировать прогноз заработной платы в Российской Федерации на год вперед. В статье, мы также будем формировать прогноз заработной платы, но при этом будем использовать не библиотеку scipy, а библиотеку sklearn. Фишка в том, что в scipy уже предусмотрена модель ARIMA, а sklearn не располагает готовой моделью, поэтому нам придется потрудиться ручками. Таким образом, нам для решения задачи, в каком то смысле, необходимо будет разобраться как устроена модель изнутри. Также, в качестве дополнительного материала, в статье, задача прогнозирования решается с помощью однослойной нейронной сети библиотеки pytorch.
Почему важно, что системы линейных уравнений решаются быстрее, чем множатся матрицы
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/171/6ae/42c/1716ae42c814bafd81cbd483eed176e2.png)
В 1998, когда Google только появился, его киллер-фичей был патентованный алгоритм PageRank для сортировки результатов поиска по популярности. Описанный стэнфордскими аспирантами Брином и Пейджем в научной статье, он сводится к очень простой идее:
Понимание квантовых вычислений через случайное блуждание пьяненьких людей
![image](https://habrastorage.org/webt/i4/zl/fj/i4zlfj8iet2wp8xg54te504ydx4.png)
Квантовые вычисления — это самая большая революция в вычислениях со времен… вычислений. Наш мир состоит из квантовой информации, но мы воспринимаем мир как классическую информацию. То есть очень много происходит в небольших масштабах, недоступных нашим нормальным чувствам. Как люди, мы эволюционировали, чтобы обрабатывать классическую информацию, а не квантовую информацию: наш мозг запрограммирован на то, чтобы думать о саблезубых кошках, а не о кошках Шредингера. Мы можем достаточно легко закодировать нашу классическую информацию с помощью нулей и единиц, но как насчет доступа к дополнительной доступной информации, из которой состоит наша Вселенная? Можем ли мы использовать квантовую природу реальности для обработки информации? Конечно, иначе нам пришлось бы закончить этот пост здесь, и это нас всех не удовлетворило бы. Давайте исследуем возможности квантовых вычислений, а затем приступим к написанию собственного квантового кода.
Отправной точкой для изучения квантовых вычислений является понимание того, что, хотя многие принципы противоречат здравому смыслу, классическая вселенная, которую мы знаем и любим, — всего лишь тень квантовой ткани реальности. Часть того, чтобы привыкнуть к кванту, — это привыкнуть к ограничениям нашего собственного восприятия. Это ограничение аналогично рисованию трехмерного объекта на двухмерном листе бумаги. Взгляните на каркас ниже. Он может представлять собой либо коробку (мы можем проиллюстрировать это стаканом сверху), угол (мы можем поместить бутылку внутрь, чтобы мы увидели угол).
![image](https://habrastorage.org/getpro/habr/post_images/80c/239/da8/80c239da88529d1f04bfe9419e3f5d04.png)
Мы вынуждены видеть либо одно, либо другое, а не то и другое одновременно.
Как ускорить код на Python в тысячу раз
![](https://habrastorage.org/webt/fc/-j/8b/fc-j8brzz3u_aku5v3ajtyftyxu.jpeg)
Обычно говорят, что Python очень медленный
В любых соревнованиях по скорости выполнения программ Python обычно занимает последние места. Кто-то говорит, что это из-за того, что Python является интерпретируемым языком. Все интерпретируемые языки медленные. Но мы знаем, что Java тоже язык такого типа, её байткод интерпретируется JVM. Как показано, в этом бенчмарке, Java намного быстрее, чем Python.
АТАТА: распутываем задачу про палиндром
![](https://habrastorage.org/webt/my/yl/8o/myyl8oclin_rfmesorfbo5647wu.png)
Продолжение под катом.
Information
- Rating
- Does not participate
- Location
- Россия
- Date of birth
- Registered
- Activity