JavaRush /בלוג Java /Random-HE /משימת מבחן לתעסוקה, בוא נבין את זה..
timurnav
רָמָה

משימת מבחן לתעסוקה, בוא נבין את זה..

פורסם בקבוצה
חברים, שלום לכולם. אני רוצה לשתף אתכם בניסיון שלי בפתרון משימת מבחן לתפקיד מפתח Java בחברה רוסית. אני אגיד מיד שהטמעת הפונקציונליות העיקרית של המשימה אינה קשה במיוחד, אבל כמו תמיד, הפרטים והדברים הקטנים חשובים, מה שמנע ממני להגיש אותה בזמן; הם מעולם לא ענו על המשימה - התפקיד הפנוי שלהם כבר היה מלא כששלחתי להם. אני מציע לך לבדוק את המשימה כדי לראות אם עשיתי את כל מה שנדרש ממני. ולמי שאין לו מושג איך להכין, אוסיף הרבה מים על איך התמודדתי עם זה. אם מישהו מעוניין בזה, ברוך הבא לחתול. אני אגיד מיד שלא אפרסם כאן את כל הפתרון, אבל יהיו הרבה הסברים למתחילים, אם מישהו לא מעוניין לקרוא את ההשתפכות שלי, הנה הפרויקט ב-github . אני אתחיל עם טקסט של המשימה עצמה.
משימת מבחן מס' 1
תיאור: שרת API (JSON HTTP API) כלי פיתוח: Java Framework: Play Framework 2.4 (או מתקדם יותר) או Spring Boot 1.2.3 (או יותר) מסד נתונים: MySQL פרוטוקול: HTTP, יציאה 80 פונקציונליות (בקשות):
  1. מטעין.
    • אנו מעבירים את הקובץ (תמונת אווטר JPG) לשרת.
    • אנו שומרים את התמונה בספרייה בשרת.
    • תגובת השרת היא ה-URI הפנימי של התמונה.
  2. הוספת משתמש חדש.
    • אנו מעבירים את הנתונים האישיים של המשתמש לשרת (URI של התמונה, שם משתמש, מייל וכו').
    • אנו שומרים את המידע במסד הנתונים.
    • תגובת השרת היא המזהה הייחודי של המשתמש החדש.
  3. קבלת מידע על המשתמש.
    • אנו מעבירים מזהה משתמש ייחודי לשרת.
    • קריאת מידע ממסד הנתונים.
    • תגובת השרת היא הנתונים האישיים של המשתמש (ראה למעלה).
  4. שינוי סטטוס משתמש (מקוון, לא מקוון).
    • אנו מעבירים את זיהוי המשתמש הייחודי והסטטוס החדש (Online, Offline) לשרת.
    • שינוי סטטוס המשתמש.
    • תגובת שרת - מזהה משתמש ייחודי, סטטוס חדש וקודם.
    הערה: השרת מבצע שאילתות ל-API/בסיס נתונים חיצוניים. מכיוון שמדובר במשימת בדיקה פשוטה, יש צורך ליישם "סטאב" עם גישה מדומה והשהיית זמן של 5-10 שניות.
  5. סטטיסטיקות שרתים.
    • אנו מעבירים פרמטרים לשרת: 1. סטטוס לקוח (מקוון, לא מקוון או נעדר), 2. מזהה ייחודי (חותמת זמן) של הבקשה (יכול להיות שנעדר)
    • תגובת השרת היא רשימה של משתמשים עם סטטוסים ו-URI של תמונה, כמו גם מזהה ייחודי (חותמת זמן) של הבקשה.
    הערה: אם הבקשה מכילה פרמטרים, על השרת לסנן את תגובתו לפיהם. אם הבקשה מכילה מזהה ייחודי (חותמת זמן) של הבקשה (התקבלה קודם לכן), אז השרת צריך להחזיר רק משתמשים שהסטטוס שלהם השתנה לאחר (בזמן) מזהה ייחודי זה (חותמת זמן).
דרישות חובה:
- RESTful. - Все данные в формате JSON. - Сервер API должен быть спроектирован с учетом того, что requestы 3 и 5 имеет высший приоритет (по отношению к requestам 1, 2, 4) и должны быть выполнены максимально быстро. - Обработка ошибок.
Необязательные требования (желательно):
- Документирование codeа. - Архитектура Сервера API должна быть рассчитана на высокую нагрузку и масштабирование. - Тесты.
Результат тестового задания:
- Результат тестового задания должен быть предоставлен в архиве и с подробной инструкцией по его развертыванию. Желательно приложить Dockerfile для сборки Docker контейнера для тестового задания. Можно загрузить на github.com. - Должен содержать краткую documentацию созданного API (список requestов, параметры requestов, форматы requestов, форматы ответов и т.д.). - Информация о времени потраченном на тестовое задание в разрезе: проектирование, программирование, documentация и т.д. Обращаем внимание, что это тестовое задание предназначено только для оценки знаний и умений, а не ставит целью создание законченного продукта (serverа API), поэтому допускаются упрощения с объяснением и указанием причин.
внимательные и опытные программисты могут пропустить следующий раздел, тут я буду разбираться с самим текстом задания. "Шапка" задания не вызывает ниHowих сложностей с восприятием, поэтому просто скажу что мой выбор пал на Spring Boot, но не потому что я уже когда-то что-то на нем делал, а потому что я уже прошел реальный проект с использованием Spring (но Boot'а там не было, How я понимаю из-за его простоты). По функционалу serverа: 1) Загрузчик файлов. Тут принципиально ничего сложного нет, мне нужно было просто разобраться How картинки вообще хранятся на serverе, оказалось, что наиболее удобным способом является простое размещение их в Howой-нибудь специально отведенной для этого директории. Конкретную реализацию разберем ниже. 2) Добавление нового пользователя, простая операция, если вы делали когда-нибудь CRUD applications, то он поддержит меня, если нет - всё увидите ниже. 3)Получение информации о пользователе. нет вопросов - всё ясно. 4)Изменение статуса пользователя. первые два пункта задания ясны How день, а что там с внешним requestом??? тут без 100гр не разобраться, я даже сейчас на 100% не уверен правильно ли я понял. Детали ниже. 5)Статистика serverа. Тут тоже интересно. первым пунктом предлагается реализовать метод с различными вариантами параметров, пока не понятно How это делать учитывая что это должен быть метод контроллера. вторым пунктом спрашивают всех юзеров, у кого изменился статус после момента времени вроде понятно, но есть тонкости.
Getting Started
ох, сколько раз я читал эту фразу, пока разбирался с этим заданием! Если вы пробовали когда нибудь разбираться в настройке проекта на Spring, но при этом по Howой-то причине так ни разу и не попробовали Spring Boot, поздравляю вас, вы испытаете просто восторг от того, что я напишу ниже. Я где-то вычитал, что раньше программисты очень большое количество codeа раньше переносor из проекта в проект, это шаблонный code - настройки подключения к базам данных, маппинг сервлетов и прочее-прочее, так вот чтобы, например, уменьшить объем шаблонного codeа для работы с базами данных мы используем JPA/Hibernate, они скрывают часть шаблонов но чтобы настроить их опять же нужно писать xml файл or конфигурационные классы. а если у вас маленький проект, то получается что ни фига вы не меньше codeа пишете, а даже наоборот. Дальше мы оборачиваем работу с JPA в Спринг, есть много проектов, но наиболее удобный это, конечно же, Spring Data. Это очень большой проект который может работать наверное со всем чем можно и JPA и NoSQL еще целую кучу разных проектов, он невероятно магический мы будем его использовать в нашем проекте. Используя Spring мы почти избавляемся от настроек соединения с БД, Spring все делает за нас, нам только нужно навтыкать нужных аннотаций по транзакционности, кешированию и в особых случаях нагуглить (подсмотреть у других) еще Howих-нибудь настроек в кофигурации контекста. Но при этом у большинства начинающих разработчиков нет абсолютно ниHowого понятия How создать проект на Spring. Никто не знает fully How его настроить чтобы запустить проект и получить результат в браузере пройдя по ссылке начинающейся с localhost:8080/*. И тут на сцену выходит Spring Boot! Про Spring Boot лучше рассказать на конкретном примере! Начнем с заготовки. Whatбы создать проект Spring Boot разработчики Spring придумали "конструктор" создания шаблонов. Им можно воспользоваться на их сайте, но гораздо проще сделать это в нашей любимой IDE Intellij IDEA. И так: File->New->Project В окне переходим на вкладку Spring Initializr, в ней должно быть выставлено jdk, и URL https://start.spring.io, проверяем подключение к интернету, далее нужно будет выбрать название, а затем технологии которые мы будем использовать, на первом этапе нам нужно только WEB - ставим рядом с ней галочку и далее создается проект. Whatбы мавен подтянул все зависимости нам нужно открыть вкладку Maven в идее и нажать кнопку обновить. Мы получor готовый шаблон applications, в котором зарыты все настройки для клиент-serverного общения. Whatбы получить первое впечатление создадим класс контроллера(про MVC-то уж наверняка все слышали). Во всех Spring applicationsх контроллеры имеют достаточно простую конструкцию - это класс, который помечен аннотацией @Controller(возможны префиксы, например, @RestController), этот класс отвечает за обработку входящих requestов. Для того, чтобы контроллер распознал request на Howой-нибудь address нужно сделать маппинг этого address на метод контроллера. Ниже представлен code этого класса, пока мы будем работать без иехрархии директорий, поэтому положим его в один пакадж с классом созданным автоматически Initializr'ом, у меня он называется DemoApplication. import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "/hello") public class DemoController { @RequestMapping(method = RequestMethod.GET) public String halloWorld() { return "Hello World!"; } @RequestMapping(value = "/{name}", method = RequestMethod.GET) public String halloName(@PathVariable("name") String name) { return "Hello, " + name + "!"; } } разберемся что тут. @RestController. How раз та annotation, о которой я писал выше. именно рестконтроллер используем поскольку мы хотим сразу увидеть результат и не хотим писать pages.jsp (фу-Howа), нам будет проще сразу увидеть результат в браузере в виде строки. @RequestMapping - How раз привязка к addressу. префикс общего address будет такой: localhost:8080. Как мы видим весь класс висит на addressе /hello, это означает что все методы внутри этого класса имеют префикс localhost:8080/hello. Далее первый метод класса, в его собственном маппинге указан метод Http протокола - request GET(про методы Http протокола почитайте сами) What это всё означает? обратившись GET requestом на address localhost:8080/hello - получим ответ в виде строки "Hello World!", давайте проверим это! В классе DemoApplication, есть одна крутая annotation, которая можно сказать в одиночку запускает весь контекст спринга - @SpringBootApplication. Метод main этого класса становится волшебным, How раз запускает всю магию скрытую в SpringApplication, если вызвать контекстное меню на этом классе то в строке Run появятся варианты, рекомендую запускаться раном с зеленой меткой, так консоль будет приятнее выглядеть и в будущем будет проще читать логи прям из нее. Запускаем приложение. когда вывод в консоль прекратится, вы должны увидеть в консоли
2015-09-02 09:25:36.895 INFO 5844 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2015-09-02 09:25:36.900 INFO 5844 --- [ main] demo.DemoApplication : Started DemoApplication in **** seconds (JVM running for 15.501)
где "****" - длительность запуска applications :) после этого в любом браузере (or curl, or чем там вы пользуетесь?) нужно набрать address на который замапor метод контроллера
localhost:8080/hello
В браузере должно отобразиться каноническое
Hello World!
вот вам и веб приложение! Если вы заметor в контроллере есть еще один метод, там есть собственный маппинг address, к текущему addressу добавляется плейсхолдер. Который спрингом передается в метод в качестве параметра. Не трудно догадаться что за это отвечает annotation @PathVariable. Так на request
localhost:8080/hello/Ваше Name
браузер покажет
Hello, Ваше Name!
С основами Spring Boot разобрались. Далее прикрутим базу данных, но это будет уже в следующем посте. Всем спасибо.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION