• Приведение примитивных типов. Приведение типа int к типу short и byte.
    SVN| Java 2020-04-20 21:55
  • Полезные команды в PostgreSQL

    Размер БД

    Для получения физического размера файлов применяем следующий запрос:

    SELECT pg_database_size(current_database());
    
    

    Результат будет представлен в формате числа вида 41809016. В нашем случае current_database() является функцией, возвращающей имя текущей БД. Вместо неё мы можем ввести имя текстом:

    SELECT pg_database_size('my_database');
    
    

    Если хотим получить информацию в более удобочитаемом виде, нам пригодится функция pg_size_pretty:

    SELECT pg_size_pretty(pg_database_size(current_database()));
    
    

    В итоге получим информацию вида 40 Mb.

    Перечень таблиц

    Порой, нужно получить перечень таблиц БД. Для этого нам пригодится следующий запрос:

    SELECT table_name FROM information_schema.tables
    WHERE table_schema NOT IN ('information_schema','pg_catalog');
    
    

    Здесь information_schema — это стандартная схема БД, содержащая коллекции представлений (views): таблицы, поля и т. п. Представления таблиц включают информацию о всех таблицах БД.

    Следующий запрос выберет все таблицы из указанной схемы текущей БД:

    SELECT table_name FROM information_schema.tables
    WHERE table_schema NOT IN ('information_schema', 'pg_catalog')
    AND table_schema IN('public', 'myschema');
    
    

    Стоит добавить, что в последнем условии IN мы можем указать имя определенной схемы.

    Размер таблицы

    Как и в случае с получением размера БД, размер данных таблицы мы можем вычислить посредством соответствующей функции:

    SELECT pg_relation_size('accounts');
    
    

    В нашем случае функция pg_relation_size возвращает объём, занимаемый на диске указанным слоем заданной таблицы либо индекса.

    Имя наибольшей таблицы

    Чтобы вывести список таблиц текущей БД, отсортированный по размеру таблицы, подойдёт следующий запрос:

    SELECT relname, relpages FROM pg_class ORDER BY relpages DESC;
    
    

    Чтобы получить информацию о наибольшей таблице, мы можем ограничить запрос посредством LIMIT:

    SELECT relname, relpages FROM pg_class ORDER BY relpages DESC LIMIT 1;
    
    

    Что здесь что:

    relname — имя таблицы, представления, индекса и т. д.;

    relpages — размер представления этой таблицы на диске в количестве страниц (по умолчанию одна страницы — 8 Кб);

    pg_class — системная таблица, содержащая информацию о связях таблиц БД.

    Перечень подключенных пользователей, активность пользователя

    Если хотим узнать имя, IP и используемый порт подключенных юзеров, выполняем:

    SELECT datname,usename,client_addr,client_port FROM pg_stat_activity;
    
    

    Если хотим узнать активность соединения конкретного пользователя, выполняем:

    SELECT datname FROM pg_stat_activity WHERE usename = 'devuser';
    


    SVN| PostgreSQL 2020-04-19 20:17
  • Использование JNDI в Java

    Интерфейс Context

    Данный интерфейс содержит набор констант для инициализации контекста, а также набор методов для создания и удаления контекстов, привязки объектов к имени, а также для поиска и получения объектов.


    Рассмотрим некоторые операции, которые выполняются с помощьюа данного интерфейса.


    Наиболее частое действие — поиск объекта по имени. Осуществляется с помощью методов:

    • Object lookup(String name)
    • Object lookup(Name name)

    Привязка объекта к имени осуществляется с помощью методов bind:

    • void bind(Name name, Object obj)
    • void bind(String name, Object obj)

    Оба метода привяжут имя name к объекту Object


    Обратная операция привязке — отвязка объекта от имени, осуществляется с помощью методов unbind:

    • void unbind(Name name)
    • void unbind(String name)

    Полный список методов есть на сайте официальной документации.

    InitialContext

    InitialContext — это класс, который представляет из себя корневой элемент JNDI tree и реализует интерфейс Context. Искать объекты по имени внутри JNDI tree нужно относительно некоторого узла. Таким узлом может служить корневой узел дерева — InitialContext. Типичным сценарием использования JNDI является: 
    • Получить InitialContext.
    • Использовать InitialContext для извлечения объектов по имени из JNDI tree.
    Способов получить InitialContext бывает несколько. Все зависит от окружения, в котором находится Java-программа. К примеру, если Java-программа и JNDI tree запущены внутри одного и того же application сервера, получить InitialContext довольно просто: 
    InitialContext context = new InitialContext();

    Если же это не так, получить контекст становится немного сложнее. Порой бывает необходимо передать список пропертей окружения для инициализации контекста:
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.fscontext.RefFSContextFactory");
    
    Context ctx = new InitialContext(env);

    Пример выше демонстрирует один из возможных способов инициализации контекста и иной смысловой нагрузки в себе не несет. Детально погружаться в код не нужно.

    Пример использования JNDI внутри SpringBoot unit теста

    Выше мы говорили о том, что для взаимодействия JNDI со службой имен и каталогов необходимо иметь под рукой SPI (Service Provider Interface), с помощью которого будет осуществляться интеграция между Джавой и службой имен. Стандартная JDK поставляется с несколькими различными SPI (выше мы их перечисляли), каждый из которых не вызывает большого интереса для демонстрационных целей. Поднять JNDI и Java приложение внутри какого-нибудь контейнера в какой-то мере интересно. Однако автор этой статьи — человек ленивый, поэтому для демонстрации работы JNDI избрал путь наименьшего сопротивления: запустить JNDI внутри юнит-теста SpringBoot приложения и получить доступ к контексту JNDI с помощью небольшого хака от Spring Framework. Итак, наш план:
    • Напишем пустой Spring Boot проект.
    • Внутри этого проекта создадим юнит-тест.
    • Внутри теста продемонстрируем работу с JNDI:
      • получим доступ к контексту;
      • привяжем (bind) некоторый объект под некоторым именем в JNDI;
      • получим объект по его имени (lookup);
      • проверим, что объект не null.

    SVN| JavaEE| Java| Jakarta| JNDI 2020-04-17 21:30
  • Использование JNDI в Java
    Привет! Сегодня мы познакомимся с тобой с JNDI. Узнаем, что это такое, для чего оно нужно, как работает, как нам с ним работать. А затем напишем Spring Boot юнит тест, внутри которого будем играться с этим самым JNDI.

    Введение. Службы имен и каталогов

    Прежде чем погружаться в JNDI, разберемся с тем, что же такое службы имен и каталогов. Наиболее наглядным примером такой службы является файловая система на любом ПК, ноутбуке или же смартфоне. Файловая система управляет (как это ни странно) файлами. Файлы в таких системах сгруппированы в древовидную структуру. У каждого файла есть уникальное полное имя, например: C:\windows\notepad.exe.
    Обрати внимание: полное имя файла представляет собой путь от некоторой корневой точки (диск C) до самого файла (notepad.exe). Промежуточными узлами в такой цепи являются каталоги (каталог windows).
    Файлы внутри каталогов обладают атрибутами. Например "Скрытый", "Только для чтения" и др. Подробное описание такой простой вещи как файловая система поможет лучше понять определение службы имен и каталогов. Итак,
    служба имен и каталогов — это система, которая управляет отображением множества имен во множестве объектов. В нашей файловой системе мы взаимодействуем с именами файлов, за которыми скрываются объекты — сами файлы в различных форматах. В службе имен и каталогов именованные объекты собраны в древовидную структуру. А объекты каталога обладают атрибутами. Еще одним примером службы имен и каталогов является DNS (англ. — Domain Name System, "система доменных имён"). Данная система управляет соответствием между понятными человеку доменными именами (например, https://javarush.ru/) и понятными компьютеру IP-адресами (например, 18.196.51.113). Помимо DNS и файловых систем, есть еще уйма других служб, таких как:

    JNDI

    JNDI, или же Java Naming and Directory Interface, представляет собой Java API для доступа к службам имен и каталогов. JNDI — это API, которое предоставляет единообразный механизм взаимодействия Java-программы с различными службами имен и каталогов. “Под капотом” интеграция между JNDI и любой конкретной службой осуществляется с помощью интерфейса поставщика услуг (Service Provider Interface, SPI). SPI позволяет прозрачно подключать различные службы именования и каталогов, что позволяет Java-приложению использовать JNDI API для доступа к подключенным службам. Рисунок ниже иллюстрирует архитектуру JNDI: Использование JNDI в Java - 2

    Источник: Oracle Java Tutorials

    JNDI. Смысл простыми словами

    Главный вопрос: зачем нужен JNDI? JNDI нужен для того, чтобы мы могли из Java-кода получить Java-объект из некоторой "Регистратуры" объектов по имени объекта, привязанного к этому объекту. Разобьем утверждение выше на тезисы, дабы обилие повторяющихся слов не сбило нас с толку:
    1. В конечном итоге нам нужно получить Java-объект.
    2. Мы получим этот объект из некоторой регистратуры.
    3. В этой регистратуре есть куча объектов.
    4. Каждый объект в этой регистратуре обладает уникальным именем.
    5. Чтобы получить некоторый объект из регистратуры, мы должны в своем запросе передать имя. Как бы сказать: "Дайте мне, пожалуйста, то, что у вас лежит под таким то именем".
    6. Мы можем не только считывать объекты по их имени из регистратуры, но и сохранять в данной регистратуре объекты под определенными именами (как-то ведь они туда попадают).
    Итак, у нас есть какая-то регистратура, или же хранилище объектов, или же JNDI Tree. Далее, на примере, попробуем понять смысл JNDI. Стоит отметить, что по большей части JNDI используется в Enterprise-разработке. А подобные приложения работают внутри некоторого application сервера. Этим сервером может быть какой-нибудь Java EE Application Server или же контейнер сервлетов, вроде Tomcat, либо любой другой контейнер. Сама регистратура объектов, то есть, JNDI Tree, обычно находится внутри этого application сервера. Последнее не всегда обязательно (такое дерево можно иметь локально), но наиболее типично. JNDI Tree может управляться специальным человеком (системный администратор или DevOps специалист), который будет “сохранять в регистратуре” объекты с их именами.
    Когда наше приложение и JNDI Tree находятся совместно внутри одного контейнера, мы безо всяких проблем можем получить доступ к любому Java-объекту, который хранится в такой регистратуре.
    Более того, регистратура и наше приложения могут находиться в разных контейнерах и даже на разных физических машинах. JNDI даже в таком случае позволяет получать доступ к Java-объектам удаленно.
    Типичный кейс. Администратор Java EE сервера кладет в регистратуру объект, в котором хранится необходимая информация для подключения к базе данных. Соответственно, для работы с БД мы просто запросим нужный объект из JNDI tree и будем с ним работать. Это очень удобно. Удобство заключается еще и в том, что в enterprise-разработке существуют различные окружения. Есть продакшн сервера, есть тестовые (и часто тестовых бывает более 1 шт.). Тогда, разместив на каждом сервере внутри JNDI объект для подключения к БД и используя этот объект внутри нашего приложения, нам не придется ничего менять при деплое нашего приложения с одного сервера (тестового, релизного) на другой. Везде будет доступ к базе данных.
    Пример, конечно, в какой то мере упрощенный, но, надеюсь, он поможет лучше понять, зачем нужен JNDI. Далее будем знакомиться c JNDI in Java ближе, с некоторыми элементами рукоприкладства.

    Интерфейс Name

    С помощью интерфейса Name можно управлять именами компонентов, а также синтаксисом имен в JNDI. В JNDI все операции с именами и каталогами выполняются относительно контекста. Абсолютных корней нет. Поэтому JNDI определяет InitialContext, который обеспечивает отправную точку для именования и операций с каталогами. После получения доступа к начальному контексту, его можно использовать для поиска объектов и других контекстов.



    В коде выше мы определили некоторое имя, под которым находится некоторый объект (возможно, и не находится, но мы рассчитываем на это). Наша конечная цель — получить ссылку на этот объект и использовать её в нашей программе. Итак, имя состоит из нескольких частей (или токенов), разделенных слэшем. Такие токены называют контекстами (context). Самый первый — просто context, все последующие — sub-context (далее по тексту — подконтекст). Контексты проще понимать, если рассматривать их как аналогию каталогов или директорий, или просто обычных папок. Корневой контекст — корневая папка. Подконтекст — вложенная папка.  

    Мы можем увидеть все составные части (контекст и подконтексты) данного имени, выполнив следующий код:

    Вывод будет следующим: 
    Вывод демонстрирует, что токены в имени отделяются друг от друга слэшем (впрочем, мы это упоминали).

    SVN| JavaEE| Java| Jakarta| JNDI 2020-04-16 21:28
  • Как скопировать массив в Java? Копирование массивов

    В статье поговорим о некоторых методах копирования массивов в Java. Этот язык программирования имеет встроенные методы, предназначенные для решения данных задач. С их помощью вы сможете сделать как полную копию массива, так и выполнить копирование некоторых элементов массива.

    Методы для копирования массивов в Java

    В Java существует довольно много специальных методов для копирования массивов:

    1.В первую очередь, хотелось бы упомянуть Object.clone() — этот метод вы можете использовать для полного копирования массива. Соответственно, если вы хотите скопировать массив частично, этот способ вам не подойдёт.

    2.Следующий на очереди — System.arraycopy() — по сути, это один из наилучших способов создать частичную копию массива в Java. В этом методе определены следующие параметры: — массив, элементы которого планируем копировать; — индекс элемента; — итоговый (результирующий) массив; — первый элемент итогового массива; — общее число элементов, предназначенных для копирования.

    К примеру, написав System.arraycopy(источник, 2, назначения, 5, 7), вы скопируете семь элементов из массива-источника в итоговый массив, начиная со второго индекса источника в пятый индекс результирующего массива.

    3.Arrays.copyOf() — подойдёт вам, если планируете выполнить копирование нескольких первых элементов массива либо сделать полную копию массива. Способ не так универсален, как System.arraycopy(), но так же прост в применении.

    4.Arrays.copyOfRange() — полезный метод, обеспечивающий частичное копирование массива.

    В принципе, для решения большинства задач по полному либо частичному копированию массивов в Java вышеперечисленных методов вам вполне хватит. Только учтите, что методы, встроенные в Java для копирования, годятся лишь для одномерных массивов.

    Пришла пора посмотреть на них в действии.

    import java.util.Arrays;
    
    public class JavaArrayCopyExample {
    
        /**
         * В этом классе мы демонстрируем методы копирования массивов в java
         * @param args
         */
        public static void main(String[] args) {
            int[] source = {1,2,3,4,5,6,7,8,9};
            int[] source1 = {1,2,3};
            int[] destination=null;
            System.out.println("Массив-источник = " + Arrays.toString(source));
    
            destination = copyFirstFiveFieldsOfArrayUsingSystem(source);
            System.out.println("Копируем первые пять элементов массива, если они есть. Итоговый массив = " + Arrays.toString(destination));
    
            destination = copyFirstFiveFieldsOfArrayUsingSystem(source1);
            System.out.println("Копируем первые пять элементов массива, если они есть. Итоговый массив = " + Arrays.toString(destination));
    
            destination = copyFullArrayUsingSystem(source);
            System.out.println("Осуществляем полное копирование массива посредством System.copyarray(). Итоговый массив = " + Arrays.toString(destination));
    
            destination = copyFullArrayUsingClone(source);
            System.out.println("Осуществляем полное копирование массива посредством clone(). Итоговый массив = " + Arrays.toString(destination));
    
            destination = copyFullArrayUsingArrayCopyOf(source);
            System.out.println("Осуществляем полное копирование массива посредством Arrays.copyOf(). Итоговый массив = " + Arrays.toString(destination));
    
            destination = copyLastThreeUsingArrayCopyOfRange(source);
            System.out.println("Копируем последние три элемента массива посредством Arrays.copyOfRange(). Итоговый массив = " + Arrays.toString(destination));
        }
    
        /**
         * Данный метод выполняет полное копирование массива посредством Arrays.copyOf()
         * @param source
         * @return
         */
        private static int[] copyFullArrayUsingArrayCopyOf(int[] source) {
            return Arrays.copyOf(source, source.length);
        }
    
        /**
         * Данный метод копирует последние три элемента посредством
         * Arrays.copyOfRange() 
         * @param source
         * @return
         */
        private static int[] copyLastThreeUsingArrayCopyOfRange(int[] source) {
            // проверка длины для предотвращения java.lang.ArrayIndexOutOfBoundsException
            //но для простоты метода мы этого не делаем :)
            return Arrays.copyOfRange(source, source.length-3, source.length);
        }
    
        /**
         * Данный метод выполняет полное копирование массива посредством clone() 
         * @param source
         * @return
         */
        private static int[] copyFullArrayUsingClone(int[] source) {
            return source.clone();
        }
    
        /**
         * Данный метод выполняет полное копирование массива посредством System.arraycopy() 
         * @param source
         * @return
         */
        private static int[] copyFullArrayUsingSystem(int[] source) {
            int[] temp=new int1;
            System.arraycopy(source, 0, temp, 0, source.length);
            return temp;
        }
    
        /**
         * Метод копирует первые пять элементов 
         * посредством System.arraycopy()
         * @param source
         * @return
         */
        private static int[] copyFirstFiveFieldsOfArrayUsingSystem(int[] source) {
            if(source.length > 5){
                int[] temp=new int[5];
                System.arraycopy(source, 0, temp, 0, 5);
                return temp;
            }else{
                int[] temp=new int1;
                System.arraycopy(source, 0, temp, 0, source.length);
                return temp;
            }
    
        }
    
    }
    


    SVN| Java 2020-04-01 21:35
  • Новое в JDK 14 (синтаксис)


    Наверное, вы уже слышали, что 17 марта состоялся релиз Java Development Kit 14. Новая сборка принесла несколько важных изменений в синтаксис языка, о которых обязательно должен узнать каждый Java-разработчик.

    Автор видео поставил перед собой цель подробно рассмотреть новшества, включенные в JDK 14, выделяя наиболее полезные среди них. Особое внимание в ролике уделено NPE, Pattern Matching, Switch Expression, Records и Text blocks.

    SVN| Java 2020-03-27 14:44
  • Топ-50 Java Core вопросов и ответов на собеседовании. Часть 3. SVN| Interview| Java 2020-03-20 13:49
  • Топ-50 Java Core вопросов и ответов на собеседовании. Часть 2. SVN| Interview| Java 2020-03-18 15:26
  • Топ-50 Java Core вопросов и ответов на собеседовании. Часть 1. SVN| Interview| Java 2020-03-16 15:28
 SVN, Copyright © 2019 All rights reserved. Running...