- Home »

Вопросы и ответы для собеседования по Servlet
Если собираешься попадать на Java-собеседования, особенно на позицию разработчика веб-приложений, то Servlet API — это вопрос, который точно всплывёт. Эта штука уже не первый день крутится вокруг корпоративной Java, и знание её тонкостей может сыграть решающую роль в твоей карьере. Особенно если ты планируешь деплоить свои приложения на собственных серверах и хочешь понимать, что происходит под капотом популярных фреймворков типа Spring. Собрал для тебя самые частые вопросы с детальными ответами, примерами кода и практическими советами по настройке.
## Что такое Servlet и как он работает?
Servlet — это Java-класс, который расширяет возможности сервера для обработки HTTP-запросов. По сути, это спецификация, которая определяет, как Java-приложения должны взаимодействовать с веб-серверами. Когда приходит запрос, контейнер сервлетов (типа Tomcat) создаёт экземпляр твоего сервлета и вызывает соответствующий метод.
Жизненный цикл сервлета включает:
• **Загрузка и инициализация** — вызов `init()`
• **Обработка запросов** — вызов `service()`, который делегирует в `doGet()`, `doPost()` и т.д.
• **Уничтожение** — вызов `destroy()`
public class HelloServlet extends HttpServlet {
@Override
public void init() throws ServletException {
// Инициализация ресурсов
System.out.println("Servlet initialized");
}
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Hello, World!
");
}
@Override
public void destroy() {
// Очистка ресурсов
System.out.println("Servlet destroyed");
}
}
## Настройка сервлета: от конфигурации до деплоя
### Способ 1: Через web.xml (старая школа)
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
version="3.1">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.example.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
### Способ 2: Через аннотации (современный подход)
@WebServlet(name = "HelloServlet",
urlPatterns = {"/hello"},
loadOnStartup = 1)
public class HelloServlet extends HttpServlet {
// твой код
}
### Быстрая настройка на VPS
Для тестирования и разработки тебе понадобится сервер. Можешь заказать VPS для небольших проектов или выделенный сервер для production-нагрузок.
# Установка Java и Tomcat на Ubuntu
sudo apt update
sudo apt install openjdk-11-jdk
sudo apt install tomcat9
# Создание WAR-файла
jar -cvf myapp.war *
# Деплой в Tomcat
sudo cp myapp.war /var/lib/tomcat9/webapps/
sudo systemctl restart tomcat9
## Разбор популярных вопросов с собеседований
### RequestDispatcher vs sendRedirect
Характеристика | RequestDispatcher | sendRedirect |
---|---|---|
Местоположение | Серверная сторона | Клиентская сторона |
URL в браузере | Остаётся прежним | Меняется |
Производительность | Быстрее | Медленнее (два запроса) |
Область видимости | Внутри приложения | Любой URL |
// RequestDispatcher (forward)
RequestDispatcher dispatcher = request.getRequestDispatcher("/result.jsp");
dispatcher.forward(request, response);
// sendRedirect
response.sendRedirect("/app/success.jsp");
### Работа с сессиями
// Получение сессии
HttpSession session = request.getSession();
session.setAttribute("username", "john_doe");
// Настройка таймаута
session.setMaxInactiveInterval(1800); // 30 минут
// Инвалидация сессии
session.invalidate();
### Фильтры — мощный инструмент
Фильтры позволяют перехватывать запросы и ответы до того, как они достигнут сервлета:
@WebFilter("/*")
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
// Выполнение запроса
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - start;
System.out.println("Request processed in: " + duration + "ms");
}
}
## Практические кейсы и подводные камни
### ❌ Частые ошибки
**1. Thread Safety**
Сервлеты не thread-safe по умолчанию. Избегай instance variables:
// ПЛОХО
public class BadServlet extends HttpServlet {
private int counter = 0; // Общий для всех потоков!
protected void doGet(HttpServletRequest request,
HttpServletResponse response) {
counter++; // Race condition!
}
}
// ХОРОШО
public class GoodServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) {
int counter = 0; // Локальная переменная
counter++;
}
}
**2. Утечки памяти в сессиях**
// Плохая практика - большие объекты в сессии
session.setAttribute("heavyObject", new HeavyObject());
// Лучше использовать ID и кэш
session.setAttribute("objectId", objectId);
Object obj = cache.get(objectId);
### ✅ Лучшие практики
**Конфигурация пула соединений в context.xml:**
<Context>
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
maxTotal="100"
maxIdle="30"
maxWaitMillis="10000"
username="dbuser"
password="dbpass"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testdb"/>
</Context>
## Альтернативы и современные подходы
### Spring Boot vs чистые Servlet
Аспект | Чистые Servlet | Spring Boot |
---|---|---|
Скорость разработки | Медленно | Быстро |
Контроль | Полный | Ограниченный |
Размер приложения | Маленький | Большой |
Производительность | Высокая | Хорошая |
### Микросервисы с Servlet
@WebServlet("/api/users/*")
public class UserApiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
if (pathInfo.matches("/\\d+")) {
// GET /api/users/123
handleGetUser(request, response);
} else {
// GET /api/users
handleGetUsers(request, response);
}
}
private void handleGetUser(HttpServletRequest request,
HttpServletResponse response)
throws IOException {
response.setContentType("application/json");
response.getWriter().write("{\"id\": 123, \"name\": \"John\"}");
}
}
## Нестандартные применения
### Servlet как WebSocket endpoint
@ServerEndpoint("/websocket")
public class WebSocketEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Connection opened");
}
@OnMessage
public void onMessage(String message, Session session) {
try {
session.getBasicRemote().sendText("Echo: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
### Servlet для file upload
@WebServlet("/upload")
@MultipartConfig(
maxFileSize = 1024 * 1024 * 5, // 5MB
maxRequestSize = 1024 * 1024 * 10 // 10MB
)
public class FileUploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Part filePart = request.getPart("file");
String fileName = filePart.getSubmittedFileName();
try (InputStream input = filePart.getInputStream()) {
Files.copy(input, Paths.get("/uploads/" + fileName));
}
}
}
## Полезные ссылки и ресурсы
• Официальная документация Servlet API
• Документация Apache Tomcat
• Jakarta Servlet API
## Интересные факты и статистика
Servlet API появился в 1997 году и до сих пор остаётся основой для большинства Java веб-приложений. Согласно опросам разработчиков, около 65% enterprise-приложений на Java используют Servlet API напрямую или через фреймворки.
Производительность чистых сервлетов может достигать 50,000+ запросов в секунду на обычном сервере, что делает их отличным выбором для высоконагруженных API.
## Автоматизация и скрипты
### Автоматический деплой с помощью Maven
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>TomcatServer</server>
<path>/myapp</path>
</configuration>
</plugin>
### Bash-скрипт для мониторинга
#!/bin/bash
# monitor_servlet.sh
APP_URL="http://localhost:8080/myapp/health"
LOG_FILE="/var/log/servlet-monitor.log"
while true; do
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" $APP_URL)
if [ $RESPONSE -eq 200 ]; then
echo "$(date): Application is healthy" >> $LOG_FILE
else
echo "$(date): Application is down! Response: $RESPONSE" >> $LOG_FILE
# Restart Tomcat
sudo systemctl restart tomcat9
fi
sleep 30
done
## Заключение и рекомендации
Servlet API — это не просто legacy-технология, а мощный инструмент, который стоит знать любому Java-разработчику. Даже если ты работаешь со Spring Boot, понимание принципов работы сервлетов поможет тебе лучше оптимизировать приложения и решать сложные задачи.
**Когда использовать чистые Servlet:**
• Микросервисы с минимальными зависимостями
• Высокопроизводительные API
• Embedded-приложения
• Когда нужен полный контроль над HTTP-обработкой
**Когда лучше выбрать фреймворк:**
• Rapid prototyping
• Большие enterprise-приложения
• Когда команда не очень опытная
• Проекты с жёсткими дедлайнами
Главное — не бояться “грязной” работы с низкоуровневыми API. Это знание всегда пригодится на собеседованиях и в реальных проектах, особенно когда что-то пойдёт не так в production.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.