سلیب و افض به یک مشکل مشترک رسیدند. آنها تصمیم گرفتند تا از شرّ سرچ هرساله خود راحت شوند. هر دوی آنها همیشه فراموش میکردند که جام جهانی بعدی در چه سالی برگزار میشود و همواره یکی از دو عبارت زیر را سرچ میکردند:
جام جهانی بعدی کی است
و یا
when is the next world cup
ناگهان سلیب فکری به سرش زد، زمان آن رسیده بود تا یکبار برای همیشه برنامهای به زبان جاوا بنویسند که با ورودی گرفتن سال فعلی، سال جام جهانی بعدی را به آنها بگوید. به نظر سلیب اجرا کردن یک برنامه جاوا به شدت آسانتر از سرچ کردن با چالشهای سخت و طولانی همچون تایپ کردن، کندی اینترنت، فیلترینگ گوگل و... بود، البته که همگی با سلیب موافقیم اما مشکل آنجا بود که سلیب نمیتوانست برنامه مورد نظر را پیادهسازی کند برای همین از شما کمک میخواهد تا به او در این راه کمک کنید.
پروژهی اولیه را از این لینک دانلود کنید.
ساختار فایلهای پروژه بهصورت زیر است:
شما باید تابع predict
موجود در فایل Predictor.java
را مطابق با خواست مسئله پیادهسازی کنید. امضای تابع مورد نظر به شکل زیر است:
این تابع یک متغیر عددی با نام year
به عنوان سال فعلی ورودی میپذیرد. شما باید بگویید جام جهانی بعدی در چه سالی برگزار میشود. توجه داشته باشید که جام جهانی تنها در سالهایی برگزار میشود که باقی مانده عدد سال بر عدد ۴ برابر با عدد ۲ باشد.
پس از پیادهسازی موارد خواستهشده، فایل Predictor.java
را آپلود کنید.
امیرحسین که فردی است جوان و جویای نام! بهدنبال پیادهسازی سیستمی است که دنیا را تکان دهد. او فکری در سر دارد که احساس میکند اولین قدم از رسیدن به یک سیستم هوشمند قوی است.
او قصد دارد کلاسهایی را در زبان جاوا، فقط با داشتن اطلاعات کلی از آن کلاسها و بهصورت پویا ایجاد کند. امیرحسین که اولین گامهای این پروژه را نوشته، در تکمیل آن از شما کمک خواسته است.
پروژهی اولیه را از این لینک دانلود کنید. ساختار فایلهای پروژه اولیه بهصورت زیر است:
وظیفه اصلی شما در این سوال، تکمیل کلاس ClassUtil
است. در این کلاس متدی با نام classMaker
وجود دارد که پارامتر ورودی از نوع ClassDetail
دریافت میکند و باید کلاسی با اطلاعاتی که از این پارامتر دریافت میکند، بسازد. در ادامه به بررسی کلاس ClassDetail
میپردازیم:
ClassDetail
🔗این کلاس دارای ۵ پراپرتی زیر است:
type
: این پراپرتی که از نوع OopType
است مشخص کننده نوع کلاسی است که باید ساخته شود. این نوع میتواند enum
، interface
یا class
باشد.name
: این پراپرتی که از نوع رشته است نام کلاس را مشخص میکند.properties
: این پراپرتی که از نوع Map
است نوع و نام پراپرتیهای کلاس را مشخص میکند، در این مپ کلیدها نوع و مقادیر نام پراپرتیها است.methods
: این پراپرتی لیستی از کلاس Method
است. کلاس Method
نیز دارای سه پراپرتی returnType
، name
و parameters
است که بهترتیب نام، نوع مقدار بازگشت و پارامترهای ورودی متد را مشخص میکند.oop
: این پراپرتی لیستی از رشتهها را مشخص میکند. این رشتهها نام کلاسهای جاواست که شما باید براساس نوع این کلاسها، آنها را extends
یا implements
کنید.ClassUtil
🔗حال که با کلاس ClassDetail
آشنا شدید باید کلاس ClassUtil
را تکمیل کنید. در ادامه به بررسی دو مثال از عملکرد این کلاس خواهیم پرداخت.
فرض کنید قصد داریم تا یک enum
با نام Month
بسازیم که پراپرتی با نام NAME
دارد. برای این کار کد زیر را مینویسیم و از متد کلاسی که تکمیل کردید استفاده میکنیم:
خروجی این کد باید کلاسی بهصورت زیر باشد:
در مثالی دیگر فرض کنید قصد داریم تا کلاسی بسازیم که دارای مقادیری بهصورت زیر باشد:
که در این حالت متغیر code
باید بهصورت زیر باشد:
oop
قرار داده میشود، حتما وجود دارند و از پکیجهای استاندارد جاوا هستند.import
کرده باشد.extends
و ... ، باید در کلاس شما رعایت شده باشد.extends
یا implements
، کلاس شما باید کامل ساخته شود و فقط extends
یا implements
را نادیده بگیرد.void
باشد.پس از پیادهسازی موارد خواستهشده، کلاس ClassUtil
را زیپ کرده و ارسال کنید.
ابوالفضل مدت زیادی است که با فریمورک Spring Boot کار میکند. اخیراً او به این فکر فرو رفته که قابلیتهای مختلف این فریمورک چگونه کار میکنند. برای درک عمیقتر این موضوع، او میخواهد بداند قابلیت autowiring که تزریق وابستگی (dependency injection) خودکار با استفاده از آن انجام میشود چگونه کار میکند. از شما میخواهیم نسخهی سادهای از این بخش فریمورک Spring Boot را برای او بنویسید.
پروژهی اولیه را از این لینک دانلود کنید. ساختار فایلهای پروژه بهصورت زیر است:
@Component
🔗از این انوتیشن در کلاسهایی استفاده میشود که بخواهیم امکان استفاده از آنها در تزریق وابستگی خودکار فراهم باشد. این انوتیشن شامل پارامتر value
از نوع String
است.
@Autowired
🔗از این انوتیشن زمانی استفاده میشود که بخواهیم کانستراکتور موردنظر را جهت فراخوانی هنگام تزریق وابستگی خودکار مشخص کنیم. اگر کلاس موردنظر تنها شامل یک کانستراکتور باشد، نیازی به استفاده از این انوتیشن نیست. در غیر اینصورت، فقط یکی از کانستراکتورهای کلاس باید دارای این انوتیشن باشد.
@Qualifier
🔗از این انوتیشن زمانی استفاده میشود که بخواهیم از بین چند پیادهسازی برای یک اینترفیس یا کلاس، یکی را برای autowiring انتخاب کنیم. این انوتیشن شامل پارامتر value
از نوع String
است.
Injector
🔗این کلاس، وظیفهی اصلی قابلیت autowiring را برعهده دارد. این کلاس شامل متدی با نام get
و با امضای زیر است:
این متد را بهگونهای پیادهسازی کنید که با دادن یک کلاس به آن، یک نمونه از آن کلاس ساخته شود. همچنین، کلاس دادهشده میتواند شامل یک یا چند کانستراکتور باشد.
نکات زیر هنگام پیادهسازی متد get
باید رعایت شوند:
public
نبود، یک استثنا از نوع NoPublicConstructorFoundException
پرتاب کنید.@Autowired
بودند، یک استثنا از نوع NoUniqueConstructorFoundException
پرتاب کنید.@Qualifier
نبودند، یک استثنا از نوع NoUniqueComponentFoundException
پرتاب کنید (برای مثال، اگر اینترفیسی با نام IA
داشته باشیم و دو پیادهسازی A1
و A2
از آن داشته باشیم که مقدار موجود در @Component
آنها یکسان باشد).@Component
با value
یکسان برای بیش از یک پیادهسازی برای یک اینترفیس یا کلاس وجود داشت، یک استثنا از نوع NoUniqueComponentFoundException
پرتاب کنید.A
در کانستراکتور خود یک آبجکت از نوع B
لازم داشته باشد و کلاس B
در کانستراکتور خود یک آبجکت از نوع A
لازم داشته باشد)، یک استثنا از نوع CircularDependencyFoundException
پرتاب کنید.get
کلاس Injector
و هنگام بررسی آبجکتهای موردنظر جهت ساخت صورت گیرد.Injector
تعریف کنید.get
کلاس Injector
استفاده نمیشود.پس از پیادهسازی متد get
، فایل Injector.java
را آپلود کنید.
شهرام و بهرام بعد از تصادف سنگینی که منجر به خسارت بسیار سنگینی که برای آنها شد تصمیم گرفتند تا شرکت بیمهای را تاسیس کنند. این دو با شرکتهای مختلف بیمه وارد مذاکره شدند و قول همکاری با آنها را گرفتهاند.
این دو قصد دارند برای شروع APIهایی را طراحی و در معرض استفاده عموم قرار دهند اما از آنجا که این دو نفر هیچ تجربهای در زمینه برنامهنویسی ندارند، برای این کار از شما کمک خواستهاند.
نیازمندیهای این دو برای این پروژه عبارت است از:
مطابق با این نیازمندیها، وبسرویسهای زیر باید پیادهسازی شوند:
عنوان | آدرس |
---|---|
تعریف شرکت بیمه | POST /companies/save |
تعریف انواع بیمه توسط یک شرکت خاص | POST /insurances/save |
دریافت اطلاعات شرکت بیمه | GET /companies/get/{id} |
دریافت اطلاعات بیمه | GET /insurances/get/{id} |
ابتدا پروژهی اولیه و خام اسپرینگ بوتی را از این لینک دانلود کنید. سپس شما باید به پیادهسازی نیازمندیهای ذکر شده بپردازید.
در برنامه شما باید بتوان شرکت جدیدی ثبت کرد. شرکتها باید در جدولی به نام companies
ذخیره شوند و اطلاعات این جدول بهصورت زیر است:
نام ستون | نوع |
---|---|
name | String |
همچنین این شرکت میتواند چندین بیمه (insurances) ایجاد کند.
برای ایجاد شرکت بیمه شما باید اندپوینتی با اطلاعات زیر ایجاد کنید:
اگر شرکت ذخیره شد باید عبارت Company saved.
و اگر هر خطایی رخ داد، عبارت Company saving problem!
را با وضعیت BAD_REQUEST
برگردانید.
در برنامه شما باید بتوان برای هر شرکت تعدادی بیمه ثبت کرد. برای شروع برنامه شما باید از دو نوع بیمه افراد و وسایل نقلیه پشتیبانی کند. بیمهها باید در جدولی به نام insurances
ذخیره شوند و اطلاعات این جدول بهصورت زیر است:
نام ستون | نوع |
---|---|
type | ENUM |
name | String |
price | Double |
created_at | LocalDateTime |
همچنین این جدول به شرکتی (company) که آن را ایجاد کرده، مرتبط است و ستون created_at
زمان درج ردیف را نگه میدارد و type
هم ENUM ای است که میتواند PERSON
یا VEHICLE
باشد.
جدولهای vehicles_insurance
و persons_insurance
نیز باید در پروژه شما وجود داشته باشند که اطلاعات تکمیلی بیمهها را در خود نگه میدارند تا اگر شرکتی این نوع بیمهها را ثبت کرد، اطلاعات تکمیلی در این جداول ذخیره شود.
ساختار جدول vehicles_insurance
:
نام ستون | نوع |
---|---|
usage | String |
ساختار جدول persons_insurance
:
نام ستون | نوع |
---|---|
min_age | int |
برای ایجاد بیمهها شما باید اندپوینتی با اطلاعات زیر ایجاد کنید:
اگر بیمه ذخیره شد باید عبارت Insurance saved.
و اگر هر خطایی رخ داد، عبارت Insurance saving problem!
را با وضعیت BAD_REQUEST
برگردانید.
همانطور که میبینید در مثال بالا بیمه افراد با نام دلخواه برای یک شرکت ایجاد میشود. حال فرض کنید قصد دارد تا بیمه وسایل نقلیه را نیز برای این شرکت ایجاد کنیم، برای این کار همین اندپوینت را با اطلاعات زیر صدا میزنیم:
بنابراین باید اندپوینت و جداول شما برای انواع بیمهها بهخوبی پیادهسازی شوند.
برای این قسمت اندپوینتی ایجاد کنید تا بتوان اطلاعات یک شرکت بیمه خاص را دریافت کرد، اطلاعات این اندپوینت باید بهصورت زیر باشد:
برای این قسمت اندپوینتی ایجاد کنید تا بتوان اطلاعات یک بیمه خاص را دریافت کرد، اطلاعات این اندپوینت باید بهصورت زیر باشد:
h2
استفاده شده است.org/quera/bime
هستید، فقط باید پروژه شما خواستههای مسئله را بهخوبی پیادهسازی کرده باشد.پس از پیادهسازی موارد خواستهشده، این پروژه را زیپ کرده و ارسال کنید.
در این سؤال، باید سامانهی فروش بلیت مسابقات فوتبال در استادیومهای مختلف را پیادهسازی کنید!
پروژهی اولیه را از این لینک دانلود کنید.
org.quera.ticket
شامل موجودیتهای JPA برنامه است که مطابق با schema دیتابیس طراحی شدهاند. شناسه (id
) موجودیتها بهصورت خودکار توسط Hibernate تولید میشود.org.quera.ticket.security
شامل کلاسهایی برای مدیریت احراز هویت است.تعدادی وبسرویس REST مطابق نیازمندیهای زیر باید پیادهسازی شود:
آدرس | عنوان |
---|---|
GET /api/ping |
بررسی صحت برنامه |
POST /api/users/{id}/update_balance |
تغییر موجودی یک کاربر |
GET /api/stadiums |
دریافت اطلاعات استادیومها |
POST /api/stadiums |
ایجاد استادیوم جدید |
GET /api/stadiums/{id} |
دریافت اطلاعات یک استادیوم |
DELETE /api/stadiums/{id} |
حذف یک استادیوم |
GET /api/teams |
دریافت اطلاعات تیمها |
POST /api/teams |
ایجاد تیم جدید |
GET /api/teams/{id} |
دریافت اطلاعات یک تیم |
DELETE /api/teams/{id} |
حذف یک تیم |
GET /api/matches |
دریافت اطلاعات مسابقات |
POST /api/matches |
ایجاد مسابقهی جدید |
GET /api/matches/{id} |
دریافت اطلاعات یک مسابقه |
DELETE /api/matches/{id} |
حذف یک مسابقه |
GET /api/seat_classes |
دریافت اطلاعات مجموعه جایگاهها |
POST /api/seat_classes |
ایجاد مجموعه جایگاه جدید |
GET /api/seat_classes/{id} |
دریافت اطلاعات یک مجموعه جایگاه |
DELETE /api/seat_classes/{id} |
حذف یک مجموعه جایگاه |
GET /api/tickets |
دریافت لیست بلیتهای کاربر فعلی |
POST /api/tickets |
خرید بلیت برای یک صندلی |
با ارسال درخواست به این endpoint ، پاسخ زیر باید برگردانده شود:
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. با ارسال درخواست به این endpoint بههمراه پارامتر balance
در بدنهی درخواست، مقدار موجودی کاربر ورودی باید بهروز شود.
با ارسال درخواست به این endpoint ، اطلاعات همهی استادیومها در قالب یک آرایه باید برگردانده شوند.
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. یک استادیوم با اطلاعات اولیهی دادهشده ایجاد میشود و مشخصات آن برگردانده میشود. مقادیر name
و capacity
در بدنهی درخواست ارسال میشوند. در صورتی که مقدار balance
واردشده منفی باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که کاربری با شناسهی واردشده موجود نباشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
با ارسال درخواست به این endpoint ، اطلاعات استادیومی که شناسهی آن وارد شده است باید برگردانده شود. در صورتی که استادیومی با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. با ارسال درخواست به این endpoint ، استادیومی که شناسهی آن وارد شده است باید حذف شود و کد پاسخ باید 204
باشد. در صورتی که استادیومی با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
با ارسال درخواست به این endpoint ، اطلاعات همهی تیمها در قالب یک آرایه باید برگردانده شوند.
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. با ارسال درخواست به این endpoint ، یک تیم با اطلاعات اولیهی دادهشده ایجاد میشود و مشخصات آن برگردانده میشود. مقدار name
در بدنهی درخواست ارسال میشوند. در صورتی که تیمی با نام واردشده از قبل وجود داشته باشد، کد پاسخ باید 400
باشد.
با ارسال درخواست به این endpoint ، اطلاعات تیمی که شناسهی آن وارد شده است باید برگردانده شود. در صورتی که تیمی با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. با ارسال درخواست به این endpoint ، تیمی که شناسهی آن وارد شده است باید حذف شود و کد پاسخ باید 204
باشد. در صورتی که تیمی با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
با ارسال درخواست به این endpoint ، اطلاعات همهی مسابقات در قالب یک آرایه باید برگردانده شوند.
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. یک مسابقه با اطلاعات اولیهی دادهشده ایجاد میشود و مشخصات آن برگردانده میشود. مقادیر زیر در بدنهی درخواست ارسال میشوند:
home_id
)away_id
)stadium_id
)date
) با فرمت yyyy-MM-dd
اگر از تاریخ مسابقه گذشته باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که شناسهی تیم میزبان معتبر نباشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که شناسهی تیم میهمان معتبر نباشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که شناسهی استادیوم معتبر نباشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
اگر استادیوم در تاریخ ذکرشده رزرو باشد (مسابقهی دیگری در آن روز در استادیوم وجود داشته باشد)، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
با ارسال درخواست به این endpoint ، اطلاعات مسابقهای که شناسهی آن وارد شده است باید برگردانده شود. در صورتی که مسابقهای با شناسهی واردشده وجود داشته باشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. با ارسال درخواست به این endpoint ، مسابقهای که شناسهی آن وارد شده است باید حذف شود و کد پاسخ باید 204
باشد. در صورتی که مسابقهای با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
با ارسال درخواست به این endpoint ، اطلاعات همهی مجموعه جایگاهها در قالب یک آرایه باید برگردانده شوند.
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. یک مجموعه جایگاه با اطلاعات اولیهی دادهشده ایجاد میشود و مشخصات آن برگردانده میشود. مقادیر زیر در بدنهی درخواست ارسال میشوند:
min_number
)max_number
)match_id
)price
)در صورتی که مسابقهای با شناسهی واردشده موجود نباشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که مقدار min_number
کوچکتر از ۱ باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که مقدار max_number
کوچکتر از min_number
باشد یا بزرگتر از ظرفیت استادیوم باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که مقدار price
منفی باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
اگر مجموعه جایگاهی برای بازی موردنظر وجود داشته باشد که شماره صندلی مشترکی با مجموعه جایگاه فعلی داشته باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
با ارسال درخواست به این endpoint ، اطلاعات مجموعه جایگاهی که شناسهی آن وارد شده است باید برگردانده شود. در صورتی که مجموعه جایگاهی با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد.
این endpoint باید تنها برای کاربرانی قابل دسترس باشد که نقششان ADMIN
است. با ارسال درخواست به این endpoint ، مجموعه جایگاهی که شناسهی آن وارد شده است باید حذف شود و کد پاسخ باید 204
باشد. در صورتی که مجموعه جایگاهی با شناسهی واردشده وجود نداشته باشد، کد پاسخ باید 404
باشد.
با ارسال درخواست به این endpoint ، لیست بلیتهای کاربر واردشدهی فعلی باید در قالب یک آرایه برگردانده شود.
با ارسال درخواست به این endpoint ، عملیات خرید بلیت یک صندلی برای کاربر فعلی باید انجام شود. مقادیر match_id
و seat_number
در بدنهی درخواست موجود خواهند بود.
در صورتی که مسابقهای با شناسهی واردشده موجود نباشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که از تاریخ مسابقه گذشته باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که مقدار seat_number
کوچکتر از ۱ باشد یا بزرگتر از ظرفیت استادیوم بازی باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که مجموعه جایگاهی برای شماره صندلی موردنظر تعریف نشده باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که کاربر فعلی، صندلی فعلی را از قبل خریده باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که کاربر دیگری صندلی فعلی را از قبل خریده باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
در صورتی که میزان موجودی کاربر کمتر از قیمت صندلی باشد، کد پاسخ باید 400
باشد و بدنهی پاسخ باید بهصورت زیر باشد:
403
باید برگردانده شود. در صورتی که هیچ کاربری وارد برنامه نشده باشد، کد پاسخ 401
باید برگردانده شود.پس از پیادهسازی موارد خواستهشده، پوشهی src
پروژه را زیپ کرده و ارسال کنید. توجه داشته باشید که فقط تغییرات اعمالشده در پوشهی src/main/java/org/quera/ticket
در نظر گرفته میشوند.