Concurrency vs Parallelism

Concurrency به وقتی گفته میشه چند تسک روی زمانهایی که با هم overlap دارن انجام میشن، نه اینکه لزوما در یک زمان انجام بشوند. مثل multitasking مثلا multi-thread

Parallelism یعنی وقتی واقعا کارها همزمان انجام میشن، مثلا 2 تا تسک روی دو تا CPU مجزا انجام می شوند Multi-Processing

تبدیل n+1 عدد query به 3 query

این یک مثال واقعی از بهبود یک پروژه است. query اولیه به شکل زیر بود:

با ابزار django debug toolbar تعداد query های این تکه کد را مرور کردم و جاهایی که به سرور query زده میشود به این شکل است:

  1. در خط Branch.objects.get(name__iexact=”bss”).office_set.all() یک query به دیتابیس زده میشود.

2. در خط for el in bss_branch: یک query به دیتابیس زده می شود.

3. در خط for svc in el.services.all(): یک query به دیتابیس زده میشود. یعنی اگر در bss_branch تعداد N المان وجود داشته باشد به ازای هر کدام یک query در این قسمت زده خواهد شد.

یعنی برای هر el که تعداد آن به اندازه bss_branch هست یک query جدید داریم

بنا براین در کد بالا یک query زده شده و branch ها استخراج شده (در قسمت 1) که ترجمه آن:

در قسمت دوم یک query زده شده و office های آن branch استخراج شده:

در قسمت سوم به ازای هر کدام از office ها یک query زده شده و service های آن استخراج شده به عنوان مثال یکیش رو آوردم:

پس در مجموع N+1 درخواست دیتابیس query زدن شد.

حالا اینو بهینه میکنیم به کد زیر:

در این نمونه کد query های زیر را داریم:

  1. در خط bss_branch = Branch.objects.get(name__iexact=”bss”).office_set.prefetch_related(‘services’) یک query به دیتابیس داریم.
  2. در خط for el in bss_branch: یک query زده شده و office های branch را استخراج کرده.
  3. دوباره در همان خط یک query زده شده و service های تمامی office ها یک جا استخراج شده در این قسمت دیگر N بار query زده نشده

query قسمت 1

query قسمت 2

query قسمت 3

همانطور که توی کد بالا میبینید توی خط آخر تمامی query ها ادغام شده اند

بنابراین N+1 دستور query به 3 query تبدیل شد

مشکل ثبت مجدد فرم با رفرش

. توی کد زیر بعد از ثبت کردن فرم اگر صفحه را رفرش کنیم همان فرم دوباره ثبت میشود.

مشکل در فروم جنگو این جوری توضیح داده شده است:

یعنی بعد از POST موفق باید فرم را redirect کنیم که با این کار صفحه جدید با GET فراخوانی میشود در نتیجه اگر رفرش کنیم باز هم در خواست GET ارسال میگردد. یعنی کد را به شکل زیر تغییر میدهیم.

serializer توی Django Rest Framework با دیتای ورودی چیکار میکنه؟

بهترین روش یادگیری یه فریم ورک خوندن کد خود فریم ورک و داکیومنت توی خود کد هست. برای serializer توی جنگو یک کامنت هست توی rest_framework/serializer.py که:

خیلی خوب توضیح میده که اگر به serializer پارامتر data رو پاس داده باشیم تابع is_valid قابل استفاده است. و initial_data هم در دسترس هست که همون دیتایی هست که به API پاس داده شده. بعد از is_valid این داده ورودی به valid شده تبدیل میشه که میتونیم توی validated_data ببینیم. مثلا اگر Id به object مربوطه تبدیل میشه. و errors و data هم در دسترس خواهد بود. data درواقع اون رکورد جدیدی هست که ایجاد شده است.

مثال زیر رو ببینید:

میبینید که بعد serializer.is_valid() مقادیر مربوطه رو پرینت کردم.

مثال خروجی هم در ادامه میبینید:

باگ توی اضافه کردن EventListener

در کد زیر باگ نهفته ای وجود دارد. یک دکمه حذف یک ردیف از جدول وجود دارد که وقتی روی آن کلیک میکنیم. eventListener به آن اضافه میشود. باگ به این شکل از که به هر تعداد کلیک بر روی این دکمه EventListener اضافه میشود. تا زمانی که صفحه رفرش شود. این باگ موجب میشود که در نهایت به تعداد eventListener ها درخواست به سرور ارسال میشود.

برای حل این مشکل باید هر وقت خواستیم EventListener اضافه کنیم، قبلی را پاک کنیم.

چرا Promise و کاربردهاش

برای حل مشکل Asynchronous توی جاوااسکریپت. قبل از Promise برنامه نویس ها از callback استفاده میکردند که مشکلات زیادی داشته از جمله callback hell

کد بالا رو در نظرم بگیرید. توی هر مرحله باید callback تودرتو نوشت که باعث میشه. کد کثیف و اگر توی کد داخلی باگی پیدا بشه پیدا کردن و فیکس کردنش سخته.

توی Promise میتونیم به صورت زنجیروار همه عملیاتها رو مدیریت کرد بجای ساختار تودرتو. گارانتی شده که یا عملیات موفق میشه و تابع resolve اجرا میشه یا عملیات ناموفق خواهد بود و تابع reject اجرا میشه. یعنی به راحتی میتونی تمامی حالات رو با تابع then و catch مدیریت کنیم. حتی اگر عملیات به دلیل کندی زیاد طول بکشه.

مثال بالا رو میتونیم زنجیری مدیریت کنیم

یکی از کاربردهاش API call هست

توی مثال زیر حتی چندین API با هم صدا زده میشه و میبینیم که چقدر خوانا و راحت نوشته میشه:

Promise چیه؟

Promise یک آبجکت هست که یک تسک Asynchronous رو توی جاواساکریپت اجرا می کنه. این آبجکت تو تابع داره resolve و reject که این آبجکت گارانتی میکنه که یکی از این دو قطعا اجرا میشه. بخاطر همین بهش میگن Promise. یعنی گارانتی میکنه که این تسک یا موفق میشه یا نه و خارج از این دو حالت نیست.

با صدا زدن یه Promise شما از دو تابع میتونید استفاده کنید. then و catch اولی وقتی که تسک موفق بشه خروجی رو میگیره و دومی وقتی که

توی کد بالا موارد زیر اتفاق میوفته:

  1. Promise درجا اجرا میشه
  2. دو ثانیه برنامه می ایستد
  3. resolve اجرا میشه
  4. then اجرا میشه

اگر بجای resolve تابع reject رو اجرا کنیم. توی مرحله 4 بجای then تابع catch اجرا میشه.

بازنویسی serializer توی Django Rest Framework

توی serializer های DRF گاهی لازمه وقتی متد list() اون صدا زده میشه باید قبلش دیتایی که ازش گرفته میشه تغییری بدیم برای این کار از متد to_representaion استفاده میکنیم.

یک باگ ساده و یک راه حل ساده تر

کد زیر یک باگ جالب داره.

در صورتی که branch انتخاب نشده باشه cleaned_data.get(“branch”).name این اکسپشن میده. برای اصلاحش باید یه تغییر ساده بدیم

اپراتورهای rest و spread در جاوااسکریپت

امروز با کد زیر مواجه شدم و فهمش برام جذاب بود:

با مفهوم اپراتورهای rest و spread آشنا شدم که از ES6 به بعد به جاوااسکریپت اضافه شدن.

کد زیر رو در نظر بگیرید»

خروجی کد بالا [3, 2, 4] است. حالا کد زیر رو ببینید:

حالا خروجی کد بالا برابر با 4 است. یعنی اپراتور spread که همون … است آرایه رو به المانهای توش پخش میکنه و نتیجه اون اپراتور میشه Math.max(4,2,3)

اپراتور دیگه ای وجود داره به اسم rest:

یک سری مثال در جاوااسکریپت و react