Compare commits
18 Commits
61e293f81b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c513ce326f | |||
| 9361978648 | |||
| 8f42d4a320 | |||
| c654fcd9c2 | |||
| 2ec4a7e7db | |||
| 283660b9ef | |||
| f0817da47e | |||
| c9bc96dafc | |||
| 6538742678 | |||
| a7f8e74f3f | |||
| 9b0c9f4b4a | |||
| b62e54bbb0 | |||
| 6853ada348 | |||
| 4d0e404259 | |||
| da3ad9dd1a | |||
| 005017595b | |||
| 23a9e06d53 | |||
| 8c95d15f6c |
@@ -0,0 +1,27 @@
|
|||||||
|
## Учебная архитектура
|
||||||
|
## Реальные VLIW и Эльбрус
|
||||||
|
### Виды параллелизма
|
||||||
|
> [!warning] Эта часть должна переехать в часть лекций
|
||||||
|
1. На уровне инструкций
|
||||||
|
- Конвейризация
|
||||||
|
- Суперскалярность
|
||||||
|
- Длинные машинные слова (very long instruction word)
|
||||||
|
2. На уровне данных
|
||||||
|
- Векторы
|
||||||
|
3. На уровне потоков - многопоточность
|
||||||
|
4. На уровне процессов - много ядер в процессоре
|
||||||
|
### Оптимизация обращений к памяти
|
||||||
|
- Есть спекулятивные команды, по типу спекулятивного чтения. В самом начале процессор читает, а если нигде по итогу не использовалось, то прочитанное значение отваливается.
|
||||||
|
- Оптимизация обращений к памяти в цикле: вместо `load -> alu -> store` компилятор расслаивает итерации и делает `store i -> alu i+1 -> load i+2` (i - номер итерации)
|
||||||
|
### Оптимизация переходов
|
||||||
|
Переход довольно затратная операция для конвейрных процессоров. Виды оптимизаций:
|
||||||
|
1. Штраф за переход и просто все этапы конвейера сбрасываются (самый простой вариант, на практике встречается редко)
|
||||||
|
2. В Эльбрусе - предикаты, выполняются обе ветки (if-else) а потом записывает только то, что в предикате. Превращает Control Flow в Data Flow. Используется только для коротких веток (3-5 команд). Логика: команды сравнения записывают в регистровый файл предикатов 0 или 1. Компилятор ставит абсолютно все команды в поток исполнения (и из if, и из else), но ставит специальные биты в команду: номер предиката, который контроллирует выполнение. Дальше команды исполняются, на этапе декода процессор видит предикат, а на этапе записи в память делает операцию, только если управляющий предикат - 1. (P.S. такое же было и в Intel Itanium)
|
||||||
|
3. Предикт переходов, в cisc - это делает процессор (у него маленькая область видимости, поэтому может быть неэффективно), в vliw - это делает компилятор (компилятор видит всю программу целиком и может отлично с этим справится). Процессор готовится к переходу и загружает команды в конвейер. Эльбрус позволяет подготовавливать до трех переходов одновременно.
|
||||||
|
### Регистровое окно и стек регистров
|
||||||
|
- Процессор содержит несколько сотен регистров, каждая фукнция "заказывает" себе у процессора нужное количество, при этом видимые для функции регистров делятся на три группы: регистры с параметрами, регистры для временных вычислений, регистры с параметрами для вызываемой функции. В момент вызова функции регистровый файл виртуально сдвигается вниз - первая и вторая группы не будут видны вызванной функции. Третья группа становится первой, а новые вторые и третью группы функция снова заказывает.
|
||||||
|
- Если процессору не хватает физических регистров для функции, то процессор сам в фоновом режиме сбрасывает неиспользуемую часть регистрового файла в стек в ОЗУ. При возврате из функции процессор незаметно восстанавливает регистры из стека.
|
||||||
|
- Есть глобальная группа регистров (типичные регистры из cisc, risc)
|
||||||
|
### Безопасность
|
||||||
|
- Несколько стеков: регистры пользователя на одном, адрес возврата и состояние процессора - на другом - защита от buffer overflow и подмены адреса возврата
|
||||||
|
- Процессор различает в памяти указатели и сами данные. В Эльбрусе нельзя создать указатель не из указателя. При этом первичный указатель безопасно получается специальными командами и механизмами в процессоре
|
||||||
@@ -4,4 +4,6 @@
|
|||||||
- [x86_64](x86_64.md) (реальная архитектура)
|
- [x86_64](x86_64.md) (реальная архитектура)
|
||||||
- [acc32](acc32.md)
|
- [acc32](acc32.md)
|
||||||
- [f32a](f32a.md)
|
- [f32a](f32a.md)
|
||||||
- [m68k](m68k.md)
|
- [m68k](m68k.md) (будет)
|
||||||
|
- [risc-iv](risc-iv.md) (будет)
|
||||||
|
- [vliw-iv](vliw-iv.md) (в работе, есть интересные факты про Эльбрус)
|
||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
Повседневные или почти вещи
|
Повседневные или почти вещи
|
||||||
- [Linux](Linux.md)
|
- [Linux](Linux.md)
|
||||||
- [Полезные утилиты и сайты](Полезные%20утилиты%20и%20сайты.md)
|
- [Полезные утилиты и сайты](Полезные%20утилиты%20и%20сайты.md)
|
||||||
- [VPN](VPN.md)
|
- [VPN](VPN.md)
|
||||||
|
- [Миграция с npm на npmplus](Миграция%20с%20npm%20на%20npmplus.md)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Может меняться, актуальная информация в [ридми](https://github.com/ZoeyVid/NPMPlus#migration-from-upstreamvanilla-nginx-proxy-manager)
|
||||||
|
1.
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
Очень "полезные" материалы
|
Очень "полезные" материалы
|
||||||
[Java](Программирование%20на%20Java/Java.md) - полный, ультимативный гайд по жабе (WIP)
|
[Java](Программирование%20на%20Java/Java.md) - полный, ультимативный гайд по жабе (WIP)
|
||||||
[АиСД](АиСД/АиСД.md)- разбор задач на алгоритмы и структуры данных (пока что только с литкода), позже будут добавлены шаблоны для методов, описание каждой из структур данных и много чего еще
|
[АиСД](АиСД/АиСД.md)- разбор задач на алгоритмы и структуры данных (пока что только с литкода), позже будут добавлены шаблоны для методов, описание каждой из структур данных и много чего еще
|
||||||
[ИТМО](Итмо/3%20сем.md) - список предметов на текущий семестр + базовые требования + материалы
|
[ИТМО](Итмо/ИТМО.md) - список предметов на текущий семестр + базовые требования + материалы
|
||||||
[Веб](Веб/Веб.md) - лекции и заметки по Веб-программированию
|
[Веб](Веб/Веб.md) - лекции и заметки по Веб-программированию
|
||||||
[Computer Science](Computer%20Science/Computer%20Science.md) - лекции и материалы по АК+ОПД+PL и в целом база по CS
|
[Computer Science](Computer%20Science/Computer%20Science.md) - лекции и материалы по АК+ОПД+PL и в целом база по CS
|
||||||
[Экзамен](ОПД/Экзамен.md) - разбор экзамена по ОПД за 2 семестр
|
[Экзамен](ОПД/Экзамен.md) - разбор экзамена по ОПД за 2 семестр
|
||||||
|
|||||||
@@ -1,3 +1,47 @@
|
|||||||
- Все запросы могут обрабатываться одним процессом CGI-программы
|
- Все запросы могут обрабатываться одним процессом CGI-программы
|
||||||
- Веб-сервер взаимодействует с процессом через UNIX Domain Sockets или TCP/IP (а не через stdin и stdout)
|
- Веб-сервер взаимодействует с процессом через UNIX Domain Sockets или TCP/IP (а не через stdin и stdout)
|
||||||
- Для общения используется бинарный протокол, обеспечивающий передачу любых текстовых данных
|
- Для общения используется бинарный протокол, обеспечивающий передачу любых текстовых данных
|
||||||
|
## FastCGI на Java
|
||||||
|
Пример
|
||||||
|
```Java
|
||||||
|
public static void main(String[] args) {
|
||||||
|
FCGIInterface fcgiInterface = new FCGiInterface();
|
||||||
|
while (fcgiInterface.FCGIAccept() >= 0) {
|
||||||
|
String content = """
|
||||||
|
<html>...</html>
|
||||||
|
""";
|
||||||
|
String response = """
|
||||||
|
HTTP /1.1 200 OK
|
||||||
|
Content-Type: text/html
|
||||||
|
Content-Length: %d
|
||||||
|
|
||||||
|
|
||||||
|
%s
|
||||||
|
""".formatted(content.getBytes(StandardCharsets.UTF_8).length, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- `FCGIInterface` - реализует магию по перенаправлению `System.in`, `System.out` и `System.err` в потоки TCP сокета. Поля для запросов и сокета - статические
|
||||||
|
- `FCGIInterface.request.params` - объект `Properties`, через который можно узнать список параметров, переданных веб-сервером
|
||||||
|
- Наиболее значимые параметры:
|
||||||
|
- `REQUEST_METHOD` - Get, Post и тд
|
||||||
|
- `QUERY_STRING` - параметры запроса после `?`
|
||||||
|
- `CONTENT_TYPE` - значение заголовка запроса
|
||||||
|
- `CONTENT_LENGTH` - значение заголовка запроса
|
||||||
|
Еще пример
|
||||||
|
```Java
|
||||||
|
private static String readRequestBody() throws IOException {
|
||||||
|
FCGIInterface.request.inStream.fill();
|
||||||
|
|
||||||
|
var contentLength = FCGIInterface.request.inStream.available();
|
||||||
|
var buffer = ByteBuffer.allocate(contentLength);
|
||||||
|
var readBytes = FCGIInterface.request.inStream.read(buffer.array(), 0, contentLength);
|
||||||
|
|
||||||
|
var requestBodyRaw = new byte[readBytes];
|
||||||
|
buffer.get(requestBodyRaw);
|
||||||
|
buffer.clear();
|
||||||
|
|
||||||
|
return new String(requestBodyRaw, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,306 @@
|
|||||||
|
## Платформа Java EE
|
||||||
|
- Набор стандартов и спецификаций для создания корпоративных приложений на Java
|
||||||
|
- Спецификации Java EE реализуются серверами приложений
|
||||||
|
- Apache Tomcat
|
||||||
|
- Sun/Oracle GlassFish
|
||||||
|
- BEA/Oracle WebLogic
|
||||||
|
- IBM WebSphere
|
||||||
|
- RedHat JBoss
|
||||||
|
## Сервлеты
|
||||||
|
- [Серверные сценарии](Серверные%20сценарии.md) написанные на Java
|
||||||
|
- Жизненным циклов сервлетов управляет веб-контейнер (он же контейнер сервлетов)
|
||||||
|
- В отличие от [CGI](CGI.md) запросы обрабатываются в отдельных потоках (а не процессах) на веб-контейнере
|
||||||
|
## Преимущества
|
||||||
|
- Выполняются быстрее, чем CGI-сценарии
|
||||||
|
- Хорошая масштабируемость
|
||||||
|
- Надежность и безопасность
|
||||||
|
- Платформенно-независимы
|
||||||
|
- Множество инструментов мониторинга и отладки
|
||||||
|
## Недостатки
|
||||||
|
- Слабое разделение уровня представления и бизнес-логики
|
||||||
|
- Возможны конфликты при параллельной обработке запросов
|
||||||
|
## Обработка HTTP-запроса
|
||||||
|
1. Браузер формирует [HTTP](../Сеть%20и%20API/HTTP.md)-запрос и отправляет его на сервер
|
||||||
|
2. Веб-контейнер создает объекты `HttpServletRequest` и `HttpServletResponse`
|
||||||
|
3. Веб-контейнер вызывает метод `service` у сервлета
|
||||||
|
4. Сервлет формирует ответ и записывает его в поток вывода `HttpServletResponse`
|
||||||
|
## Пример сервлета
|
||||||
|
```Java
|
||||||
|
package sample.servlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
public class SampleServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
String pageTitle = "Пример сервлета";
|
||||||
|
response.setContentType("text/html");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
out.println("<html>");
|
||||||
|
...
|
||||||
|
out.println("</html>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Конфигурация сервлета
|
||||||
|
Конфигурирование происходит в `WEB-INF/web.xml` (есть конечно аннотации, но это слишком современно). В `WEB-INF/classes` должны лежать скомпилированные джава-классы
|
||||||
|
```xml
|
||||||
|
<!-- Регистрируем сервлет -->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>SampleServlet</servlet-name>
|
||||||
|
<servlet-class>org.itmo.sample.SampleServlet></servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<!-- Маппинг -->
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>SampleServlet</servlet-name>
|
||||||
|
<url-pattern>/sample</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
```
|
||||||
|
Полный файл `web.xml`
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app>
|
||||||
|
|
||||||
|
<!-- Регистрируем сервлет -->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>SampleServlet</servlet-name>
|
||||||
|
<servlet-class>org.itmo.sample.SampleServlet></servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<!-- Маппинг -->
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>SampleServlet</servlet-name>
|
||||||
|
<url-pattern>/sample</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
||||||
|
```
|
||||||
|
## Жизненный цикл сервлета
|
||||||
|
- Жизненным циклом управляет веб-контейнер
|
||||||
|
- Методы, управляющие жизненным циклом, должен вызывать только веб-контейнер
|
||||||
|
### 1. Загрузка класса сервлета
|
||||||
|
Проверяются пути: `WEB-INF/classes/`, `WEB-INF/lib/*.jar`, стандартные классы Java SE и классы веб-контейнера
|
||||||
|
```xml
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>SampleServlet</servlet-name>
|
||||||
|
<servlet-class>org.itmo.sample.SampleServlet></servlet-class>
|
||||||
|
|
||||||
|
<!-- Этот параметр можно получить через унаследованный метод getInitParametr(paramName); -->
|
||||||
|
<init-param>
|
||||||
|
<param-name>say-hello</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</init-param>
|
||||||
|
</servlet>
|
||||||
|
```
|
||||||
|
### 2. Создание экземпляра сервлета
|
||||||
|
Создание через конструктор `new SampleServlet()`
|
||||||
|
### 3. Вызов метода init()
|
||||||
|
`init(config)` - принимает `config`
|
||||||
|
### 4. Обработка HTTP-запросов
|
||||||
|
На каждый запрос в новом потоке (на самом деле там пул потоков) вызывается метод `service()`
|
||||||
|
### 5. Уничтожение сервлета
|
||||||
|
Вызов метода `destroy()`
|
||||||
|
## Контекст сервлетов
|
||||||
|
- API, с помощью которого сервлет может взаимодействовать со своим контейнером
|
||||||
|
- Доступ к методам осуществляется через интерфейс `javax.servlet.ServletContext`
|
||||||
|
- У всех сервлетов внутри приложения общий контекст
|
||||||
|
- В контекст можно помещать общую для всех сервлетов информацию (методы `getAttribute` и `setAttribute`)
|
||||||
|
- Если приложение - распределенное, то на каждом экземпляре JVM контейнером создается свой контекст
|
||||||
|
```Java
|
||||||
|
import java.io.*;
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
|
||||||
|
public class DemoServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
|
||||||
|
res.setContentType("text/html");
|
||||||
|
PrintWriter pw = res.getWriter();
|
||||||
|
|
||||||
|
ServletContext context = getServletContext();
|
||||||
|
String driverName = context.getInitParameter("dname");
|
||||||
|
pw.println("driver name: " + driverName);
|
||||||
|
pw.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
В `web.xml` до сервлетов
|
||||||
|
```xml
|
||||||
|
<context-param>
|
||||||
|
<param-name>dname</param-name>
|
||||||
|
<param-value>org.postgresql.Driver</param-value>
|
||||||
|
</context-param>
|
||||||
|
```
|
||||||
|
## HTTP-сессии
|
||||||
|
- Напомним, что HTTP - stateless
|
||||||
|
- `javax.servlet.HttpSession` - интерфейс, позволяющий идентифицировать конкретного клиента (браузер) при обработке множества HTTP-запросов от него
|
||||||
|
- Экземпляр `HttpSession` создается при первом обращении клиента к предложению и сохраняется некоторое (настраиваемое) время после последнего обращения
|
||||||
|
- Идентификатор сессии либо помещается в `cookie`, либо добавляется к URL. Если удалить этот идентификатор, то сервер создаст новую сессию
|
||||||
|
- В экземпляр `HttpSession` можно помещать общую для этой сессии информацию (`getAttribute` и `setAttribute`)
|
||||||
|
- Сессия привязана к конкретному приложению, у разных приложений - разные сессии
|
||||||
|
- В распределенном окружении обеспечивается сохранение целостности данных в HTTP-сессии
|
||||||
|
```Java
|
||||||
|
public class SimpleSession extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
response.setContentType("text/html");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
|
||||||
|
out.println("<html>");
|
||||||
|
...
|
||||||
|
out.println("session id: " + session.getId());
|
||||||
|
out.println("session timeout: " + session.getMaxInactiveInterval());
|
||||||
|
session.setMaxInactiveInterval(20*60);
|
||||||
|
out.println("new session timeout: " + session.getMaxInactiveInterval());
|
||||||
|
...
|
||||||
|
out.println("</html>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Диспетчиризация запросов сервлетами
|
||||||
|
- Сервлеты могут делегировать обработку запросов другим ресурсам (сервлетам, JSP, HTML-страницам)
|
||||||
|
- Диспетчеризация осуществляется с помощью реализаций интерфейса `javax.servlet.RequestDispatcher`
|
||||||
|
- Два способа получения `RequestDispatcher` - через `ServletRequest` (абсолютный или относительный URL) и `ServletContext` (только абсолютный URL)
|
||||||
|
- Два способа делегирования - `forward` и `include` (в обоих случаях url не меняется)
|
||||||
|
- `forward` - полностью отдает запрос другому сервлету или JSP-странице
|
||||||
|
- `include` - включает в себя обработку запроса от другого сервлета или JSP-страницы
|
||||||
|
- Полный редирект (меняется url в браузере, статус-код 302) - `response.sendRedirect(url)`
|
||||||
|
```Java
|
||||||
|
public class MyServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
|
||||||
|
RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp");
|
||||||
|
dispatcher.forward(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Фильтры запросов
|
||||||
|
- Фильтры позволяют осуществлять пред- и постобработку запросов до и после передачи их ресурсу (сервлету, JSP или HTML-странице)
|
||||||
|
- Пример предобработки - допуск только авторизованных пользователей
|
||||||
|
- Пример постобработки - запись в лог времени обработки запроса
|
||||||
|
- Реализуют интерфейс `javax.servlet.Filter`
|
||||||
|
- Ключевой метод `doFilter`
|
||||||
|
- Метод `doFilter` класса `FilterChain` передает управление следующему фильтру или целевому ресурсу, таким образом возможна реализация последовательностей фильтров
|
||||||
|
```Java
|
||||||
|
public class MyFilter implements Filter {
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig arg0) throws ServletException {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
|
||||||
|
PrintWrite out = resp.getWriter();
|
||||||
|
out.print("filter is invoked before");
|
||||||
|
|
||||||
|
chain.doFilter(req, resp); // sends to next resource
|
||||||
|
|
||||||
|
out.print("filter is invoked after);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Конфигурация похожа на конфигурацию сервлетов
|
||||||
|
```xml
|
||||||
|
<web-app>
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>s1</servlet-name>
|
||||||
|
<servlet-class>HelloServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>s1</servlet-name>
|
||||||
|
<url-pattern>/servlet1</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<filter-name>f1</filter-name>
|
||||||
|
<filter-class>MyFilter</filter-class>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>f1</filter-name>
|
||||||
|
<url-pattern>/servlet1</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
||||||
|
```
|
||||||
|
> [!important] Порядок сверху вниз, но если использовать аннотации, то порядок недетерминирован
|
||||||
|
## Конфигурация аннотациями
|
||||||
|
Конфигурация можно писать прямо в Java коде. Tomcat сам сканирует классы и регистрирует компоненты
|
||||||
|
### Сервлеты
|
||||||
|
`@WebServlet` - замена `<servlet>` и `<servlet-mapping>`
|
||||||
|
```Java
|
||||||
|
import jakarta.servlet.annotation.WebServlet;
|
||||||
|
import jakarta.servlet.http.HttpServlet;
|
||||||
|
|
||||||
|
@WebServlet("/api/check")
|
||||||
|
public class CheckServlet extends HttpServlet {}
|
||||||
|
```
|
||||||
|
Продвинутый вариант
|
||||||
|
```Java
|
||||||
|
import jakarta.servlet.annotation.WebServlet;
|
||||||
|
import jakarta.servlet.annotation.WebInitParam;
|
||||||
|
|
||||||
|
@WebServlet(
|
||||||
|
name = "MyCheckLogic", // Аналог <servlet-name>
|
||||||
|
urlPatterns = {"/api/check", "/run"},// Можно привязать сразу несколько URL!
|
||||||
|
loadOnStartup = 1, // Запустить при старте сервера
|
||||||
|
initParams = { // Замена <init-param>
|
||||||
|
@WebInitParam(name = "adminEmail", value = "admin@itmo.ru"),
|
||||||
|
@WebInitParam(name = "maxSize", value = "5000")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class CheckServlet extends HttpServlet { ... }
|
||||||
|
```
|
||||||
|
### Фильтры
|
||||||
|
`@WebFilter` - замена `<filter>` и `<filter-mapping>`
|
||||||
|
```Java
|
||||||
|
import jakarta.servlet.annotation.WebFilter;
|
||||||
|
import jakarta.servlet.Filter;
|
||||||
|
|
||||||
|
@WebFilter(urlPatterns = "/*")
|
||||||
|
public class EncodingFilter implements Filter {}
|
||||||
|
```
|
||||||
|
## Справка по параметрам/аттрибутам
|
||||||
|
### Внешние данные от пользователя
|
||||||
|
- `getParameter()`
|
||||||
|
- Приходит от браузера/клиента по сети
|
||||||
|
- Возвращает `String` или `null`
|
||||||
|
- Находится в URL или в теле запроса
|
||||||
|
- Приоритет у первого query параметра
|
||||||
|
- `String user = request.getParameter("red");`
|
||||||
|
- Если несколько `String[] colors = request.getParameterValues("color");`
|
||||||
|
- Никакого `set` не существует
|
||||||
|
### Внутренние данные приложения
|
||||||
|
- `getAttribute()` и `setAttribute()`
|
||||||
|
- Записывается Java-кодом на сервере. Браузер ничего не знает
|
||||||
|
- Возвращает `Object` или `null`, поэтому требует явного каста
|
||||||
|
- Внутри запроса `HttpServletRequest` - живет 1 запрос
|
||||||
|
- Используется для передачи из Model в View
|
||||||
|
- `request.setAttribute("myUser", new User()); User u = (User) request.getAttribute("myUser");`
|
||||||
|
- Внутри сессии `HttpSession` - живет пока юзер на сайте
|
||||||
|
- `HttpSession session = request.getSession();`
|
||||||
|
- `session.setAttribute("role", "ADMIN")`;
|
||||||
|
- `String role = (String) session.getAttribute("role");`
|
||||||
|
- Внутри контекста `ServletContext` - живет пока работает сервер
|
||||||
|
- `ServletContext context = getServletContext();`
|
||||||
|
- `context.setAttribute()` и `context.getAttribute()`
|
||||||
|
### Метаданные HTTP
|
||||||
|
- `getHeader()`
|
||||||
|
- Приходит от браузера в служебных строках
|
||||||
|
- Возвращает `String` или `null`
|
||||||
|
- `request.getHeader("Authorization");`
|
||||||
|
### Статические настройки из файла конфигурации
|
||||||
|
- `getInitParameter()`
|
||||||
|
- Читается сервером из файла `web.xml` или аннотаций
|
||||||
|
- Возвращает `String` или `null`
|
||||||
|
- `String email = getServletConfig().getInitParameter("email");` - для сервлета
|
||||||
|
- `String dbUrl = getServletContext().getInitParameter("dbUrl");` - для всех сервлетов
|
||||||
@@ -7,4 +7,5 @@
|
|||||||
## Серверная обработка
|
## Серверная обработка
|
||||||
- [Серверные сценарии](Серверные%20сценарии.md)
|
- [Серверные сценарии](Серверные%20сценарии.md)
|
||||||
- [CGI](CGI.md)
|
- [CGI](CGI.md)
|
||||||
- [FastCGI](FastCGI.md)
|
- [FastCGI](FastCGI.md)
|
||||||
|
- [Java Servlets](Java%20Servlets.md)
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
Предметы третьего сема:
|
|
||||||
1. [АК](Предметы/АК.md)
|
|
||||||
2. [Веб-программирование](Предметы/Веб-программирование.md)
|
|
||||||
3. [ЯПы](Предметы/ЯПы.md)
|
|
||||||
4. [Физика](Предметы/Физика.md)
|
|
||||||
5. [Теорвер](Предметы/Теорвер.md)
|
|
||||||
6. [Матан](Предметы/Матан.md)
|
|
||||||
7. [ВТП](Предметы/ВТП.md)
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
## Удобный вход
|
||||||
|
Когда уже есть ssh-ключ ввод пароля становится не обязательным, но порт и имя пользователя с доменом вводить приходится
|
||||||
|
Можно добавить в `.ssh/config`
|
||||||
|
```
|
||||||
|
Host helios
|
||||||
|
HostName se.ifmo.ru
|
||||||
|
User sXXXXXX
|
||||||
|
Port 2222
|
||||||
|
```
|
||||||
|
Теперь вход будет по `ssh helios`
|
||||||
|
## Смена оболочки (на zsh)
|
||||||
|
Скачивать свои пакеты нельзя, но благо zsh уже скачан (в `/usr/local/bin/zsh`)
|
||||||
|
Менять оболочку нормальным способом через `chsh` тоже нельзя, поэтому используем такой костыль: создаем в домашней папке `.bash_profile` и добавляем туда:
|
||||||
|
```bash
|
||||||
|
# Переключаемся на zsh только в интерактивном режиме (чтобы не сломать scp и sftp)
|
||||||
|
if [ -t 1 ] && [ -x /usr/local/bin/zsh ]; then
|
||||||
|
exec /usr/local/bin/zsh -l
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
Теперь у нас zsh
|
||||||
|
### oh-my-zsh
|
||||||
|
1. Устанавливаем oh-my-zsh
|
||||||
|
```bash
|
||||||
|
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||||
|
```
|
||||||
|
2. Скорее всего вылетит ошибка прав, поэтому дефолтный конфиг копируем сами
|
||||||
|
```bash
|
||||||
|
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
|
||||||
|
```
|
||||||
|
3. Скачиваем два базовых дополнения
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
|
||||||
|
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
|
||||||
|
```
|
||||||
|
4. Скачиваем тему `powerlevel10k`
|
||||||
|
```bash
|
||||||
|
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k"
|
||||||
|
```
|
||||||
|
5. Меняем `.zshrc`
|
||||||
|
```
|
||||||
|
|
||||||
|
...
|
||||||
|
ZSH_THEME="powerlevel10k/powerlevel10k"
|
||||||
|
...
|
||||||
|
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
6. Применяем через `source .zshrc`, настраиваем тему
|
||||||
|
7. Для того чтобы заново запустить настройку темы: `p10k`
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
## Текущие предметы
|
||||||
|
1. [АК](Предметы/АК.md)
|
||||||
|
2. [Веб-программирование](Предметы/Веб-программирование.md)
|
||||||
|
3. [ЯПы](Предметы/ЯПы.md)
|
||||||
|
4. [Физика](Предметы/Физика.md)
|
||||||
|
5. [Теорвер](Предметы/Теорвер.md)
|
||||||
|
6. [Матан](Предметы/Матан.md)
|
||||||
|
7. [ВТП](Предметы/ВТП.md)
|
||||||
|
## Полезные материалы
|
||||||
|
- [Гайд](https://github.com/Imtjl/1st-year-guide) на первый курс на гитхабе
|
||||||
|
- [Гайд](https://github.com/Imtjl/2nd-year-guide) на второй курс на гитхабе
|
||||||
|
- [Настройка](Helios.md) Гелиоса
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
kanban-plugin: board
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## В работе
|
||||||
|
|
||||||
|
- [ ] Собрать материалы
|
||||||
|
- [ ] Изучить примеры лабб
|
||||||
|
- [ ] ...
|
||||||
|
|
||||||
|
|
||||||
|
## Выполнено
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%% kanban:settings
|
||||||
|
```
|
||||||
|
{"kanban-plugin":"board","list-collapse":[false,false]}
|
||||||
|
```
|
||||||
|
%%
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[АК лаб 4 доска](АК%20лаб%204%20доска.md) с задачами
|
||||||
|
## Сбор информации
|
||||||
|
- [Пример](https://github.com/ryukzak/brainfuck/tree/master) Пенского
|
||||||
|
- [Таблица](https://github.com/petrovviacheslav/myitmo/tree/main/Computer-System-Architecture) с примерами
|
||||||
|
- [Пример](https://github.com/2BuRy1/itmo/tree/main/%D0%92%D1%82%D0%BE%D1%80%D0%BE%D0%B9%D0%9A%D1%83%D1%80%D1%81/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0%20%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0/%D0%9B%D0%B0%D0%B1%D0%B03/scheme) risc-схемы
|
||||||
|
- [Пример](https://github.com/awesoma31/csa-lab4/tree/19e11019630092c809329798c278da500e169110) alg варианта
|
||||||
|
- [Пример](https://github.com/sultanowskii/drum) варианта на risc схеме
|
||||||
|
- [Пример](https://github.com/Azat2202/itmo-labs/tree/master/2%20year/%D0%90%D0%9A/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%203) варанта на stack схеме
|
||||||
|
## Мой вариант
|
||||||
|
- `alg | risc | harv | hw | trap | port | cstr | vector | alg3`
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# 1 лаба
|
||||||
|
## Быстрый вариант
|
||||||
|
Тут все максимально легко, в лабе три (скорее всего) файла: index.html, style.css и script.js
|
||||||
|
Кидаем эти файлы в `~/public_html` на гелиосе, теперь лаба доступна по ссылке `https://se.ifmo.ru/~sXXXXXX/index.html` (XXXXXX - ваш ИСУшник)
|
||||||
|
## Другие варианты
|
||||||
|
На гелиосе запущен веб-сервер из папки `public_html`, все что вы туда кладете, доступно из интернета (как вот [эти](https://pdmi.zhabka.fun/) презентации)
|
||||||
|
Так что можно сделать папку `lab1` и веб-сервер подтянет `index.html` с оттуда, лаба будет доступна по ссылке `.../~sXXXXXX/lab1`
|
||||||
|
> [!hint] Самый крутой вариант
|
||||||
|
> Если лаба залита на гитхаб/gitea/gitlab/..., то делаем гит клон в удобную папку на гелиосе, а в `public_html` создаем символическую ссылку на нужную папку/файл `index.html`, теперь для обновления лабы на гелиосе можно тупо сделать `git pull`
|
||||||
|
# 2 лаба
|
||||||
|
Тут все сложнее, по требованию задания лабы нужно поднимать `apache httpd` + свой бекенд на FastCGI-либе
|
||||||
|
Пока не мой [гайд](https://www.youtube.com/watch?v=URdECcC25vY) на деплой
|
||||||
|
Также здесь будет гайд на легкий локальный тест в докере + nginx
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
> [!hint]
|
||||||
|
> В старых рубежках может быть актуально все, кроме вопросов о PHP
|
||||||
|
> Нужно знать весь материал лекций до 3.2
|
||||||
|
- [Файл](https://docs.google.com/document/d/11ccQ3H0NNVfMtdiKW1Zxq0woOfk9o-2p0VcKhj4Bz_A/edit?tab=t.0#heading=h.5xocd8wh7ln) для подготовки (от 2025 года)
|
||||||
|
- [Разбор](https://docs.google.com/document/d/1c-9ci-rwhO1EB7cTknReMxZEzvrdazObXMiVpq9Ov3o/edit?tab=t.0) 2022 года
|
||||||
|
- [Билеты](https://docs.google.com/document/d/1EBdskbN0v1942zgW2qu_datoyJ0yoVxBx69D4sPemyk/edit?tab=t.0) 2022 года
|
||||||
|
- [Заметки](https://grove-spandex-678.notion.site/1-fe90f5db40b6477ebd439b9f3229e6ee) в notion
|
||||||
|
- [Еще](https://github.com/AppLoidx/Web-Development-Cheats/blob/master/itmo-university/module%20tests/ModuleTest1Questions.md) 2022 год
|
||||||
|
- [Задания](https://github.com/AppLoidx/Web-Development-Cheats/blob/master/itmo-university/module%20tests/ModuleTest1.md) на код 2022 года
|
||||||
|
- Прошлогодняя [рубежка](https://github.com/sub-myitmo/web-rubezhka1)
|
||||||
|
- [Еще](https://invited-digit-866.notion.site/2022-53c853d396364002b29a1331dfc78bba#80cee9d88a03495ea134ec05a365d43c) заметки в notion от 2022 года
|
||||||
|
## Разбор типовых задач
|
||||||
|
### 1. Сделать слошную синюю границу 2px у текстового ввода внутри класса `auth_form` при фокусе
|
||||||
|
```CSS
|
||||||
|
.auth-form input[type="text"]:focus {
|
||||||
|
border: 2px solid blue;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 2. Написать миксин на SCSS и использовать его в классе `user-card`, добавить вложенный стиль при наведении курсора
|
||||||
|
```SCSS
|
||||||
|
@mixin card-style($bg-color: #ffffff) {
|
||||||
|
background-color: $bg-color;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card {
|
||||||
|
@include card-style;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 3. Написать код на JS, который читает поле ввода, если там число, то выводит удвоенное значение в консоль, иначе сообщение об ошибке в alert
|
||||||
|
```JavaScript
|
||||||
|
const form = document.querySelector("#calcForm");
|
||||||
|
const input = document.querySelector("#numInput");
|
||||||
|
form.addEventListener("submit", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const text = input.value;
|
||||||
|
const number = parseFloat(text);
|
||||||
|
if (isNan(number)) {
|
||||||
|
alert("Введите число");
|
||||||
|
} else {
|
||||||
|
console.log(number*2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
### 4. Написать асинхронную функцию, которая делает POST запрос с координатами точки и возвращает json-ответ
|
||||||
|
```JavaScript
|
||||||
|
async function sendCoordinates(x, y) {
|
||||||
|
const url = "/api/points";
|
||||||
|
const data = {x: x, y: y};
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
const res = await response.json();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 5. Через JQuery поменять элемент с классом `content-box` и вывести значение из поля ввода с id `statusInput`
|
||||||
|
```JavaScript
|
||||||
|
$("#toggle-btn").on("click", () => {
|
||||||
|
$(".content-box").slideUp().css("color", "red");
|
||||||
|
console.log($("#statusInput").val());
|
||||||
|
});
|
||||||
|
```
|
||||||
|
### 6. Написать FCGI-сценарий, который проверяет строку запроса, если там есть слово `ping`, то выводит `pong`. Иначе возвращает 400 ошибку
|
||||||
|
```Java
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
FCGIInterface fcgi = new FCGIInterface();
|
||||||
|
|
||||||
|
while (fcgi.accept() >= 0) {
|
||||||
|
if (FCGIInterface.request == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = FCGIInterface.request.getProperty("QUERY_STRING");
|
||||||
|
if (query != null && query.contains("ping")) {
|
||||||
|
System.out.println("Content-Type: text/plain\n");
|
||||||
|
System.out.println("ping");
|
||||||
|
} else {
|
||||||
|
System.out.println("Status: 400 Bad Request");
|
||||||
|
System.out.println("Content-Type: text/plain\n");
|
||||||
|
System.out.println("Bad Request");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 7. Написать сервлет, который считает количество заходов пользователя на сайт через HTTP-сессии
|
||||||
|
```Java
|
||||||
|
@WebServlet("/counter")
|
||||||
|
public class MyServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest req, HttpServletResponse res) {
|
||||||
|
HttpSession session = req.getSession();
|
||||||
|
if (session.getAttribute("visitCount") == null) {
|
||||||
|
session.setAttribute("visitCount", 0);
|
||||||
|
}
|
||||||
|
int count = (Integer) session.getAttribute("visitCount") + 1;
|
||||||
|
session.setAttribute("visitCount", count);
|
||||||
|
res.setContentType("text/plain");
|
||||||
|
PrintWriter out = res.getWriter();
|
||||||
|
out.println("Вы посетили страницу %d раз".format(count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 8. Написать сервлет, который проверяет роль пользователя и пропускает, если он админ, иначе переадресация на сообщение об ошибке
|
||||||
|
```Java
|
||||||
|
@WebServlet("/task")
|
||||||
|
public class MyServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
|
||||||
|
String role = req.getParameter("role");
|
||||||
|
if (role == null || !role.equals("admin")) {
|
||||||
|
res.sendRedirect("/access-denied.html");
|
||||||
|
}
|
||||||
|
req.setAttribute("secretData", "TopSecret123");
|
||||||
|
RequestDispatcher disp = req.getRequestDispatcher("/admin.jsp");
|
||||||
|
disp.forward(req, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 9. Написать фильтр, который пропускает пользователя дальше, только если в его сессии есть атрибут `user`
|
||||||
|
```Java
|
||||||
|
@WebFilter("/secure/*")
|
||||||
|
public class MyFilter implements Filter {
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
|
||||||
|
HttpServletRequest httpReq = (HttpServletRequest) req;
|
||||||
|
HttpServletResponse httpRes = (HttpServletResponse) res;
|
||||||
|
HttpSession session = httpReq.getSession();
|
||||||
|
if (session.getAttribute("user")==null) {
|
||||||
|
httpRes.setContentType("text/plain");
|
||||||
|
httpRes.setStatus(403);
|
||||||
|
hhtpRes.getWriter().println("Вход воспрещен");
|
||||||
|
} else {
|
||||||
|
chain.doFilter(req, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 10. Реализовать функцию на JavaScript, которая будет закрывать текущее окно, если в нем открыт гугл
|
||||||
|
```JavaScript
|
||||||
|
function closeWindow() {
|
||||||
|
if (window.location.href === "https://www.google.ru") {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 11. Открытие в новом окне браузера гугла через JS
|
||||||
|
```JavaScript
|
||||||
|
window.open("http://google.com", "newwin", "width=1200,height=600");
|
||||||
|
```
|
||||||
@@ -9,11 +9,10 @@
|
|||||||
Проводит практик
|
Проводит практик
|
||||||
1 - конец октября
|
1 - конец октября
|
||||||
2 - декабрь
|
2 - декабрь
|
||||||
|
[Материалы](../Лабы/Веб/Рубежка%201.md) по первой рубежке
|
||||||
## Лабы
|
## Лабы
|
||||||
На сайте великого тюнита, их 4
|
На сайте великого тюнита, их 4
|
||||||
На том же сайте гайд на деплой фронта на гелиос
|
[Деплой лаб](../Лабы/Веб/Деплой%20лаб.md) - гайд на деплой лаб
|
||||||
Напомню классику - [Гайд на 2 курс гитхаб](https://github.com/Imtjl/2nd-year-guide) - там гайд на деплой лаб
|
|
||||||
[Видео-гайд](https://www.youtube.com/watch?v=URdECcC25vY) на деплой 2 лабы, возможно сделаю текстовую заметку
|
|
||||||
## Лекции
|
## Лекции
|
||||||
[Веб](../../Веб/Веб.md)
|
[Веб](../../Веб/Веб.md)
|
||||||
## Материалы
|
## Материалы
|
||||||
|
|||||||
Reference in New Issue
Block a user