Основы кроссплатформенной разработки ПО
Спецкурс для специальности "Программная инженерия"
Димитров Вячеслав Михайлович, старший преподаватель кафедры ИМО, dimitrov@cs.petrsu.ru
Лабораторные работы
- Одно приложение (JSON редактор).
- Можно придумать свое: графический интерфейс, работа с сетью, работа с файловой системой.
- Разные языки и платформы: Java, Qt, Python, ElectronJS, React Native (Mobile)
- Демонстрация 1-4 под две платформы: Linux, Windows
- Демонстрация 5 под Android
Определение
Кроссплатформенное ПО - ПО, которое работает на более чем одной платформе или операционной системе с возможностью перекомпиляции, но без изменения исходного кода.
Технологии обеспечения кроссплатформенной поддержки
Виртуальная машина
Реализует специфику платформы, но при этом позволяет транслировать программу в свой внутренний формат и запускать приложение под платформу.
Пример: Java Virtual Machine, Parrot.
Кроссплатформеная библиотека
Реализует множество возможностей, и позволяет писать код без адаптации к системе (системозависимые части реализуются на уровне библиотеки).
Пример: Qt и Boost.
Web-Технологии
Разработка с помощью HTML, CSS и javascript на готовом визуализаторе одного из браузеров.
Пример: Electron, Enyo
Мобильная разработка
Разработка единой кодовой базы для платформ с последующей компиляцией и созданием приложений под каждую отдельную платформу (Android, iOS, Windows Phone).
Пример: React Native
Java
- Текущая версия 14
- Java Runtime Enviroment (JVM + java, выполнение программ)
- Java Development Kit (JRE + средства компиляции и отладки)
- Проект OpenJDK - исходный код JRE/JDK
- Сборки и сертификация.
Java
- Один из поставщиков и сборщиков JRE/JDK - Oracle.
- Сборка OpenJDK от Oracle (обновления прекращаются как только выходит новая версия).
- OracleJDK, бесплатно на этапе разработки, платно в рабочей среде.
- Сборка AdoptOpenJDK: длительная поддержка, выбор JVM.
JVM
- Запускать приложения на Java.
- Управлять и оптимизировать память.
- Реализации: HotSpot, OpenJ9.
- Scala, Groovy и Kotlin
Cтруктура class файла
- Магическое число 0xCAFEBABE - JVM понимает, что это class файл
- 4 байта - версия Java
- Массив констант. 14 типов констант (класс, метод, строка, целое число и т. д.).
- Флаги доступа (интерфейс/класс, общедоступный/абстрактный, финальный).
- Список полей (массив структур с полем, типом, значением (финальное)).
package ru.petrsu.cross;
public class HelloWorld {
public static void main(String[] args) {
say("Hello");
say("World!");
}
public static void say(String str) {
System.out.println(str);
}
}
$ javac HelloWorld.java
$ javap -c HelloWorld
Compiled from "HelloWorld.java"
public class ru.petrsu.cross.HelloWorld {
public ru.petrsu.cross.HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String Hello
2: invokestatic #3 // Method say:(Ljava/lang/String;)V
5: ldc #4 // String World!
7: invokestatic #3 // Method say:(Ljava/lang/String;)V
10: return
public static void say(java.lang.String);
Code:
0: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
7: return
}
Загрузка класса
- Bootstrap - базовый загрузчик, загружает классы платформы.
- Extension classloader - загружает из jre/lib/ext.
- AppClassLoader - загружает из -classpath.
- Собственный загрузчик классов (динамические плагины).
Линковка класса
- Верификация байт-кода.
- Выделение памяти под статические поля и их инициализация.
- Разрешение символьных ссылок.
- Выполнение методов классов.
Инструкции JVM
- Инструкция - один байт кода операции (байт код).
- Код операции - действие.
- ~200 операций.
- 7 примитивных типов данных.
Вызов методов
- Методы экземпляров.
- Методы классов (статические).
- Методы экземпляра используют динамическое (позднее) связывание
- Методы класса используют статическое (раннее) связывание.
- Инструкции invokevirtual и invokestatic.
Управление памятью: традиционный подход
- Явное выделение памяти программистом для объекта.
- Обращение к объекту по сохраненному указателю.
- Явное удаление объекта
- Две проблемы: висячие ссылки и утечка памяти.
Управление памятью: java
- При запуске JVM создается куча.
- Во время выполнения может менять размеры.
- Все созданные объекты находятся в куче.
- Когда куча заполнена происходит сборка мусора.
Управление памятью: java
- Сборка мусора - процесс освобождения места в куче.
- Гарантируется, что удаляются только недоступные из выполняемого кода объекты.
- Объекту присвоена null или он инициализирован другим объектом.
Управление памятью: стек.
- Для каждого потока используется свой стек.
- Предел размера стека определен операционной системой
- Хранит примитивы и ссылки на объекты
- Работает по схеме последним вошел, первым вышел (LIFO)
- Память стека существует пока выполняется текущий метод
- Обращение к памяти стека происходит значительно быстрее, чем к памяти кучи
- Автоматически выделяется и освобождается, когда метод вызывается и завершается соответственно
Управление памятью. Куча.
- Пространство кучи является общим для всего приложения
- Размер кучи не ограничен
- Все созданные объекты хранятся в куче
- Пространство кучи существует пока работает приложение
- Медленнее, чем стек
- Память в куче выделяется, когда создается новый объект и освобождается сборщиком мусора, когда в приложении не остается ни одной ссылки на его
Java 8
- Лямбды
- Коллекции и потоки
Java 8. Лямбды
Runnable runnable = new Runnable(){
@Override
public void run(){
System.out.println("Hello world !");
}
};
Java 8. Лямбды
Runnable runnable = () -> System.out.println("Hello world two!");
Java 8. Коллекции
List list = Arrays.asList("franz", "ferdinand", "fiel", "vom", "pferd");
list.stream()
.filter(name -> name.startsWith("f"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Java 9
- Дополнительные методы для создания коллекций (List.of, Set.of, Map.of)
- Дополнительные методы для коллекций
- Options, ifPresentOrElse
- В интерфейсы добавлены private методы
- jShell - оболочка для простых команд
- Свой HTTPClient (раньше Apache HttpClient или OkHttp). Preview.
Java 10
- Переменная var (все еще строго типизированный). Только внутри методы.
Java 11
- Несколько новых методов для String (isBlank, lines, strip и др.)
- Запустить исходные файлы
- Вывод типа локальной переменной (var) для лямбда-параметров
- HTTPClient в окончательной версии.
- Сборщик мусора No-Op
Java 13
- Новый switch.
- Многострочные строки (preview).
Java 13. Какой был switch
switch(status) {
case SUBSCRIBER:
// code block
break;
case FREE_TRIAL:
// code block
break;
default:
// code block
}
Java 13. Какой стал switch
boolean result = switch (status) {
case SUBSCRIBER -> true;
case FREE_TRIAL -> false;
default -> throw new IllegalArgumentException("something is murky!");
};