بیان بیست و ششم

از چشم‌انداز جوانی که بنگری، زندگی آینده‌ای دراز و بی‌پایان است؛ ولی از چشم‌انداز پیری، تنها گذشته‌ای بسیار کوتاه به چشمت می‌آید. وقتی با کشتی دور می‌شویم، اجزای ساحل ریز و ریزتر می‌شوند و امکان شناسایی و تمایزشان نیز کمتر؛ هم‌چون سال‌هایی که پشت سر نهاده‌ایم با همه رویدادها و تکاپوهایشان.

فیلم “زندگی کردن” کوروساوا

فیلم Ikiru 1952 به معنی زندگی کردن داستان یک کارمند شهرداریه که 30 سال کار اداری و بروکراتیک دلمرده ای داره که هر روز در حال پاسکاری اداری کارها به ادارات دیگه هستن. 30 سال مرخصی نرفته و لذت زندگی با خانواده رو نچشیده و تمام حقوقش هم پس انداز کرده تا اینکه میفهمه سرطان داره و نهایتا 6 ماه دیگه زنده است.

یادش می افته که با همسر مرحومش و پسرش تفریحی نکرده و 30 سال توی اداره مشغول کاغذبازی بی هدف بوده و ارباب رجوع رو بیخودی پاسکاری کرده و مسئولیت هیچ کاری رو بر عهده نداشته. حتی یادش نمیاد که توی این 30 سال چه کار مفیدی برای مردم انجام داده.

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

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

https://www.youtube.com/watch?v=RdfvVRNJ9do

مشکل N+1 – سوال مصاحبه

N+1 query problem وقتی است که برنامه دیتایی که با یک query می توانست به دست بیاره رو N بار بیشتر query بزنه. طبیعتا مشکل پرفورمنسیه.

توی مدیوم یه مقاله هست که این مشکل رو با یک مثال توضیح داده که باعث میشه خیلی خوب مشکل N+1 query رو بفهمیم.

فرض کنید که میخاید کیک درست کنید. یخچال توی آشپزخونه نیست و توی اتاق زیر شیروانیه بنابراین برای برداشتن هر چیزی از تو یخچال باید پله ها رو بالا بریم. شما توی آشپزخونه هستید ولی کتاب شیرینی پزی توی اتاق خوابه.

اول میرید از اتاق خواب کتاب آشپزی رو میارید به آشپزخونه بعد میبینید گفته که به 200 گرم آرد نیاز دارید. میرید اتاق زیرشیروانی و آرد رو میارید. دستور پخت نوشته 3 عدد تخم مرغ، دوباره میرید اتاق زیرشیروانی و 3 تا تخم مرغ میارید. دوباره میبینید که نوشته یه لیوان شیر و ….

میبینید که با این روش شما N بار اضافه رفتید بالا در حالی که همون دفعه اول که رفتید کتاب آشپزی رو بیارد بهتر بود همه وسایل مورد نیاز رو هم بیارید.

حالا یه مثال از ORM جنگو ببینیم که این مشکل رو چطور حل میکنه.

فرض کنید که یه مدل Post داریم که هر Post یه Author داره و طبیعتا هر Author میتونه چند تا Post داشته باشه. رابطه 1->N هست. حالا میخایم پست ها و نویسنده هاشون رو چاپ کنیم.

توی کد بالا مشکل N+1 وجود داره.

توی خط اول چند query به دیتابیس فرستاده میشه؟ هیچ به دلیل اینکه ORM جنگو Lazy هست (تا زمان درخواست داده query ارسال نمیشه)

توی خط دوم که توی حلقه درخواست داده شده یک query به دیتابیس ارسال میشه و لیست پست ها رو میگیره و میریزه توی queryset. توی قسمت print وقتی title رو میخات چاپ کنه دیگه query زده نمیشه چون title یکی از property های Post هست که قبلا گرفته شده ولی وقتی میخات author رو چاپ کنه دوباره یک query به دیتابیس زده میشه که Author مربوط به اون پست رو بگیره (چون دو تا model جدا با رابطه 1->N هستن) بنابراین توی هر iteration از حلقه یک query دیگه زده میشه و این پرهزینه است و بهش میگن N+1 problem.

برای حل این مشکل باید برای پست ها Author ها رو هم یکجا با یک query بگیریم. برای حل این موضوع باید روی دو تا model یک join زده بشه.

ORM جنگو این مشکل رو با select_related() و prefetch_related() حل کرده.

select_related()

prefetch_related()

توی دو تا کد بالا فقط 1 query به دیتابیس زده میشه.

فرق select_related و prefetch_related چیه؟

select_related به یک Join تبدیل شده و به دیتابیس ارسال میشود و برای مدل هایی که ارتباط 1->N یا one to one دارند استفاده میشود اما prefetch_related دو داده را گرفته و به صورت پایتونی join میزنه در ضمن برای رابطه های چند به چند یا Generic استفاده میشه.

مثالی که توی مستندات جنگو هست:

مثال زیبای بعدی

معماری یک پروژه جنگو با Nginx و Gunicorn

به طوی کلی برای پیاده سازی یه پروژه که با backend پایتونی زده شده (مثل جنگو و فلسک) باید از یک اپلیکیشن سرور (مثل uWSGI یا Gunicorn) و یک وب سرور (که اینجا بهش پراکسی سرور گفته میشه استفاده کرد. مثل شکل زیر:

ولی چرا مثل یک پروژه که با php زده میشه نمیتونیم مستقیم از یه وب سرور استفاده کنیم و خلاص؟ به این دلیل که وب سرورها قابلیت اجرای وب اپلیکیشن های پایتونی رو به خوبی پیاده سازی نکردن. این روش مزایای زیادی داره یکی اینکه تمام منطق کد پایتونی توسط Gunicorn اجرا میشه و عملا Nginx فقط request رو به اون فوروارد میکنه. در عوض خود Nginx کارهای دیگه ای رو انجام میده و عملا باعث بهبود عملکرد اپلیکیشن سرور میشه مثلا درخواست های کاربر رو فیلتر می کنه و اونایی که معتبر هستن رو به اپلیکیشن سرور میده همچنین فایلهای static مثل html, css و… رو خود Nginx به کاربر میده و باعث میشه اپلیکیشن سرور کار پرهزینه انجام نده.

تصویر بالا معماری گفته شده رو نشون میده که یه قابلیت دیگه از این معماری رو میبینیم. همینطور که میبینیم 3 نمونه از پروژه با 3 worker اجرا شده که باعث افزایش کارایی اپلیکیشن میشه. در این حالت خود Nginx درخواست ها رو مدیریت می کنه و میدونه به کدوم worker بفرسته.

سایت دیجیتال اوشن جزئیات پیاده سازی این معماری رو توضیح داده

کدام دیتابیسها با سیستم migration جنگو سازگارترند؟

از بین دیتابیس های معمول برای استفاده در یک وب اپلیکیشن MySQL، PostgreSQLو SQLite پراستفاده ترند. اگر بخواهیم برای یک پروژه Django از یکی از اینها استفاده کنیم باید بدانیم سیستم Migration جنگو با همه آنها به صورت یکسان سازگار نیست. تفاوت سازگاری در آنها در چیست؟

PostgreSQL

سازگارترین دیتابیس با Migration جنگو PostgreSQL است

MySQL

این دیتابیس در عملیات تغییر schema در model ها از تراکنشها transactions پشتیبانی نمی کند (البته با موتور ذخیره سازی InnoDB از transactions هم پشتیبانی میکند به جز برخی عملیاتهای دیتابیس مانند تغییر در schema که در لینک میبینید) یعنی اگر در عملیات مایگریشن به خطایی برخورد بکند تغییرات قبلی rollback نمی شود و ممکن است دیتابیس را معیوب کند و باید تغییرات را به صورت دستی درست کنیم.

علاوه بر آن در هر عملیات مایگریشن این دیتابیس تمام اسکیماها و جدولها و ایندکس ها را از اول rewrite میکند که این در دیتابیسهای بزرگ پرهزینه است زیرا ممکن است دیتابیس production برای زمان زیادی پاسخگو نباشد.

نهایتا MySQL محدودیتهای دیگری هم دارد مانند طول نام ستونها و Index ها. این یعنی ممکن است اگر ایندکسی برای دیتابیس دیگر کار کند که طول نام آن از محدودیت MySQL بیشتر باشد با مایگریشن به این دیتابیس عملیات به خطا بخورد.

SQLite

استفاده از این دیتابیس در پروداکشن و پروژه های جدی توصیه نمی شود بخاطر محدودیتاهای شدید در تغییر اسکیما در عملیات مایگریشن که جزئیات این محدودیت ها در این لینک قابل مشاهده است.

ساخت کامند کاستوم در django-admin

توی جنگو میشه برای یک app کامند کاستوم custom command نوشت. use case های زیادی میتونه داشته باشه. فرض کنیم یه model داریم به اسم campaign که مربوط به قرعه کشی هایی هست که توی وبسایت فروشگاهمون وجود داره. این کمپین فقط عید نوروز فعاله و یه فیلد داره به اسم active که برابر با true میشه. حالا بعد از نوروز میخایم اون رو غیرفعال کنیم بهتره که بتونیم با یه کامند این تغییر رو توی دیتابیس بدیم.

برای این کار یک کامند برای campaign app میسازیم. از این به بعد هر پروژه ای که این app را به INSTALLED_APP اضافه کنه این کامند رو هم خواهد داشت. برای این کار باید توی app مورد نظر یه package با ساختار زیر بسازیم.

توی فایل campaigneactivation.py باید یه کلاس به اسم Command بسازیم که از کلاس BaseCommand ارث بری میکنه.

این کامند الان اضافه شده و میشه به شکل زیر ازش استفاده کرد.

کلاس BaseCommand پارامترهای زیادی داره که جزئیاتش تو این لینک هست

context manager توی پایتون چیه؟ به چه دردی میخوره و چطور میشه یکی نوشت؟

این سوالی بود که توی یکی از مصاحبه های کاری از من پرسیده شد و مدیر فنی اون شرکت میگفت توی یک پروژه ما نیاز داشتیم خودمون یک context manager بنویسیم.

بدلیل محدودیت منابع در سیستم، وجود مکانیزمی که برای مدیریت منابع یعنی گرفتن و رهاسازی اتوماتیک منابع می تواند به مدیریت منابع و جلوگیری از آن کمک کند. منابعی مثل فایل، کانکشن های دیتابیس و … این وظیفه context manager هست

توی پایتون برای باز کردن یک فایل میشه از کلیدواژه with استفاده کنیم. اینجا دقیقا داریم از یک context manager استفاده میکنیم. context manager به ما اجازه میده که یک resource رو به خوبی allocate کنیم و بعد از استفاده آزاد کنیم. فرض کنید که دو عملیات مرتبط دارید و میخاید این دو عملیات با هم به صورت جفتی توی یک بلاک کد انجام بشه، context manager به شما این امکان رو میده که این کار رو انجام بدید. مثلا میخایم یک فایل رو باز کنیم و توش بنویسیم و اگر در حین نوشتن توی فایل به ارور خوردیم فایل خودبه خود بسته بشه، یعنی یه جورایی این فایل که یک resource هست رو allocate کردیم و در آخر هم به درستی آزادش میکنیم و عملا هم این چندتا کار به هم مرتبط هستن و باید جفتی با هم توی یه بلاک کد انجام بشه: باز کردن نوشتن و بستن.

کد زیر دقیقا معادل کد بالاست وقتی که از context manager استفاده نکنیم. میبینید که اولا از کد بیشتری استفاده شده ثانیا دو عملیاتی که بهم مرتبط هستند و بهتر بود در یک بلاک کد استفاده شود از هم جدا شدند:

پیاده سازی context manager به صورت class

فقط با تعریف کردن متدهای __enter__ و __exit__ یک context manager ساخته ایم و میتوانیم از آن در بلاک with استفاده کنیم

جزئیات بیشتر در لینک زیر موجوده

https://book.pythontips.com/en/latest/context_managers.html

use case های دیگه ای هم برا context manger توی لینک زیر میبینیم

https://www.geeksforgeeks.org/context-manager-in-python/

https://www.linkedin.com/pulse/context-managers-python-gautam-kumar/

مدل چیکسنت میهایی

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

از طرفی اگر برای شما پیش آمده باشد که به شرکتی با پوزیشنی مشغول شوید که عملا سواد و مهارت شما خیلی کمتر از جایگاهی هست که باید باشد، شما استرس بالایی را تحمل خواهید کرد. تا اینکه در این موقعیت شغلی مطالعه کنید و چالش های کاری را پشت سر بگذارید، بعد از مدتی توانایی شما بالا رفته و حس بهتری خواهید داشت. از استرس شما کم شده و روز به روز خوشحالتر و متمرکزتر می شویم. بعد از چند سال در همان موقعیت دیگر چالش جدید نخواهید داشت و عملا هر روز یک سری تسک تکراری بدون یادگیری و بدون نیاز به فکر کردن و سرچ کردن خواهید داشت در این مرحله دپرس خواهیم بود و بهتر است بفکر جابجایی یا پروژه های جدید باشیم.

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

گزیده‌ای از کتاب – باباگوریو

آن وقت دانشجو دلباختۀ چیزهای پوچی می شود که در نظر او باشکوه و بزرگ می‌نمایند. مرد بزرگ اون فلان استاد کلژ دو فرانس است که پول میگیرد تا خود را هم‌سطح شنوندگان خود قرار دهد اون گره کراوات خود را بالا می‌آورد و با فلان زنی که در گالری درجه یک اپراکمیک نشسته است نظربازی می‌کند. در این نوآموزی‌های متوالی دانشجو از کودکی خود بیرون می‌آید، افق زندگی خود را وسعت می‌بخشد و سرانجام قشرهای انسانی که روی هم قرار گرفته و با هم جامعه انسانی را تشکیل می دهد را به خوب درک میکند. اگر او در ابتدا رژه کالسکه‌ها در شانزلیزه در یک روز خوش آفتابی دیده و تحسین کرده است، به زودی به آنجا می‌رسد که خود نیز تملک آن را آرزو کند. اوژن، هنگامی که پس از قبول شدن در امتحان ادبیات و حقوق سال اول برای تعطیلات نزد خانواده خود برمیگشت، بی آنکه خود بداند، این دوره نوآموزی را گذرانده بود. پندارهای کودکانه و افکار محدود شهرستانی را از دست داده بود. فهم و ادراک تازه و جاه طلبی تحریک شده‌اش سبب شدند که خانه پدری و زندگی خانواده را با نظری درست ببیند.

رفتار حرفه ای در محیط کار 1

در این مورد مقالات زیادی وجود داره پس من اون مواردی که خودم تجربه کردم و میدونم دردسرساز هست رو مینویسم. هدف از نوشتن یادآوری به خودم و نشون دادن این مشکلات به دوستانیه که در اول مسیر کاری هستن. این رفتارها ممکنه توی همه شرکتها مصداق نداشته باشه اما من چون توی شرکتهای کوچک و بزرگ و سازمان شبه دولتی و خصوصی هم کار کردم این موارد رو تجربه کردم.

1.حضور به موقع: این مورد ممکنه توی شرکتهای استارت آپ معنی نداشته باشه و اونها بتونن هر تایمی برن سر کار یا دورکار باشن اما توی خیلی از شرکتها یک ساعت مقرر باید حضور داشت و یک ساعت هم شناوری در نظر گرفته میشه. بهتره توی اون ساعت حاضر باشیم. حضور به موقع در طولانی مدت برند خوبی از ما میسازه از طرفی بقیه روی ما بیشتر حساب می کنن.

2.انجام کار شخصی در تایم اداری: حرفه ای ترین حالت اینه که در ساعت کاری فقط کارهای شرکت رو انجام بدیم و توی اون بازه زمانی از بورس بازی، سوشیال مدیا و معامله خودرو و هر کار دیگه ای خودداری کنیم در عوض سر وقت از شرکت بیایم بیرون و بریم به زندگیمون برسیم.

3.اضافه کاری بیش از حد: بهترین حالت اینه که اضافه کاری هر ماه یه مقداری معقولی باشه. اینکه از نیروهای زیرمجموعه اضافه کاری بیش از حد بخایم حرفه ای نیست خود زیرمجموعه هم باید سعی کنه توی تایم کاری تسکها رو ببنده و اضافه کاری رو به حداقل برسونه. در عوض از اون تایم برای تفریح، خانواده و کارهای شخصیش استفاده کنه

4.رومنس در آفیس: این مورد نیاز به توضیح نداره، رابطه عاطفی تو کار عملکرد دو طرف رو نابود می کنه

5.رابطه کاری: همه میگن اگه رابطه دوستانه ای با هم تیمی ها داشته باشیم خیلی خوبه ولی حد این رابطه دوستانه چقدره؟ بنظرم باید نهایتا رابطه دوستانه در حد همکار بمونه (حداقل در محیل کار). کلا توی رابطه کاری اگر رفتاری باعث حس ناراحتی در کسی شد بدونیم که زیاده روی کردیم.

6.استفاده از ادبیات کاری: توی آفیس بهتره از ادبیات زننده و جنسی و کلمات خارج از عرف استفاده نکنیم.

7.همیشه خودت باش!: نه این کاملا درست نیست. خودت نباش! اگر منظور از این جمله اینه که صادق باش میتونیم بپذیریم ولی هر محیطی رفتار خودش رو داره. نباید اون طوری که با پارتنرمون توی کافی شاپ صحبت می کنیم با همکارمون توی محیط کار حرف بزنیم. نباید اون طوری که توی خونه لباس می پوشیم در محیط کار هم باشیم.

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