سلام دوست عزیز😃👋

به «مسابقه استخدامی به‌پرداخت ملت» خوش آمدی!

هرگونه ارتباط با سایر شرکت‌کنندگان و یا استفاده از ابزارهای تولید کد، مثل chatGPT و... در مسابقات کوئرا ممنوع است و بعد از شناسایی از لیست شرکت‌کنندگان مسابقه حذف می‌شوید.

لینک‌های مفید برای شرکت در مسابقه:

سوالات و مشکلات خودتان را می‌توانید از طریق قسمت «سوال بپرسید» با ما در میان بگذارید.

  • چهار سوال اول مسابقه الگوریتمی است و سوال پنجم مهارت شما را در پیاده‌سازی می‌سنجد.
  • در سوالات الگوریتمی تنها در صورتی نمره‌ی آن را می‌گیرید که همه‌ی تست‌ها را بدون خطا پاسخ دهید و در غیر این‌صورت هیچ نمره‌ای از آن دریافت نمی‌کنید.
  • حل همه‌ی سوالات با زبان برنامه‌نویسی C++ یا Java برای استخدام در به‌پرداخت الزامی است.
  • پیشنهاد می‌کنیم برای افزایش سرعت برنامه‌ها، اگر با زبان پایتون سوالات را حل می‌کنید از Pypy 3 به‌جای Python 3.12 استفاده کنید.

موفق باشید و بهتون خوش بگذره 😉✌

لیست سوالات را می‌توانید از نوار سمت راست این صفحه مشاهده کنید.

شبیه‌ساز خودپرداز


شما باید یک سیستم شبیه‌سازی خودپرداز (ATM) طراحی کنید که بتواند تراکنش‌های مالی شامل ثبت‌نام کاربر، ورود به سیستم، برداشت، واریز و انتقال وجه [و استعلام موجودی] را پردازش کند. علاوه بر آن، سیستم باید قادر به مدیریت و ثبت گزارش و لاگ‌های مختلف باشد و امکان کوئری زدن روی این لاگ‌ها را فراهم کند.

در این سیستم، هر لاگ سه ویژگی سطح لاگ (level)، پیام (message) و زمان ایجاد (timestamp) دارد.

همچنین سه سطح لاگ قابل ثبت است. هرکدام از این نوع لاگ‌ها، در شرایطی قابل ثبت هستند و کاربردهای متفاوتی دارند.

سطوح لاگ‌ها🔗

  1. لاگ ERROR (خطا):

    • مواردی که به دلیل مشکل جدی یا ناموفق بودن عملیات رخ داده‌اند.
    • مثال: خطای insufficient funds یا invalid credentials.
  2. لاگ INFO (اطلاعات):

    • اطلاعات عمومی مربوط به رخدادهای موفق و معمولی سیستم.
    • مثال: موفقیت در login یا deposit.
  3. لاگ DEBUG (دیباگ):

    • اطلاعات دقیق‌تر و فنی برای ردیابی مشکلات یا رفتارهای سیستم.
    • مثال: session created یا amount updated.

نشست (Session)🔗

نشست (Session) در برنامه‌های کاربردی، به‌ویژه در سیستم‌های تحت وب به دوره‌ای از ارتباط فعال بین کاربر و سیستم گفته می‌شود که در آن اطلاعاتی موقت ذخیره و مدیریت می‌شود. نشست‌ها معمولاً برای شناسایی کاربران، حفظ وضعیت تعامل آن‌ها با سیستم، و مدیریت امنیت به کار می‌روند. هر نشست در این سیستم ویژگی‌های زیر را دارد:

  1. شناسه یکتا (Session ID):

    • یک نشست با یک شناسه یکتا مشخص می‌شود. در سیستم ما Session ID به‌صورت یک شمارنده افزایشی (شروع از ۱) تولید می‌شود.
  2. مدت اعتبار (Expiration):

    • نشست‌ها موقتی هستند و تا زمانی معتبرند که کاربر با سیستم تعامل داشته باشد یا زمان انقضای مشخص‌شده به پایان نرسد.
    • در این سیستم، اگر از زمان ورود بیش از ۱۰ دقیقه (۶۰۰ ثانیه) گذشته باشد، نشست منقضی می‌شود.
    • زمان انقضای هر نشست تنها در هنگام اجرای دستورات بررسی می‌شود.
  3. در این سیستم، هر کاربر تنها دارای یک نشست فعال است.

دستورهای مجاز🔗

  1. register <user> <password> <role> <timestamp>
  2. login <user> <password> <timestamp>
  3. logout <session> <timestamp>
  4. withdraw <session> <amount> <timestamp>
  5. deposit <session> <amount> <timestamp>
  6. transfer <session> <target_user> <amount> <timestamp>
  7. log <level> <starttime> <finishtime> <timestamp>

هر یک از این دستورات، در واقع شبیه‌سازی انجام آنها در واقعیت است. در ادامه، عملکرد هر دستور را به طور کامل شرح می‌دهیم.

ثبت‌نام
register <user> <password> <role> <timestamp>
Plain text

این دستور کاربر جدیدی را با اطلاعات زیر ثبت می‌کند:

  • <user>: نام کاربری.
  • <password>: رمز عبور.
  • <role>: نقش کاربر که می‌تواند "admin" یا "user" باشد.
  • <timestamp>: زمان ثبت‌نام به فرمت yyyy/MM/dd:HH:mm:ss.

نام کاربری به ازای هر کاربر منحصر به فرد است. همچنین موجودی اولیه تمام کاربرانی که ثبت‌نام می‌کنند، در ابتدا صفر می‌باشد. اگر کاربر قبلاً ثبت شده باشد، لاگ خطای "user already registered" از نوع ERROR ثبت شود و اطلاعات آن کاربر در سیستم ثبت نشود. در غیر این‌صورت، لاگ اطلاعات "user registered successfully" از نوع INFO ثبت شود.

ورود به حساب
login <user> <password> <timestamp>
Plain text

کاربر با نام کاربری و رمز عبور معتبر وارد سیستم می‌شود:

  • اگر نام کاربری یا رمز عبور نادرست باشد، لاگ خطای "invalid credentials" با نوع ERROR ثبت کنید.
  • اگر کاربر قبلاً وارد شده باشد، لاگ اطلاعات "already logged in" با نوع INFO ثبت کنید. سپس در صورتی که از نشست (session) قبلی بیش از ۱۰ دقیقه زمان گذشته باشد، یک نشست جدید برای آن کاربر ایجاد و نشست قبلی حذف شود. در غیر این صورت، تغییری در سیستم ایجاد نخواهد شد و کاربر وارد حسابش می‌شود.
  • در صورتی که هیچ یک از شرایط بالا برقرار نبود، یک نشست جدید ساخته شده، کاربر وارد حساب می‌شود و یک لاگ INFO با پیام "user logged in successfully" ثبت می‌شود.

مکانیزم تولید session ID:برای هر ورود موفق، یک شناسه یکتا (session ID) به کاربر اختصاص داده می‌شود. این شناسه در واقع یک شمارنده افزایشی با شروع از ۱ است و به ازای هر ورود کاربران، یکی افزایش پیدا می‌کند.

خروج از حساب
logout <session ID> <timestamp>
Plain text

این دستور کاربر را از سیستم خارج می‌کند و session مربوط به او را از حافظه حذف می‌کند:

  • اگر شناسه نشست معتبر نباشد یا منقضی شده باشد، لاگ "session expired or invalid" با نوع ERROR ثبت می‌شود.
  • در غیر این صورت لاگ INFO با پیام "user logged out" ثبت شود.
برداشت وجه
withdraw <session ID> <amount> <timestamp>
Plain text

این دستور به کاربر اجازه برداشت مبلغ مشخصی به اندازه amoumt از حساب را می‌دهد:

  • <session>: شناسه نشست کاربر.
  • <amount>: مبلغ برداشت.
  • <timestamp>: زمان درخواست.

قوانین:

  • اگر نشست منقضی شده باشد (حداقل ۱۰ دقیقه از ورود گذشته باشد)، لاگ "session expired" با نوع ERROR ثبت شود.
    • محاسبه انقضا: از اختلاف زمانی بین <timestamp> اجرای دستور و زمان ورود (login) استفاده کنید. سیستم باید از فرمت زمانی yyyy/MM/dd:HH:mm:ss استفاده کند.
  • اگر موجودی کافی نباشد، لاگ"insufficient funds" با نوع ERROR ثبت می‌شود.
  • در صورت برداشت موفقیت‌آمیز، لاگ INFO با پیام "amount withdrawn successfully" ثبت شود.
واریز وجه
deposit <session ID> <amount> <timestamp>
Plain text

مبلغ مشخصی را به حساب کاربر اضافه می‌کند.

  • اگر نشست منقضی شده باشد، لاگ "session expired" با نوع ERROR ثبت شود.
  • در غیر این صورت لاگ INFO با پیام "amount deposited successfully" ثبت شود.
انتقال
transfer <session ID> <target_user> <amount> <timestamp>
Plain text

این دستور به کاربران اجازه می‌دهد مبلغی را از حساب خود به حساب کاربر دیگری انتقال دهند:

  • <session>: شناسه نشست کاربر فرستنده.
  • <target_user>: نام کاربری دریافت‌کننده.
  • <amount>: مبلغ انتقال.
  • <timestamp>: زمان درخواست.

قوانین:

  1. اگر نشست منقضی شده باشد، لاگ "session expired" با نوع ERROR ثبت شود.
  2. اگر کاربر دریافت‌کننده ثبت نشده باشد، لاگ "target user not found" با نوع ERROR ثبت کنید.
  3. اگر موجودی کافی نباشد، خطای "insufficient funds" با نوع ERROR ثبت کنید.
  4. شرایط بالا، از اول به آخر بررسی شوند و در صورتی که تناقضی در هر یک از شرایط به وجود بیاید، ادامه روند متوقف شود.
  5. در صورت انتقال موفقیت‌آمیز، لاگ INFO با پیام "amount transferred successfully" ثبت شود.
بررسی لاگ‌ها
log <level> [<t1>] [<t2>] <timestamp>
Plain text

این دستور برای کوئری زدن روی لاگ‌های سیستم استفاده می‌شود:

  • <level>: سطح لاگ که می‌تواند error، info یا debug باشد.
  • <t1> و <t2>: بازه زمانی که لاگ‌ها باید در آن جستجو شوند. این پارامترها اختیاری هستند؛ اگر t1 و t2 ارائه نشود، همه لاگ‌های موجود با سطح مشخص‌شده بدون توجه به زمان بازگردانده شوند.
  • <timestamp>: زمان ارسال درخواست برای اجرای دستور log است.
  • بلافاصله پس از اجرای دستور، یک لاگ get log [level] [t1] [t2] [timestamp] با نوع DEBUG در سیستم ثبت و در کنسول چاپ شود.

خروجی:

  1. خروجی شامل تمام لاگ‌هایی است که:
    • سطح لاگ آن‌ها برابر با <level> است.
    • زمان ثبت لاگ در بازه [<t1>, <t2>] قرار دارد.
  2. فرمت چاپ لاگ‌ها در کنسول به صورت زیر است:
    <timestamp> <level> <message>
    Plain text
  3. اگر لاگی پیدا نشود، خروجی "no logs found" در کنسول چاپ شود.

نکات قابل توجه🔗

  1. پس از انجام هر نوع عملیات، لاگ آن در سیستم ثبت می‌شود. همچنین پس از ثبت لاگ، خروجی آن با فرمت

    [log-type] log-message
    Plain text

    در کنسول چاپ می‌شود.

  2. هر دستور، یک پارامتر <timestamp> با فرمت زمانی yyyy/MM/dd:HH:mm:ss دارد که نشان می‌دهد آن دستور در چه زمانی اجرا شده است. از این زمان باید در دستور log برای فیلتر کردن لاگ‌ها استفاده کنید.

  3. دستورات نامعتبر:

    • همه دستورات با حروف کوچک وارد می‌شوند.
    • اگر دستور داده‌شده فرمت اشتباهی داشته باشد یا آرگومان‌های کافی نداشته باشد، سیستم باید به صورت داخلی آن را نادیده بگیرد.
  4. ورودی تضمین‌شده:

    • ورودی‌ها به ترتیب زمانی داده می‌شوند، بنابراین نیازی به بررسی ترتیب زمان‌ها نیست.
    • هیچ دو اتفاقی به طور همزمان رخ نمی‌دهد.
  5. برای گرفتن امتیاز کامل، به کوچکی یا بزرگی حروف در خروجی دقت کنید.

  6. در صورتی که هر یک از بخش‌های مسئله را به درستی پیاده‌سازی کردید، امتیاز آن را مستقل از سایر بخش‌ها خواهید گرفت. (البته، دقت کنید برای دریافت امتیاز عملیات withdraw، ابتدا باید عملیات deposit به درستی پیاده‌سازی شود.)

ورودی🔗

سطر اول ورودی شامل یک عدد صحیح و مثبت nn است که تعداد سطرهای ورودی را نشان می‌دهد. 1n10001≤n≤1000 در nn سطر بعدی، هر سطر شامل یکی از دستورهای بالا است.

خروجی🔗

خروجی‌های خواسته شده برای هر دستور را به ترتیب چاپ کنید.

مثال‌ها🔗

ورودی نمونه ۱🔗

10
register user1 pass1 user 2025/01/08:09:00:00
register user2 pass2 user 2025/01/08:09:01:00
login user1 pass1 2025/01/08:09:02:00
deposit 1 300 2025/01/08:09:03:00
withdraw 1 500 2025/01/08:09:04:00
transfer 1 user3 100 2025/01/08:09:05:00
logout 1 2025/01/08:09:06:00
login user1 wrongpass 2025/01/08:09:07:00
login user2 pass2 2025/01/08:09:08:00
log error 2025/01/08:09:00:00 2025/01/08:09:10:00 2025/01/08:09:09:00
Plain text

خروجی نمونه ۱🔗

[INFO] user registered successfully
[INFO] user registered successfully
[INFO] user logged in successfully
[INFO] amount deposited successfully
[ERROR] insufficient funds
[ERROR] target user not found
[INFO] user logged out
[ERROR] invalid credentials
[INFO] user logged in successfully
2025/01/08:09:04:00 ERROR insufficient funds
2025/01/08:09:05:00 ERROR target user not found
2025/01/08:09:07:00 ERROR invalid credentials
[DEBUG] get log error 2025/01/08:09:00:00 2025/01/08:09:10:00
Plain text

ورودی نمونه ۲🔗

10
register user1 password1 user 2025/01/08:10:00:00
register user2 password2 user 2025/01/08:10:01:00
register admin1 adminpass admin 2025/01/08:10:02:00
login user1 password1 2025/01/08:10:03:00
deposit 1 500 2025/01/08:10:04:00
withdraw 1 100 2025/01/08:10:05:00
transfer 1 user2 200 2025/01/08:10:06:00
logout 1 2025/01/08:10:07:00
login user2 password2 2025/01/08:10:08:00
log info 2025/01/08:10:00:00 2025/01/08:10:10:00 2025/01/08:10:09:00
Plain text

خروجی نمونه ۲🔗

[INFO] user registered successfully
[INFO] user registered successfully
[INFO] user registered successfully
[INFO] user logged in successfully
[INFO] amount deposited successfully
[INFO] amount withdrawn successfully
[INFO] amount transferred successfully
[INFO] user logged out
[INFO] user logged in successfully
2025/01/08:10:00:00 INFO user registered successfully
2025/01/08:10:01:00 INFO user registered successfully
2025/01/08:10:02:00 INFO user registered successfully
2025/01/08:10:03:00 INFO user logged in successfully
2025/01/08:10:04:00 INFO amount deposited successfully
2025/01/08:10:05:00 INFO amount withdrawn successfully
2025/01/08:10:06:00 INFO amount transferred successfully
2025/01/08:10:07:00 INFO user logged out
2025/01/08:10:08:00 INFO user logged in successfully
[DEBUG] get log info 2025/01/08:10:00:00 2025/01/08:10:10:00
Plain text
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.