diff --git a/01-intro-to-java/lecture/images/01.1-intellij-logo.jpg b/01-intro-to-java/lecture/images/01.1-intellij-logo.jpg new file mode 100644 index 00000000..430dbe78 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.1-intellij-logo.jpg differ diff --git a/01-intro-to-java/lecture/images/01.10-rocket.jpg b/01-intro-to-java/lecture/images/01.10-rocket.jpg new file mode 100644 index 00000000..e10255ce Binary files /dev/null and b/01-intro-to-java/lecture/images/01.10-rocket.jpg differ diff --git a/01-intro-to-java/lecture/images/01.11-array.jpg b/01-intro-to-java/lecture/images/01.11-array.jpg new file mode 100644 index 00000000..38c503bd Binary files /dev/null and b/01-intro-to-java/lecture/images/01.11-array.jpg differ diff --git a/01-intro-to-java/lecture/images/01.12-matrix.jpg b/01-intro-to-java/lecture/images/01.12-matrix.jpg new file mode 100644 index 00000000..6fa69bda Binary files /dev/null and b/01-intro-to-java/lecture/images/01.12-matrix.jpg differ diff --git a/01-intro-to-java/lecture/images/01.13-funcs.jpg b/01-intro-to-java/lecture/images/01.13-funcs.jpg new file mode 100644 index 00000000..7377be8e Binary files /dev/null and b/01-intro-to-java/lecture/images/01.13-funcs.jpg differ diff --git a/01-intro-to-java/lecture/images/01.14-thinking-in-java.jpg b/01-intro-to-java/lecture/images/01.14-thinking-in-java.jpg new file mode 100644 index 00000000..52aea927 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.14-thinking-in-java.jpg differ diff --git a/01-intro-to-java/lecture/images/01.15-effective-java.jpg b/01-intro-to-java/lecture/images/01.15-effective-java.jpg new file mode 100644 index 00000000..2687801d Binary files /dev/null and b/01-intro-to-java/lecture/images/01.15-effective-java.jpg differ diff --git a/01-intro-to-java/lecture/images/01.2-eclipse-logo.jpeg b/01-intro-to-java/lecture/images/01.2-eclipse-logo.jpeg new file mode 100644 index 00000000..c56247fe Binary files /dev/null and b/01-intro-to-java/lecture/images/01.2-eclipse-logo.jpeg differ diff --git a/01-intro-to-java/lecture/images/01.3-vscode-logo.jpg b/01-intro-to-java/lecture/images/01.3-vscode-logo.jpg new file mode 100644 index 00000000..5ff31a35 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.3-vscode-logo.jpg differ diff --git a/01-intro-to-java/lecture/images/01.4-netbeans-logo.jpg b/01-intro-to-java/lecture/images/01.4-netbeans-logo.jpg new file mode 100644 index 00000000..c4bc4c78 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.4-netbeans-logo.jpg differ diff --git a/01-intro-to-java/lecture/images/01.5-java-logo-mascot.png b/01-intro-to-java/lecture/images/01.5-java-logo-mascot.png new file mode 100644 index 00000000..630e86e1 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.5-java-logo-mascot.png differ diff --git a/01-intro-to-java/lecture/images/01.6-jep-per-release.png b/01-intro-to-java/lecture/images/01.6-jep-per-release.png new file mode 100644 index 00000000..c895aae2 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.6-jep-per-release.png differ diff --git a/01-intro-to-java/lecture/images/01.7-hello-world-21.jpeg b/01-intro-to-java/lecture/images/01.7-hello-world-21.jpeg new file mode 100644 index 00000000..e3da0f11 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.7-hello-world-21.jpeg differ diff --git a/01-intro-to-java/lecture/images/01.8-java-app.png b/01-intro-to-java/lecture/images/01.8-java-app.png new file mode 100644 index 00000000..5cba6de2 Binary files /dev/null and b/01-intro-to-java/lecture/images/01.8-java-app.png differ diff --git a/01-intro-to-java/lecture/images/01.9-variables.jpg b/01-intro-to-java/lecture/images/01.9-variables.jpg new file mode 100644 index 00000000..22896a6d Binary files /dev/null and b/01-intro-to-java/lecture/images/01.9-variables.jpg differ diff --git a/01-intro-to-java/lecture/slides.html b/01-intro-to-java/lecture/slides.html new file mode 100644 index 00000000..eb19c8ff --- /dev/null +++ b/01-intro-to-java/lecture/slides.html @@ -0,0 +1,29 @@ + + + + [MJT2024] Modern Java Technologies Lecture + + + + + + + + + + + + + diff --git a/01-intro-to-java/lecture/slides.md b/01-intro-to-java/lecture/slides.md new file mode 100644 index 00000000..fb4b1424 --- /dev/null +++ b/01-intro-to-java/lecture/slides.md @@ -0,0 +1,963 @@ +class: center, middle + +# Въведение в Java + +11.10.2023 + +--- + +### Какво е Java? + +- Език за програмиране +- Java компилатор +- Java виртуална машина (JVM) +- Java Development Kit (JDK) + - Java Runtime Environment (JRE) +- Java платформа + +--- + +### Java Editions + +- Java Edition е вариация на Java платформата (JDK-то), асемблирана за различна цел + - Java Platform Standard Edition (Java SE) + - Java Platform Enterprise Edition (Java EE) + - Java Platform Micro Edition (Java ME) + - vs. Android SDK + - Java Card + +--- + +### JDK инструменти + +- Основни + - javac + - java +- Допълнителни + - jshell + - javadoc + - jar + - ... + +--- + +### Java: най-популярните IDE-та + +1. IntelliJ IDEA +![IntelliJ IDEA logo](images/01.1-intellij-logo.jpg) + +2. Eclipse +![Eclipse logo](images/01.2-eclipse-logo.jpeg) + +3. Visual Studio Code +![Visual Studio Code logo](images/01.3-vscode-logo.jpg) + +4. NetBeans +![NetBeans logo](images/01.4-netbeans-logo.jpg) + +--- + +### Езикът Java + +- Създаден през 1995 от James Gosling (Sun Microsystems) +- Актуална версия: Java 21 (released 19.09.2023) + +![Java logo and mascot](images/01.5-java-logo-mascot.png) + +--- + +### Езикът Java + +![JEP per release](images/01.6-jep-per-release.png) + +--- + +### Езикът Java + +- Обектно-ориентиран +- Със C/C++ синтаксис +- "Write once, run anywhere" + +--- + +### Hello world! + +```java +public class HelloWorldApp { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} +``` + +
+ +```bash +$ javac HelloWorldApp.java +$ java HelloWorldApp +Hello world! +``` + +--- + +### Hello world, Java 21 style! + +![Hello World 21 style](images/01.7-hello-world-21.jpeg) + +```java +// Java 21 preview: Unnamed Classes and Instance Main Methods +void main() { + System.out.println("Hello world!"); +} +``` + +
+ +```bash +$ javac --enable-preview --source 21 HelloWorld.java +$ java --enable-preview HelloWorld +Hello world! +``` + +--- + +### Стандартно Java приложение + +.center[ + +![Java app diagram](images/01.8-java-app.png) + +] + +--- + +### Java виртуалната машина (JVM) + +- Интерпретира и изпълнява byte код инструкции +- Компилира по време на изпълнението byte кода до машинен код +- Заделя памет за оперативните данни +- Автоматично изчиства паметта +- Зарежда класове +- Стартира нишки +- Взаимодейства с операционната система + +--- + +### Ще започнем с езика Java от... + +- Tиповете данни +- Оператори, изрази, statements +- Условия и разклонения +- Итерация / Цикли +- Низове и операции с тях +- Масиви +- Функции + +--- + +### Tипове данни и променливи + +- Тип данни == множество стойности + операции върху тях +- Java е статично типизиран език → всички променливи трябва да бъдат декларирани, преди да бъдат използвани, и типът на дадена променлива се фиксира в декларацията ѝ и не може да се променя +- Декларацията включва името и типа, и може да е съчетана (или не) с инициализация + +--- + +### Tипове данни и променливи + +.center[![Variables](images/01.9-variables.jpg)] + +--- + +### Tипове данни + +- Примитивни типове + - Булев (boolean) тип + - Числени (numeric) типове + - Целочислени (integral) типове + - Типове за числа с плаваща запетая (floating-point) +- Reference типове + +--- + +### Примитивни типове данни + +| Тип данни | Размер | Минимум | Максимум | +| :-------- | :------ | :-------------- | :------------------------- | +| boolean | - | - | - | +| byte | 8 бита | -128 | +127 | +| char | 16 бита | Unicode 0 | Unicode 216 - 1 | +| short | 16 бита | -215 | +215 - 1 | +| int | 32 бита | -231 | +231 - 1 | +| long | 64 бита | -263 | +263 - 1 | +| float | 32 бита | IEEE754 | IEEE754 | +| double | 64 бита | IEEE754 | IEEE754 | +| void | - | - | - | + +--- + +### Минимална и максимална стойност на примитивните типове + +```java +Byte.MIN_VALUE // -128 +Byte.MAX_VALUE // 127 +Short.MIN_VALUE // -32768 +Short.MAX_VALUE // 32767 +Integer.MIN_VALUE // -2147483648 +Integer.MAX_VALUE // 2147483647 +Long.MIN_VALUE // -9223372036854775808 +Long.MAX_VALUE // 9223372036854775807 +(int) Character.MIN_VALUE // 0 +(int) Character.MAX_VALUE // 65535 +``` +--- + +### Типът char + +- цяло число без знак +- стойност (*code point*) от 0 до 65535 включително +- представя Unicode символ +- може да участва в аритметични операции (със своя code point) + +--- + +### Типът char + +| Code point | Unicode escape | Печатна репрезентация | Описание | +| ---------- | -------------- | --------------------- | :-------------------------------- | +| 33 | \u0021 | ! | Символ за удивителна | +| 50 | \u0032 | 2 | Цифра 2 | +| 65 | \u0041 | A | Главна латинска буква 'A' | +| 9203 | \u23F3 | ⏳ | Hourglass with Flowing Sand emoji | + +--- + +### Литерали на примитивните типове + +```java +int i = 1; // int by default +long l = 1L; // L or l +double d = 0.1; // d or D is optional +double d2 = 1e-1; // same, in scientific +float f = 0.1; // will not compile, why? +char c = 'A'; +char c2 = '\u0041'; // again, 'A' +``` + +--- + +### Целочислени литерали + +```java +// The number 26, in decimal +int decVal = 26; + +// The number 26, in hexadecimal +int hexVal = 0x1a; + +// The number 26, in binary +int binVal = 0b11010; + +// The number 26, in octal +int octVal = 032; +``` + +--- + +### Литерали с подчертавка: syntactic sugar + +```java +int thousand = 1_000; +int million = 1_000_000; +long magic = 0xCAFE_BABE; +int one = 0b1; +int mask = 0b1010_1010_1010; +``` + +--- + +### Стойности по подразбиране + +Компилаторът **не** присвоява стойности по подразбиране на неинициализираните локални променливи! + +--- + +### Стойности по подразбиране + +| Тип данни | Стойност по подразбиране | +| :--------------- | :----------------------- | +| boolean | false | +| short | 0 | +| int | 0 | +| long | 0L | +| float | 0.0f | +| double | 0.0d | +| char | '\u0000' | +| Reference типове | null | + +--- + +### Конвертиране на типовете + +- Имплицитно - без загуба на точност +- Експлицитно - чрез cast + +
+ +| Израз | Тип на израза | Стойност на израза | +| :---------------- | :------------ | :----------------- | +| "1234" + 99 | String | "123499" | +| (int) 2.71828 | int | 2 | +| 11 \* 0.3 | double | 3.3 | +| (int) 11 \* 0.3 | double | 3.3 | +| 11 \* (int) 0.3 | int | 0 | +| (int) (11 \* 0.3) | int | 3 | + +--- + +### Защо ни трябват типове? + +- За да ни помага компилаторът в откриването на грешки + +![Java app diagram](images/01.10-rocket.jpg) + +.font-xs[През 1996, ракетата Ариана 5 експлодира след излитане поради софтуерна грешка в конвертирането на типове (опит да „набута“ 64-битово число в 16 бита).] + +--- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператориПриоритет
postfixexpr++ expr--
unary++expr --expr +expr -expr ~ !
multiplicative\* / %
additive+ -
shift<< >> >>>
relational< > <= >= instanceof
equality== !=
bitwise AND&
bitwise exclusive OR^
bitwise inclusive OR|
logical AND&&
logical OR||
ternary? :
assignment= += -= *= /= %= &= ^= |= <<= >>= >>>=
+ +--- + +### Wrapper types + +- Представляват референтни аналози на примитивните типове +- Използват се + - където синтаксисът на езика изисква обект, а не примитивен тип + - когато ни трябват константи или помощни функции, които са имплементирани в съответния wrapper клас +- имплицитно се конвертират към съответния си примитивен тип, и обратно + +--- + +### Примитивни типове и wrapper типове + +| Тип данни | Размер | Минимум | Максимум | Wrapper | +| :-------- | :------ | :-------------- | :--------------------------| :-------- | +| boolean | - | - | - | Boolean | +| char | 16 бита | Unicode 0 | Unicode 216 - 1 | Character | +| byte | 8 бита | -128 | +127 | Byte | +| short | 16 бита | -215 | +215 - 1 | Short | +| int | 32 бита | -231 | +215 - 1 | Integer | +| long | 64 бита | -263 | +263 - 1 | Long | +| float | 32 бита | IEEE754 | IEEE754 | Float | +| double | 64 бита | IEEE754 | IEEE754 | Double | +| void | - | - | - | Void | + +--- + +### Константи и utility методи във wrapper типовете + +```java +Integer.MAX_VALUE // максималната стойност на типа +Integer.MIN_VALUE // минималната стойност на типа +Integer.valueOf(25) // връща Integer инстанция, "опаковаща" 25 +Integer.intValue() // връща int стойността, "опакована" в дадената инстанция +Integer.parseInt(String) // конвертира низ с текстово представяне на цяло число към int + +Character.isDigit('7') // true +Character.isLetter('f') // true +Character.isLetterOrDigit('!') // false +Character.isEmoji('⏳') // true. Since Java 21 +``` + +--- + +### Autoboxing + +```java +// инициализиране на променлива от тип char с литерал +char c = 'a'; + +// инициализирaне на Character обект с литерал +Character ch1 = new Character('a'); + +// autoboxing: char implicitly converted to Character +Character ch2 = 'x'; + +// wrapper to primitive conversion +char c2 = ch1; +``` + +--- + +### Низове в Java + +- Низовете са reference тип, а не примитивен +- Инстанции са на `String` класа +- Immutable са: всяка промяна води до създаване на нов `String` обект, а старият остава непроменен + +--- + +### Низовете в паметта: string pool vs heap + +- `String` литералите се създават в специална област на паметта на JVM-a, наречена *string pool* +- При опит за добавяне на низ в string pool-a, ако там вече съществува низ със същото съдържание, не се създава нов обект, а се връща референция към съществуващия (→ пести се памет) + +--- + +### Низовете в паметта: string pool vs heap + +- `String` обектите, създадени с оператора `new`, се създават в динамичната памет (heap-a). Всеки низ в heap-a е отделна инстанция, дори съдържанието на два и повече низа да е идентично +- `String` обект може да се прехвърли от heap-a в string pool-a чрез извикване на метода му `intern()` + +--- + +### Сравняване на низове + +- Сравняването на низове с `==` е сравнение на съответните референции +- Сравняването на низове за идентичност като съдържание се прави с метода `equals()` на `String` класа + +--- + +### Низовете в паметта: string pool vs heap + +```java +String literalOne = "FMI"; // goes to the string pool +String literalTwo = "FMI"; // "FMI" is present in the String pool -> + // literalTwo will refer to the same object + +System.out.println(literalOne == literalTwo); // true + +String newString = new String("FMI"); // new object in the heap + +System.out.println(literalOne == newString); // false +System.out.println(literalOne.equals(newString)); // true + +String intern = newString.intern(); // adds the string to the pool + // and returns a reference to it +System.out.println(literalOne == newString); // false, newString + // is not reassigned +System.out.println(literalOne == intern); // true +``` + +--- + +### Низове - литерали, конкатениране + +```java +String language = "Java"; +String tbd = null; +String message = "I <3 " + language; +String year = "The current year is " + 2023; +``` + +--- + +### Многоредови низови литерали + +```java +// multi-line string literals before +String html = "\n" + + " \n" + + "

Hello world!

\n" + + " \n" + + "\n"; + +// since Java 15: text blocks for multi-line string literals +String html = """ + + +

Hello world!

+ + + """; +``` + +--- + +### Низове - обхождане + +```java +String s = "Firebird"; +char ic = s.charAt(i); +char[] ca = s.toCharArray(); + +for (int i = 0; i < ca.size(); i++) {...} +for (char c : ca) {...} // enhanced for-loop, a.k.a. for-each + +Arrays.sort(ca); +String sorted = String.valueOf(ca); // "Fbdeiirr" +``` + +--- + +### String.split() + +```java +String str1 = "Current year is 2023"; + +String[] tokens = str1.split(" "); // разделител – интервал + +// tokens = ["Current", "year", "is", "2023"] + +int year = Integer.parseInt(tokens[3]); +// year == 2023 +``` + +--- + +### Други операции с низове + +Класът `String` има още много методи, реализиращи операции, които ще ни потрябват. +Разгледайте ги в [документацията](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/String.html) на класа. + +--- + +### Mutable низове + +Когато имаме нужда от mutable низове, т.е. такива, промяната на които да не води до създаване на нова инстанция, вместо `String` трябва да използваме класовете `StringBuilder` или `StringBuffer`. + +
+ +| Class name | Mutable | Performant | Thread-safe | +| :------------ | :------ | :---------------- | :---------- | +| String | no | slow, if modified | yes | +| StringBuilder | yes | fast | no | +| StringBuffer | yes | slower | yes | + +--- + +### Local variable type inference + +```java +// since Java 10 +var message = "FMI rulez!"; // local variable type inference + +message = "Cool"; // variable can be reassigned + +message = 1; // will not compile: type is fixed upon declaration and cannot change + +var mystery; // will not compile: type cannot be inferred without initializer +``` + +--- + +### Булеви константи + +- `true` или `false` +- За разлика от С/С++, не може да се използва число вместо булев израз + +--- + +### Побитови и булеви логически оператори + +``` +| the OR operator +& the AND operator +^ the XOR operator +! the NOT operator +|| the short-circuit OR operator +&& the short-circuit AND operator +== the EQUAL TO operator +!= the NOT EQUAL TO operator +``` + +--- + +### Булеви логически оператори + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ABA|BA&BA^B!A
falsefalsefalsefalsefalsetrue
truefalsetruefalsetruefalse
falsetruetruefalsetruetrue
truetruetruetruefalsefalse
+ +--- + +### if-else + +```java +if (booleanExpression) { + // statements +} + +if (booleanExpression) { + // statements +} else { + // statements +} +``` + +--- + +### Операторът ? : + +```java +// the only ternary (i.e. three-argument) operator in Java +condition ? statement1 : statement2 + +// the above is equivalent to +if (condition) { + statement1 +} else { + statement2 +} +``` + +--- + +### Итерация - while + +```java +while (booleanExpression) { + statement +} +``` + +--- + +### Итерация - do-while + +```java +do { + statement +} while (booleanExpression); +``` + +--- + +### Итерация - for + +```java +for (initialization; booleanExpression; step) { + statement +} +``` + +--- + +### Безусловно разклонение на изпълнението + +- `return [value]` +- `break [label]` +- `continue [label]` +- Няма `goto` (ключовата дума е запазена, но не е използвана) + +--- + +### Switch + +```java +switch (selector) { + case value1 : statement; break; + case value2 : statement; break; + case value3 : statement; break; + // [... ] + default: statement; +} +``` + +--- + +### Подобрен `switch` (от Java 15) + +```java +char ch = 'a'; +int t; + +// before +switch (ch) { + case 'a' : t = 1; break; + case 'b', 'c' : t = 12; break; + default : t = 27; +} + +// since Java 15 +switch (ch) { + case 'a' -> t = 1; + case 'b', 'c' -> t = 12; + default -> t = 27; +} +``` + +--- + +### Подобрен `switch` като израз (от Java 15) + +```java +int z = switch (ch) { + case 'a' -> 1; + case 'b', 'c' -> 12; + default -> 27; +}; + +int r = switch (ch) { + case 'a' : yield 1; + case 'b' : yield 12; + default : yield 27; +}; +``` + +--- + +### Pattern matching for `switch` (от Java 21) + +```java +String s = switch(obj) { + case Integer i when i > 100 -> "It's an Integer > 100"; // "guarded pattern" + case Integer i -> "It's an Integer"; + case String s -> "It's a String"; + case null -> "It's a null reference"; // able to handle null references + default -> "It is none of the known data types"; +}; +``` + +--- + +### Масиви + +.center[![Array](images/01.11-array.jpg)] + +--- + +### Масиви + +```java +int[] a; // preferred syntax +int a[]; // also valid + +// explicit initialization +// can be done only during declaration +int[] a = {1, 2, 3, 4}; + +int[] b = new int[7]; +b.length; +``` + +--- + +### Масиви + +- Декларация – не се заделя памет за елементите на масива +- Инициализация – заделя се памет за елементите на масива +- Масивите от примитивни типове се инициализират автоматично със стойността по подразбиране на съответния тип + +--- + +### Многомерни масиви + +```java +int[][] a; +a = new int[3][4]; + +int[][] b = { + { 1, 0, 12, -1 }, + { 7, -3, 2, 5 }, + { -5, -2, 2, -9 }, +}; +``` + +![Matrix](images/01.12-matrix.jpg) + +--- + +### Многомерни масиви + +```java +double[][] matrix = new double[7][]; +// rows have not yet been created + +for (int i = 0; i < 7; i++) { + // Create row i with i + 1 elements. + matrix[i] = new double[i+1]; +} +``` + +--- + +### Операции с масиви + +```java +System.arraycopy(src, srcPos, dest, destPos, length); // копиране + +Arrays.equals(arr1, arr2); // проверка за еднаквост +Arrays.fill(arr, value); // запълване с дадена стойност +Arrays.toString(arr); // конвертиране в низ +``` + +--- + +### Операции с масиви + +```java +Arrays.sort(arr); // сортиране +Arrays.sort(a, Collections.reverseOrder()); // сортиране в обратен ред +``` + +--- + +### Класът `Math` + +```java +Math.abs(v); // връща абсолютната стойност на число +Math.min(v1, v2); // връща по-малкото от две числа +Math.max(v1, v2); // връща по-голямото от две числа +Math.pow(x, y); // връща x на степен y +Math.sqrt(v); // връща корен квадратен от число +Math.round(v); // връща числото, закръглено до цяло +Math.random(); // връща псевдослучайно число в интервала [0.0, 1.0) + +// много други математически функции + +if (value < min) { + value = min; +} else if (value > max) { + value = max; +} + +// since Java 21 +value = Math.clamp(value, min, max); // връща value, ако е в интервала [min, max], или границата + +``` + +--- + +### Функции + +.center[![Functions](images/01.13-funcs.jpg)] + +--- + +Писане на стандартния изход + +```java +System.out.println("Something printed on the console"); +``` + +
+ +Четене от стандартния вход + +```java +import java.util.Scanner; +// [...] + +Scanner sc = new Scanner(System.in); +String lineRead = sc.nextLine(); + +// [...] +``` + +--- + +.center[![Thinking in Java](images/01.14-thinking-in-java.jpg)] + +--- + +.center[![Effective Java](images/01.15-effective-java.jpg)] + +--- + +## Въпроси? + +.font-xl[.ri-github-fill.icon-inline[[fmi/java-course](https://github.com/fmi/java-course)]] + +.font-xl[.ri-youtube-fill.icon-inline[[MJT2024](https://www.youtube.com/playlist?list=PLew34f6r0Pxyldqe31Txob2V3M3m1MKCn)]] diff --git a/README.md b/README.md index b3b84538..3e0e1106 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ [График на курса](https://github.com/fmi/java-course/tree/master/docs/00-schedule) -### Лекции и упражнения 2022/2023 +### Лекции и упражнения 2023/2024 | # | Тема | Лекция | Видео | Дата | Упражение | Видео | Дата | | - | :--- | :----- | :---- | :--- | :-------- | :---- | :--- | -| 1 | Въведение в Java | | | 11.10 | | | 14.10 | +| 1 | Въведение в Java | [слайдове](https://fmi.github.io/java-course/01-intro-to-java/lecture/slides.html) | | 11.10 | | | 14.10 | ### Материали от предходни издания