CodeCrafters
765 subscribers
91 photos
50 videos
42 files
170 links
Download Telegram
فصل دوم کتاب از فصل‌های بشدت محبوب برای من هستش که سعی داره هر اصطلاحی رو در برنامه بنویس بصورت دقیق توصیف کنه


اجرای سریالی و موازی سازی

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

یک برنامه بطور کل به مجموعه‌ای از دستورالعمل‌ها گفته میشود که بصورت متوالی اجرا میشود

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

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

اجرای سریالی
یک برنامه لیستی از دستورالعمل هاست و البته ترتیب اجرای آن مهم هست

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

برنامه نویسی بصورت وظیفه این امکان رو بهمون میده که بصورت مستقل از زبان ماشین محاسبات خود را انجام دهیم که به آن برنامه نویسی ماژولار میگوییم

یک تسک میتواند بخشی از یک کار باشد، اگر جامعه کلامی ما پردازنده باشد میتونیم اون رو یک دستورالعمل بنامیم
یک تسک میتونه یک توالی از عملیات باشه که انتزاعی از یک مدل در دنیای واقعی هست (مثه نوشتن متن در یک فایل)

اما در نهایت میتونیم task رو بعنوان یک واحد اجرا از انتزاع کلی دانست تصویر اول

اجرای سریالی مجموعه‌ای از تسک‌ها هستش که بصورت زنجیروار قرار گرفتن تسک دوم تسک اول رو دنبال میکنه، و تسک دوم توسط تسک سوم دنبال میشه


محاسبات متوالی
برای توصیف پدیده‌های پویا مرتبط با زمان از اصطلاح متوالی استفاده میکنیم تصویر دوم کامنت‌ها برای درک بیشتر یک بازی دونفره رو تصور کنید که نفرات به نوبت و پس از بازی نفر دیگری حق بازی دارند برای درک بهتر بازی شطرنج رو تصور کنید

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

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

مزایا و معایب محاسبات متوالی
سادگی: هر برنامه ای را میتوان در این پارادایم نوشت یک مفهوم ساده و قابل پیش بینی و رایج است
محاسبات متوالی یک رویکرد ساده با محمچعه‌ای واضح از دستورالعمل‌های گام به گام در مورد اینکه چه باید کرد و در چه زمانی انجام داد هستش

مقیاس پذیری: توانایی یک سیستم برای رسیدگی به مقدار فزاینده‌ای از کار، یا پتانسیل افزایش توانایی سیستم برای رسیدگی به کار برای سازگاری با رشد، با افزودن منابع سخت افزاری اگر بهبودی در سیستم دیده شود سیستم مقیاس پذیر می‌باشد ،اسکیل عمودی تنها راه افزایش مقیاس در محاسبات متوالی هستش

سربار: در محاسبات متوالی هیچ‌ ارتباط یا هماهنگی بین مراحل برنامه مورد نیاز نیست اما یک سربار وجود دارد که ممکن هست از همه منابع استفاده نکنیم


اجرای موازی(parallel)
همانطور که دیدیم، در اجرای سریال، تنها یک دستور در یک زمان اجرا می شود.
برنامه نویسی متوالی همان چیزی است که بیشتر مردم ابتدا یاد می گیرند و اکثر برنامه ها به این صورت نوشته می شوند: اجرا از ابتدای تابع اصلی شروع می شود و به صورت سریالی ادامه می یابد، یک کار/تابع، فراخوانی/عملیات در یک زمان.

وقتی این فرض را حذف می‌کنیم که می‌توانیم فقط یک کار را در یک زمان انجام دهیم، امکان کار موازی را باز می‌کنیم

لینک وب‌سایت

#concurrency

@code_crafters
👍21
تصور کنید با شما تماس گرفته و باید سریع به مسافرت برید چهار دست لباس دارید که باید شسته بشن میتونید شروع به شستن کنید اما اگر در نزدیکی شما یک خشکشویی وجود داشته باشد چه؟؟؟سریع به آنجا میروید و همه لباس‌هاتون رو باهم توسط دستگاه‌های متعدد آماده میکنن

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

اجرای موازی به این معنی است که اجرای کار از نظر فیزیکی همزمان است. اجرای موازی برعکس اجرای سریال است. موازی بودن را می توان با تعداد کارهایی که می توان به صورت موازی اجرا کرد اندازه گیری کرد تصویر اول در کامنت‌ها

استقلال وظیفه در مبحث محاسبات متوالی ما فقط نیاز به پردازنده با کلاک بالاتر بودیم، اما در محاسبات موازی عمدتاً برای کاهش تأخیر با تقسیم یک مسئله به وظایفی که می‌توانند به طور همزمان و مستقل از یکدیگر اجرا شوند، استفاده می‌شود.

استفاده از محاسبات موازی مشکل خاصی است. برای اعمال محاسبات موازی برای یک مسئله، باید این امکان وجود داشته باشد که مسئله به مجموعه ای از وظایف مستقل تجزیه شود تا هر منبع پردازش بتواند بخشی از الگوریتم را به طور همزمان با بقیه اجرا کند. استقلال در اینجا به این معنی است که منابع پردازش می توانند وظایف را به هر ترتیبی که دوست دارند و هر کجا که دوست دارند پردازش کنند، تا زمانی که نتیجه یکسان باشد.
عدم انطباق با این الزام، مشکل را غیرقابل موازی سازی می کند.
کلید درک اینکه آیا یک برنامه می تواند به صورت موازی اجرا شود این است که تجزیه و تحلیل شود که کدام وظایف را می توان تجزیه کرد و کدام وظایف را می توان به طور مستقل اجرا کرد
 برنامه ای که می تواند به صورت موازی اجرا شود، همیشه می تواند متوالی شود، اما یک برنامه متوالی همیشه نمی تواند موازی شود
استقلال کار همیشه امکان پذیر نیست زیرا هر برنامه یا الگوریتمی را نمی توان از ابتدا تا انتها به وظایف مستقل تقسیم کرد. برخی از کارها می توانند مستقل باشند، و برخی نمی توانند اگر به وظایفی که قبلاً اجرا شده اند وابسته باشند.این امر به توسعه دهندگان نیاز دارد تا قطعات مختلف وابسته یک برنامه را برای به دست آوردن نتایج صحیح همگام سازی کنند
همگام سازی به معنای مسدود کردن اجرای وظیفه در انتظار وابستگی است(مثال بازی شطرنج)
هماهنگ کردن محاسبات موازی وابسته به هم از طریق همگام سازی می تواند موازی بودن برنامه را به شدت محدود کند و چالش مهمی را در نوشتن برنامه های موازی در مقایسه با برنامه های متوالی ساده ایجاد می کند.

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

محاسبات موازی
محاسبات موازی از تجزیه برای تقسیم مسائل بزرگ یا پیچیده به وظایف کوچک استفاده می کند و سپس از اجرای موازی سیستم زمان اجرا برای حل موثر آنها استفاده می کند.(برای مثال رویکرد معروف به brute-force)

قانون امدال
اگر فکر میکنید با افزودن منابع بیشتر و موازی سازی کردن بیشتر سرعت رو مدام و مدام افزایش میدهید سخت در اشتباه هستید
تصور کنید سه تسک دارید که زمان اجرایی آنها متفاوت هستش (۱,۴,۳) تسک ۴ رو میتونید به دو تسک دوتایی بشکنید و موازی کنید اما تسک ۳ یک تسک متوالی هست پس هرکاری کنید نمیتونید زمان برنامه رو به کمتر از ۳ برسونید

یک برنامه موازی به سرعت کندترین قسمت متوالی آن اجرا می شود یک فرمول هم داره در تصویر دوم کامنت‌ها

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

همزمانی (concurrency) و موازی سازی (parallelism)

همزمانی در مورد وظایف متعددی است که بدون ترتیب خاصی در بازه های زمانی همپوشانی شروع، اجرا و تکمیل میشند

موازی بودن یک ویژگی اجرایی است. این اجرای فیزیکی همزمان وظایف در زمان اجرا است و به سخت افزار با منابع محاسباتی متعدد نیاز دارد روی لایه سخت افزاری قرار دارد

همزمانی و موازی بودن یک چیز نیستند

لینک وب‌سایت

#concurrency

@code_crafters
4👍2
تفاوت پروفایلینگ و بنچمارکینگ

در چند پست قبلی راجب دو‌موضوع profiling و benchmarking صحبت کردیم
با ابزارهای اون آشنا و بصورت عملی هم اجرا کردیم

تفاوت این دو در چیست؟؟؟
اندازه گیری و بررسی پرفورمنس معمولا شامل دو فرآیند متفاوت است پروفایلینگ و بنچمارکینگ، هر دو روش‌های ضروری برای بهبود عملکرد یک برنامه کاربردی هستند و بسته به موقعیت، تنها تنها یکی از این دو ممکن است اجرا بشه، در حالیکه در موارد دیگر این دو مکمل همدیگه هستند


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


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


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

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


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

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

وضعیت زیر را در نظر بگیرید:
-ما می‌خواهیم زمان پاسخ‌دهی سرور اصلی پروژه خود را بهبود بخشیم، بنابراین پروژه را نمایه (profile) می‌کنیم و تشخیص می‌دهیم که یک عملکرد خاص 10٪ از زمان کلی را تشکیل می‌دهد

-بنابراین ما تصمیم داریم بر روی بهبود عملکرد آن عملکرد تمرکز کنیم، ما منطق را در آن تابع بهبود می‌دهیم تا کارآمدتر باشد، به این امید که تاثیر کلی عملکرد منفی آن را کاهش دهیم

پس از تکمیل تغییر کد، با مقایسه زمان پاسخ سرور قبل از تغییر با زمان پاسخ سرور پس از تغییر، پروژه خود را محک (benchmark) می زنیم تا تأیید کنیم که تغییر (امیدوارم) تا چه اندازه باعث بهبود آن شده است.


لینک وب‌سایت

#monitoring

@code_crafters
2👍2🔥1
اکنون بخش دشوار اینجاست:
بر اساس موارد بالا، ممکن است استدلال کنید که اگر از پروفایل برای شناسایی عملکرد استفاده کنیم، می‌توانیم دوباره نمایه نماییم تا مقایسه کنیم. این از نظر فنی امکان پذیر است، اما بستگی به این دارد که شما در حال تلاش برای رسیدن به این معیار هستید. از آنجایی که ابزارهای نمایه سازی عملکرد تک تک عملکردها را در حین اجرای برنامه ردیابی می کنند، مقداری سربار اضافه می کنند که زمان اجرا را کاهش می دهد، که می تواند تأثیر مربوط به تغییر را تغییر دهد.

یک راه بهتر برای ارزیابی تأثیر کلی عملکرد یک تغییر، گرفتن معیارها با استفاده از ابزارهایی است که استانداردهای عمومی صنعت مانند TTFB را اندازه گیری می کند.
خلاصه بگم TTFB مخفف Time to First Byte است. اگر بخواهیم به دور از هرگونه پیچیدگی معنای آن را بگوییم، یعنی مدت‌زمانی که طول می‌کشد تا اولین بایت از پاسخ سرور به سیستم کاربر درخواست‌کننده برسد. بگذارید قضیه را کمی باز کنیم. یکی از مهم‌ترین کارایی‌های TTFB این است که کند بودن بیش‌ازحد سرور را معلوم می‌کند.


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

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

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

یکی از بهترین روش ها برای توضیح این تنوع مورد انتظار، انجام چندگانه است.

بررسی می کند تا تأیید کند که یک رعایت خاص به دلیل ویژگی های محیطی فقط "تصادفی" نبوده است


لینک وب‌سایت

#monitoring

@code_crafters
4👍1
فصل سوم کتاب همزمانی در پایتون

در این فصل نگاهی عمیقتر به سخت افزار بالاخص cpu انداخته

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

پردازنده (CPU)
پردازنده‌ها قدیمی مدارهایی بودن که کارهای متفاوتی رو انجام میدادن و عملیات برای دستگاه‌های جانبی پیش میبردن
اما امروز به شکل مدرنتر خودش بر وظیفه اصلی خودش که همون اجرای دستورالعمل‌ هاست متمرکز شده، پردازنده از اجزای مختلفی تشکیل شده
واحدکنترل CU که وظیفه تفسیر دستورالعمل‌های ماشین را دارد

واحد منطق حسابی ALU عملیات حسابی و بیتی رو انجام میده

به لطف این دو بخش پردازنده امروزی برنامه‌های پیچیده‌تری رو پردازش میکنه

علاوه بر این واحد cache نیز که موجب افزایش بیشتر سرعت در پردازنده شده


زمانیکه یک برنامه رو اجرا میکنید داده‌های اون بر روی RAM قرار میگیرد که در اتصال با پردازنده هستش اما پردازنده بطور مستقیم به RAM دسترسی ندارد توانایی پردازنده برای محاسبه بسیار سریعتر از توانایی RAM برای انتقال داده به پردازنده هستش، به همین دلیل در پردازنده‌های مدرن یک یا چند سطح حافظه کش برای افزایش سرعت قرار دارد
در پست‌های قبلی گفتیم که هنگام خرید دستگاهی اندازه پردازنده یکی از عوامل مهم و تاثیر گذار در قدرت اون دستگاه در کنار فرکانس پردازنده هستش، یکی دیگر از موارد مهم در هنگام خرید همین کش هستش که با نمادهای L1,L2,L3 بر روی دستگاه‌ها نوشته شده و بالا بودن مقدار آن که مقداری مگابایتی هستش یکی موضوعات حائز اهمیت در انتخاب دستگاه بهتر به شمار می رود

کش بعنوان یک میز کار برای پردازنده در نظر بگیرید تصویر اول در کامنت‌ها

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

تمام دسترسی‌ها و انتقالات موجب تاخیر میشود و کش بابت کاهش این تاخیر قرار گرفته

چرخه اجرای پردازنده
پردازنده یک فرایند مداوم از اجرای دستورالعمل را در مراحل مختلف انجام میده که به عنوان چرخه پردازنده شناخته میشه و در ساده ترین شکل خود در چهار مرحله مختلف به شکل زیر هستش تصویر دوم در کامنت‌ها
۱- واکشی.  CU دستورالعمل را از RAM یا کش واکشی می کند و آن را در CPU کپی می کند.  در این فرآیند، CU از شمارنده‌های مختلفی استفاده می‌کند تا بفهمد چه دستورالعملی باید واکشی شود و کجا آن را پیدا کند

۲- دستورالعمل که قبلاً واکشی شده رمزگشایی شده و برای پردازش ارسال می شود
انواع مختلف دستورالعمل ها کارهای متفاوتی انجام می دهند، بنابراین بسته به نوع دستورالعمل و کد عملیات، باید بدانیم دستورالعمل ها به کدام واحدهای پردازشی ارسال می شود

۳- سپس دستور محاسبات به ALU منتقل می شود و اجرا را شروع می کند

۴- پس از تکمیل دستورالعمل، نتیجه در RAM نوشته می شود و دستور بعدی اجرای خود را آغاز می کند

سپس پردازنده به مرحله 1 برمی گردد تا زمانی که دیگر دستورالعملی برای واکشی باقی نماند

توسعه دهندگان دوست دارن همه چیز رو خودشون کنترل کنن(سخت افزار، خطاها، مدیریت‌ها و اشتراک منابع)
با توجه به رشد سخت افزار متناسب با مدیریت‌های گوناگون اینکار به یک مسئله پیچیده تبدیل شده، لذا امروزه ما از یک مدیر سیستم عامل که یک رابط بین توسعه دهنده و سخت افزار هست بهره میبریم به مجموعه این رابط‌ها فراخوانی سیستم مینامیم که با در اختیار گذاشتن خدمات و ابزارهایی که با سخت افزار در تعامل هستند برنامه‌های کاربردی میتوانند از آن استفاده کنند

سیستم عامل از طریق گذرگاه به منابع سخت افزاری دسترسی دارد، ما دو نوع سطح دسترسی داری فضای کاربر که در اختیار کاربر است و فضای سیستم عامل که زیر آن سخت افزار قرار دارد ، کاربر و برنامه های کاربر نمیتوانند مستقیم با سخت افزار ارتباط بگیرن سخت افزار بشکل کامل در کنترل و احاطه کرنل می باشد


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

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

لینک وبسایت

#concurrency

@code_crafters
👍2
معماری متقارن چند پردازشی SMP
حافظه معمولا سرعت پایینتری نسبت به پردازنده‌ها دارن که این خود موجب تاخیر میشود به همین دلیل امروزه از سیستم‌های چندپردازنده‌ای از SMP استفاده میکنند که با یک فضای آدرس واحد به حافظه مشترک متصل شده و تحت یک سیستم عامل کار میکند، در این معماری پردازنده‌ها توسط یک شبکه ارتباطی از طریق گذرگاه سیستم به هم متصل میشن، هرچند این شبکه‌ها سریع هستن اما اگه پردازنده‌ها نیاز به تبادل با هم داشته باشند از طریق چندکانال صورت میگیرد که انی نیست و در صورت افزایش تعداد منابع در حال تعامل فاصله بینشون موجب تاخیر میشه مجدد، بنابراین در این معماری هر پردازنده کش خصوصی خود را دارد تا ترافیک system bus را کاهش داده و تاخیر کمتری روی میده تصویر اول در کامنت‌ها
جالب ترین ویژگی SMP این است که وجود چندین پردازنده برای کاربر نهایی شفاف است.  سیستم عامل از زمان‌بندی فرآیندها در تک تک پردازنده‌ها و همگام‌سازی بین آن پردازنده‌ها مراقبت می‌کند، با این حال، در چنین سیستم هایی، افزایش تعداد پردازنده های متصل به یک گذرگاه سیستم مشترک، آن را به یک گلوگاه تبدیل می کند.  این مشکل با انسجام کش بدتر می شود، جایی که چندین هسته پردازشگر سلسله مراتب حافظه یکسانی را به اشتراک می گذارند اما کش های داده و دستورالعمل L1 خود را دارند

توسعه پروتکل MESI مشکل انسجام حافظه رو حل کرد ،با ردیابی وضعیت هر کش موجب میشه همه پردازنده‌ها دید ثابتی از داده داشته باشند


تنها راه فراتر رفتن از SMP سیستم‌های توزیع شده هست که در یک شبکه باهم در ارتباط داشته باشند و بدین شکل هر سیستم بعنوان یک خوشه حافظه و کش خودش رو داره و بر بقیه تاثیر نمیزاره


تصویر دوم در کامنت‌ها
طبقه بندی رایانه های موازی بر اساس دستورالعمل ها و جریان داده ها.
دو دسته SISD , MISD مناسب مواری سازی نیستند کار کرده انها بگونه‌ای هستش که یک بلوک از دستورالعمل‌هارو میگیرن و تنها همون رو پیش میبرند

در دسته سوم، یک دستورالعمل، داده های متعدد (SIMD) است که دارای واحدهای کنترل مشترک در چندین هسته است، با این طراحی، تنها یک دستور را می توان به طور همزمان بر روی تمام منابع پردازشی موجود اجرا کرد، که اجازه می دهد همان عملیات روی مجموعه بزرگی از عناصر داده به طور همزمان انجام شود، با این حال، مجموعه دستورالعمل در ماشین‌های SIMD محدود است، و آنها را برای حل مسائل خاصی که نیاز به قدرت محاسباتی بالایی دارند اما تطبیق‌پذیری زیادی ندارند، مناسب می‌سازد، واحدهای پردازش گرافیکی (GPU) نمونه شناخته شده SIMD امروزه هستند
دسته چهارم دستورالعمل های چندگانه، داده های چندگانه (MIMD) است، در اینجا، هر منبع پردازش یک واحد کنترل مستقل دارد
بنابراین، به انواع خاصی از دستورالعمل ها محدود نمی شود و دستورالعمل های مختلف را به طور مستقل بر روی یک بلوک جداگانه از داده ها اجرا می کند، بنابراین، شامل معماری هایی با چندین هسته، چندین CPU یا حتی چندین ماشین می شود تا وظایف مختلف را بتوان به طور همزمان در چندین دستگاه مختلف اجرا کرد

پردازنده‌های گرافیکی برای کارهای محاسباتی تکراری و موازی مانند پردازش تصویر و ویدئو، یادگیری ماشین، شبیه‌سازی‌های مالی و بسیاری دیگر از محاسبات علمی مناسب هستند. عملیاتی مانند جمع و ضرب ماتریس به راحتی با استفاده از یک GPU انجام می شود زیرا اکثر این عملیات در سلول های ماتریس مستقل از یکدیگر و مشابه هستند و بنابراین می توان آنها را موازی کرد تصویر سوم در کامنت‌ها



لینک وبسایت

#concurrency

@code_crafters
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
کارفرما ازم میپرسه این کد چکاری میکنه و من شروع میکنم به توضیح دادن

#fun

@code_crafters
😁7
This media is not supported in your browser
VIEW IN TELEGRAM
مراسم پیشوازی از نوروز در مناطق کردستان، فرهنگی دیرینه

پیاپیش نوروز پیروز

#free

@code_crafters
🔥6❤‍🔥22👎1
CodeCrafters
مراسم پیشوازی از نوروز در مناطق کردستان، فرهنگی دیرینه پیاپیش نوروز پیروز #free @code_crafters
یچی جالب راجب فرهنگ رنگ لباس زنان بهتون بگم

در این مراسمات سه نوع رنگ لباس برای زنان حائز اهمیت هست که صد البته پسر

رنگ لباس سیاه برای دختران به معنای عزادار بودن بابت یکی از نزدیکانش می‌باشد که میتونه شوهرش یا معشوقه‌ش باشه و با پوشیدن این لباس به بقیه اعلان میکنه که فعلا در دسترس برقراری ارتباط نیست و علاقه‌ای نداره

رنگ لباس زرد برای دختران به معنای داشتن معشوقه و یا نامزد هستش و این رو به بقیه میرسونه که نسبت به یکنفر تعهد عاشقانه داره

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

دیگه از خاطرات این فرهنگ دیرینه نگیم براتون😅😅😅😅
🫡152🔥2🤔2🥱2😁1
داکر و ۱۳ ترفند مهم در آن


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

در اینجا 13 ترفند داکر رو با موضوعیتی برای مهندسین ارشد بررسی میکنیم که فراتر از اصول اولیه هستند و راه های قدرتمند و کمتر شناخته شده ای را برای استفاده از داکر ارائه معرفی میکنیم


1-ساخت چند مرحله‌ای برای تصاویر (image) کارآمد
ساخت‌های چند مرحله‌ای در داکر یک تکنیک قدرتمند برای ایجاد تصاویری ناب و ایمن‌تر با جدا کردن محیط ساخت از محیط تولید در همان داکرفایل است

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

# Syntax for multi-stage builds
# Stage 1: Build the application
FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# Stage 2: Create the final image
FROM alpine:latest
COPY --from=builder /app/myapp /app/myapp
ENTRYPOINT ["/app/myapp"]


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


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

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

جداسازی محیط های ساخت: زمانی که نیاز به ساخت برنامه های کاربردی در یک محیط خاص دارید اما می خواهید آنها را در محیط دیگری اجرا کنید.


بهترین رویکرد

بهینه سازی استفاده از کش ساخت:
دستورات کپی را سفارشی کنید و با دقت اجرا کنید تا ذخیره لایه ها به حداکثر برسد

کوچک کردن اندازه تصویر نهایی: فقط مصنوعات مورد نیاز برای اجرای برنامه را در تصویر نهایی کپی کنید

مراحل ساخت برچسب: از مراحل نامگذاری شده برای بهبود خوانایی و قابلیت نگهداری داکرفایل خود استفاده کنید

دام‌های رایج
پیچیدگی بیش از حد: از ساخت‌های پیچیده چند مرحله‌ای غیرضروری که می‌تواند منجر به نگهداری داکرفایل دشوار شود، اجتناب کنید

نادیده گرفتن زمینه ساخت: حواستان به زمینه ساختی باشد که به daemon داکر ارسال می کنید، زیرا زمینه های بزرگ غیر ضروری می توانند روند ساخت را کند کنند

لینک وبسایت

#docker

@code_crafters
2👍1
2-له کردن (Squashing) لایه‌های ایمیج داکر
له کردن لایه های تصویر در داکر تکنیکی است که می تواند اندازه تصاویر داکر شما را به میزان قابل توجهی کاهش دهد.با ترکیب تمام لایه های تولید شده در طول ساخت تصویر در یک لایه، می‌توانید ذخیره سازی و توزیع تصاویر داکر خود را بهینه کنید

له کردن چیست
هنگامی که یک تصویر داکر می سازید، هر دستورالعمل در داکرفایل یک لایه جدید ایجاد می کند.این لایه‌ها می‌توانند داده‌های غیرضروری را جمع‌آوری کنند که منجر به ایجاد تصاویر متورم می‌شود. (له کردن) Squashing تعداد لایه ها را در تصاویر داکر با ادغام آنها در یک لایه کاهش می دهد، که می تواند به حداقل رساندن اندازه تصویر کمک کند

چگونه از له کردن استفاده کنیم
برای له کردن لایه‌های تصویر، می‌توانید هنگام ساخت تصاویر خود با فعال کردن Docker BuildKit از فلگ sqash-- استفاده کنید
# Enable Docker BuildKit
export DOCKER_BUILDKIT=1

# Build and squash the image
docker build --tag myapp:latest --squash .


چه وقتی از له کردن استفاده کنیم
بهینه سازی اندازه تصویر: زمانی که نیاز به کاهش اندازه تصویر نهایی داکر خود دارید، از squashing استفاده کنید، به خصوص هنگام توزیع تصاویر در یک شبکه یا ذخیره آنها در یک رجیستری

ساده سازی لایه های تصویر: اگر داکرفایل شما حاوی دستورالعمل های اجرا یا کپی زیادی است که تعداد لایه ها و اندازه کلی تصویر را افزایش می دهد


بهترین رویکرد
له کردن انتخابی: در نظر بگیرید که کدام تصاویر بیشتر از له کردن سود می برند. ممکن است برخی از لایه‌ها برای اهداف ذخیره‌سازی، به‌ویژه در حین توسعه، بدون شکست باقی بمانند.

مراقب ذخیره سازی باشید: Squashing می تواند بر مکانیسم کش لایه Docker تأثیر بگذارد. له کردن مکرر ممکن است منجر به زمان ساخت طولانی‌تر شود، زیرا داکر نمی‌تواند لایه‌های میانی را به طور موثر کش کند.

پیامدهای امنیتی: بدانید که له کردن ممکن است تاریخچه یک تصویر را پنهان کند. اطمینان حاصل کنید که لایه نهایی له شده سهوا حاوی داده های حساسی نیست که در لایه های میانی دور ریخته می شوند.

دام‌های رایج
استفاده بیش از حد در طول توسعه: له کردن پس از هر ساخت در طول توسعه می تواند به دلیل از بین رفتن مزایای ذخیره سازی، زمان ساخت را به طور قابل توجهی کاهش دهد.

نادیده گرفتن وضعیت آزمایشی: به یاد داشته باشید که ویژگی squash آزمایشی است و ممکن است در نسخه‌ها یا پیکربندی‌های مختلف داکر به طور مداوم رفتار نکند

لینک وبسایت

#docker

@code_crafters
2
Forwarded from Amiria & Zeynab
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣10😁4
3-docker buildkit secret

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

داکر buildkit سکرت چیست
یک ویژگی سیستم ساخت داکر buildkit است. این به شما این امکان رو میده تا اطلاعات مخفی و سکرت (مانند رمزهای عبور، کلیدهای خصوصی یا نشانه های API) را به طور ایمن به فرآیند ساخت منتقل کنید. این سکرت‌ها در تصویر نهایی یا در لایه‌های میانی ذخیره نمی‌شوند و فرآیند ساخت شما را امن‌تر می‌کنند


چگونه از داکر buildkit سکرت استفاده کنیم
برای استفاده از داکر BuildKit سکرت، ابتدا مطمئن شوید که Docker BuildKit فعال است.می توانید این کار را با تنظیم متغیر محیطی DOCKER_BUILDKIT=1 انجام دهید. سپس، از فلگ secret-- در طول فرآیند ساخت برای ارائه رازها استفاده کنید
# Enable Docker BuildKit
export DOCKER_BUILDKIT=1

# Build with a secret
docker build --secret id=mysecret,src=/path/to/secret/file.txt -t myapp:latest .


چه وقتی از داکر buildkit سکرت استفاده کنیم
دسترسی به مخازن خصوصی Git: زمانی که ساخت شما نیاز به pull کردن وابستگی ها از مخازن خصوصی دارد(یک پکیج خصوصی توسعه داده‌اید و در اکانت خودتون گذاشته‌اید)

استفاده از کلیدهای خصوصی: زمانی که نیاز به استفاده از کلیدهای خصوصی برای دسترسی SSH یا رمزگشایی فایل ها در حین ساخت دارید

توکن های API: زمانی که فرآیند ساخت شما شامل دسترسی به API هایی است که نیاز به احراز هویت دارند


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

اسکوپ‌های سکرت: اسرار را به وضوح تعریف کرده و به مراحل ساخت خاصی که در آن مورد نیاز است، بسط دهید و خطر مواجهه را کاهش دهید

نسخه pinning : همیشه هنگام استفاده از ویژگی‌های BuildKit، نسخه نحو را در داکر خود پین کنید تا از سازگاری و پیش‌بینی‌پذیری اطمینان حاصل کنید.

دام‌های رایج:
کدگذاری بصورت سخت (hardcoding): از کدگذاری بصورتسخت یا استفاده از روش‌های منسوخ (مثلاً ARG برای انتقال سکرت) که ممکن است اطلاعات حساسی را در لایه‌های تصویر باقی بگذارند، خودداری کنید

در شرف پاکسازی: با بازرسی لایه‌های نهایی یا ایجاد سهوا لایه‌های ذخیره‌سازی با داده‌های مخفی، مطمئن شوید که هیچ باقی‌مانده مخفی در تصویر باقی نمانده است

توضیحات تکمیلی
ویژگی buildkit در نسخه‌های جدید داکر و داکرکامپوز بصورت پیش فرض فعال می باشد که با تکنیک‌های خاصی سرعت ایجاد تصاویر رو افزایش میده

در خصوص pinning قابلیتی که به شما این امکان رو میده تا از نسخه‌های خاصی از ابزارها و وابستگی‌ها استفاده کنند، که در یک فایل با نام build.yml نوشته میشه و در کنار داکرفایل قرار میگیرد برای مثال در پایتون و جنگو داکرفایل ما بصورت زیر می باشد
FROM python:3.9

RUN pip install --upgrade pip

RUN pip install django==4.1.5

COPY . /app

CMD python manage.py runserver 0.0.0.0:8000
و فایل build.yml ما بصورت زیر خواهد بود
build:
pins:
- name: python
version: "3.9"
- name: pip
version: "22.3.1"
- name: django
version: "4.1.5"
این فایل محدودیت استفاده از ابزار و نسخه خاص رو بر روی داکر ایجاد میکند، موجب افزایش امنیت و رعایت وابستگی‌ها میشه و ایمیج‌های تکرار شونده رو براتون بوجود میاره ، اما انعطاف شمارو در ساخت ایمیج پایین میاره

لینک وبسایت

#docker

@code_crafters
2👎1
4-اهرم dockerignore.
فایل .dockerignore نقش مهمی در بهینه‌سازی ساخت‌های Docker بازی می‌کند، زیرا به شما امکان می‌دهد الگوهایی را مشخص کنید که فایل‌ها و دایرکتوری‌ها را از متن ارسال شده به Daemon داکر حذف می‌کند. این مکانیسم می تواند به طور قابل توجهی روند ساخت را سرعت ببخشد، اندازه زمینه ساخت را کاهش دهد و با حذف فایل های حساس، امنیت را افزایش دهد

این dockerignore چیست
مانند gitignore.، فایل .dockerignore به داکر می‌گوید کدام فایل‌ها و دایرکتوری‌ها را هنگام ساختن یک تصویر نادیده بگیرد.این امر به ویژه مهم است زیرا هر فایلی که به عنوان بخشی از زمینه ساخت به Daemon داکر ارسال می شود، می تواند زمان ساخت و پیچیدگی غیر ضروری را به خصوص در پروژه های بزرگ افزایش دهد.

استفاده از dockerignore
یک فایل .dockerignore در ریشه پروژه خود، جایی که Dockerfile شما قرار دارد، ایجاد کنید. در این فایل، الگوهایی را برای فایل‌ها و دایرکتوری‌ها مشخص کنید تا از زمینه ساخت Docker حذف شوند.

نمونه ای از فایل .dockerignore
.git
.gitignore
Dockerfile*
*.md
node_modules
temp/


چه وقتی از dockerignore استفاده کنیم
مخازن بزرگ: برای پروژه هایی با حجم زیاد داده، به خصوص آنهایی که برای ساخت یا زمان اجرا مورد نیاز نیستند

اطلاعات حساس: برای حذف فایل‌های حاوی سکرت‌ها(env.) یا اطلاعات حساسی که نباید در زمینه ساخت Docker گنجانده شوند

دایرکتوری‌های وابستگی: برای زبان‌هایی که وابستگی‌ها را در فهرست‌های محلی دانلود می‌کنند (مانند venv در پایتون)، که اگر در حین ساخت، وابستگی‌ها را نصب می‌کنید، در زمینه ساخت مورد نیاز نیستند

بهترین رویکرد
مرتباً مرور کنید: به‌طور دوره‌ای فایل .dockerignore خود را بررسی کنید تا مطمئن شوید که با ساختار و الزامات پروژه شما به‌روز است

الگوهای واضح: از الگوهای صریح استفاده کنید تا فایل ها و دایرکتوری های مورد نظر را دقیقاً مطابقت دهند و از حذف ناخواسته اجتناب کنید

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

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

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

لینک وبسایت

#docker

@code_crafters
Duck Typing in Python
از انجایی که پایتون داینامیک تایپ هست پس مفهوم داک تاپینیگ هم براش معنا پیدا میکنه. سیستم داک تایپینگ بر اساس اینترفیس و رفتار های ابجکت ها هست. خیلی از کلاس ها و ابزار های از موجود در پایتون از این سیستم پشتیبانی میکنند و این باعث انعطاف زیاد در کد میشه که در ادامه توضیح میدیم.


تعاریف زیادی در خصوص داک تایپینگ وجود داره، اما تعریف اصلی بر اساس این جمله معروف هست : "اگر مثل داک ( به فارسی : اردک) راه میره و مثل داک، کواک ( صدای اردک 😀) میکنه پس قطعا یک اردک است."
اگر بخواهیم این رو به برنامه نویسی تعمیم دهیم، شما میتونید چند ابجکت داشته باشید که صدای اردک در بیارن و مثل اردک راه برن و نیازی به چک کردن تایپشون که ایا اردک هستند، نباشه. داک تایپینگ یک تایپ سیستم هست که در اون، یک ابجکت میتونه سازگار با یک تایپ معین در نظر گرفته بشه اگر تمام متد ها و اتریبیوت های مورد نیاز اون تایپ رو داشته باشه. این تایپ سیستم در واقع از استفاده کردن چند ابجکت که هر کدوم از کلاس متفاوت و مستقلی هستند، در یک مفهوم خاص پشتیبانی میکنه. این امر تا زمانی ممکن هست که این کلاس ها به یک اینترفیس مشترک پایبند باشند. اگر کامل متوجه نشدید نگران نباشید با مثالی که میزنیم کاملا متوجه موضوع میشید :).
در قطعه کد زیر چند پرنده داریم که توانایی پرواز و شنا کردن رو دارند.
--------------
birds_v1.py
--------------
class Duck:
def swim(self):
print("The duck is swimming")

def fly(self):
print("The duck is flying")

class Swan:
def swim(self):
print("The swan is swimming")

def fly(self):
print("The swan is flying")

class Albatross:
def swim(self):
print("The albatross is swimming")

def fly(self):
print("The albatross is flying")


در این مثال سه پرنده ما میتونند هم پروار و هم شنا کنند اگرچه که هر کدوم یک کلاس جدا و مستقل از هم دیگه هستند. به دلیل اینکه هر سه کلاس ما اینترفیس مشترکی رو اراعه میدهند میتوانیم بدین صورت در کد از انها استفاده کنیم.
>>> from birds_v1 import Duck, Swan, Albatross

>>> birds = [Duck(), Swan(), Albatross()]

>>> for bird in birds:
... bird.fly()
... bird.swim()
...
The duck is flying
The duck is swimming
The swan is flying
The swan is swimming
The albatross is flying
The albatross is swimming

پایتون اهمیتی نمیده که وریبل پرنده )bird( دقیقا چه ابجکتی رو درون خودش داره و فقط متدی که بهش گفته شده رو اجرا میکنه.
اگر ابجکت ما متد مورد نظر رو داشته باشه، کد بدون مشکل اجرا میشه و این همون بحث انطعاف پذیری داک تایپینگ هست.

این بحث داک تایپینگ تو ابزار های built-in پایتون هم پیاده سازی و پشتیبانی میشه
که تو عکس1 در بخش کامنت ها میتونید ببینید.

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

#duck_typing
#type_system
#reall_python

@code_crafters
👍51👌1
حالا اگر بخواید تو کلاس کاستوم خودتون داک تایپینگ رو پیاده سازی کنید دو روش وجود داره
1. Regular methods
که دقیقا همون مثال پرنده ای که زدیم در بالا از همین روش استفاده شده ولی اگر بخوایم یک مثال کاربردی تر بزنیم میتونیم فرض کنیم میخوایم چند کلاس بسازیم واسه خواندن انواع فایل های csv, json, txt خب میایم سه تا کلاس میسازیم و واسه هر کدوم یک متد با نام مشابه برای خواندن فایل و یک اتریبیوت با نام مشابه نیز میسازیم، اینطوری یک اینترفیس یکسان و مشترک برای کلاس های مختلف با ساز و کار مختلف داریم. به راحتی میتونیم چند ابجکت مختلف از این کلاس ها بسازیم و با یک حلقه فور میتونیم از متد خواندن استفاده کنیم.

2. Special methods
اسپشیال متد ها یا همون داندر متد ها، با دوتا اندراسکور در اول و اخر نامشون مشخص میشوند و معنای خاصی برای پایتون دارند.
بیاید فرض کنیم میخوایم یک صف )queue( درست کنیم
و میخوایم که صف ما iterable باشه و همچنین بتونیم از
Len, reversed , in استفاده کنیم
خب کد ما به به این شکل خواهد شد :
from collections import deque

class Queue:
def __init__(self):
self._elements = deque()

def enqueue(self, element):
self._elements.append(element)

def dequeue(self):
return self._elements.popleft()

def __iter__(self):
return iter(self._elements)

def __len__(self):
return len(self._elements)

def __reversed__(self):
return reversed(self._elements)

def __contains__(self, element):
return element in self._elements

خب تو این کلاس ما دوتا عملیات کلاسیک اضافه کردن به صف و حذف کردن از صف رو داریم و همچنین چند داندر متد برای کلاس پیاده سازی کردیم تا عملیات های مورد نیاز مارو پشتیبانی کنه.
>>> from queues import Queue

>>> queue = Queue()
>>> queue.enqueue(1)
>>> queue.enqueue(2)
>>> queue.enqueue(3)

>>> [item for item in queue]
[1, 2, 3]

>>> len(queue)
3
>>> list(reversed(queue))
[3, 2, 1]

>>> 2 in queue
True
>>> 6 in queue
False
میبینید که تمام عملیات های مورد نیاز مارو به خوبی انجام میده.
منبع
#duck_typing
#type_system

#reall_python

@code_crafters
👍4💋21
دوستان عزیز داریم یه گروه جمع میکنیم که صفحات و مطالب سایت reall python رو ترجمه کنیم به زبان فارسی


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


یک اینکه این موضوع منجر میشه که با پایتون بیشتر آشنا بشید
ماژول‌ها و موارد بیشتری از پایتون رو بشناسید
و اینکه بعنوان یک کار در جامعه فارسی زبان ازتون باقی خواهد مونده
👍9
5-بررسی سلامت داکرفایل
اجرای چک های سلامت مستقیماً در داکرفایل روشی قدرتمند برای نظارت خودکار بر وضعیت عملیاتی کانتینرهای شما است. با تعریف بررسی های بهداشتی، داکر می تواند تصمیمات آگاهانه ای در مورد سلامت کانتینرها بگیرد و اقدامات مناسب را انجام دهد، مانند راه اندازی مجدد کانتینر معیوب یا جلوگیری از هدایت ترافیک به آن تا زمانی که سالم شود


بررسی سلامت داکرفایل چیست
بررسی سلامت داکر دستوری است که در داکرفایل مشخص شده است که داکر به صورت دوره ای برای بررسی سلامت یک کانتینر اجرا می کند. این دستور باید نشان دهد که آیا کانتینر به درستی کار می کند یا خیر، داکر وضعیت خروج از فرمان بررسی سلامت را برای تعیین وضعیت سلامت کانتینر تفسیر می کند: وضعیت خروج 0 به معنای سالم و غیر صفر به معنای ناسالم است

چگونه از بررسی سلامت داکرفایل استفاده کنیم
بررسی های سلامت در داکرفایل با استفاده از دستورالعمل HEALTHCHECK تعریف شده است. می‌توانید دستور اجرا، فاصله بین بررسی‌ها، زمان پایان هر چک، تعداد دفعات تکرار قبل از در نظر گرفتن سرویس ناسالم، و دوره شروع برای تثبیت کانتینر قبل از شروع بررسی‌های سلامت را مشخص کنید


نمونه داکرفایل با بررسی سلامت
این مثال یک بررسی سلامتی را روی ظرف Nginx تنظیم می‌کند و از curl برای درخواست صفحه اصلی هر 30 ثانیه استفاده می‌کند. اگر دستور سه بار پشت سر هم ناموفق باشد (صفحه به درستی برگردانده نشده است)، داکر ظرف را به عنوان ناسالم علامت گذاری می کند
Dockerfile
FROM nginx:latest


COPY nginx.conf /etc/nginx/nginx.conf

# Health check script
COPY health-check.sh /usr/share/nginx/html/health-check.sh

# Make the script executable
RUN chmod +x /usr/share/nginx/html/health-check.sh


EXPOSE 80

# Health check definition
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD /usr/share/nginx/html/health-check.sh

health-check.sh
#!/bin/bash


if curl -sSf https://localhost:80 > /dev/null; then
exit 0
else
exit 1
fi
چه وقتی از بررسی سلامت کانتینر استفاده کنیم
در دسترس بودن سرویس: زمانی که باید اطمینان حاصل کنید که یک سرویس در یک کانتینر در دسترس است و قبل از ارسال ترافیک به آن پاسخگو است

آمادگی وابستگی: در کاربردهای چند کانتینری، که در آن کانتینرهای خاصی به عملکرد کامل سایر کانتینرها بستگی دارند

سیستم های خود درمانی: برای ایجاد یک سیستم انعطاف پذیرتر که می تواند به طور خودکار ظروف ناسالم را راه اندازی مجدد کند

بهترین رویکرد
به حداقل رساندن تأثیر عملکرد: اطمینان حاصل کنید که دستور بررسی سلامت سبک است و تأثیر قابل توجهی بر عملکرد ظرف ندارد

دوره‌های شروع دقیق: یک دوره شروع واقعی را تنظیم کنید تا قبل از شروع شکست در بررسی‌های سلامت، زمان کافی برای شروع اولیه به برنامه خود بدهید

از نقاط پایانی سلامت خاص استفاده کنید: ترجیح می‌دهید از نقاط پایانی خاص (به عنوان مثال، /healthz) استفاده کنید که سلامت اجزای مختلف برنامه را بررسی می‌کند، نه فقط صفحه اصلی یا یک بررسی اولیه TCP

دام‌های رایج
دستورات پیچیده: از دستورات بیش از حد پیچیده بررسی سلامت که ممکن است غیرقابل اعتماد باشند یا عوارض جانبی غیرمنتظره ایجاد کنند، خودداری کنید

نادیده گرفتن وابستگی های خارجی: اگر سلامت کانتینر شما به خدمات خارجی بستگی دارد، مطمئن شوید که بررسی سلامت شما در دسترس بودن آنها را در نظر می گیرد و از مثبت کاذب جلوگیری می کند


یک نمونه برای داکرفایل جنگو
#----
# Use an official Python runtime as a parent image
FROM python:3.8

# Set environment variables
ENV PYTHONUNBUFFERED 1

# Set working directory
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed dependencies specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Expose port 8000 to the outside world
EXPOSE 8000

# Define the health check command
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl --silent --fail localhost:8000/health-check || exit 1

# Run the Django application
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

#---


یک نمونه در داکرکامپوز
#---
version: '3'

services:
web:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
restart: on-failure
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:8000/health-check || exit 1"]
interval: 5s
timeout: 3s
retries: 3
#---


لینک وبسایت

#docker

@code_crafters
6-قالب بندی خروجی داکر CLI
رابط خط فرمان داکر (CLI) یک ویژگی قدرتمند برای سفارشی کردن خروجی دستورات با استفاده از گزینه formating-- فراهم می کند.این گزینه از زبان الگوی Go استفاده می کند تا به کاربران اجازه دهد دقیقاً نحوه ساختار خروجی را مشخص کنند و تجزیه یا ادغام با ابزارهای دیگر را آسان تر می کند

قالب بندی خروجی داکر CLI چیست
قالب‌بندی خروجی داکر CLI به شما امکان می‌دهد تا خروجی دستورات Docker را مطابق با نیازهای خود تنظیم کنید، با استفاده از زبان قالب Go برای تعیین فرمت خروجی. این ویژگی برای استخراج قطعات خاصی از اطلاعات از خروجی‌های فرمان پرمخاطب داکر، به‌ویژه هنگام خودکارسازی وظایف یا ادغام با خطوط لوله CI/CD بسیار ارزشمند است

چگونه از قالب بندی خروجی داکر CLI استفاده کنیم
فاگ format-- را می توان با دستورات مختلف داکر CLI برای سفارشی کردن خروجی آنها استفاده کرد.در اینجا مثالی از نحوه فهرست کردن همه شناسه‌های کانتینر با استفاده از قالب سفارشی آورده شده است:
docker ps --format '{{.ID}}'

این دستور شناسه‌های همه کانتینرهای در حال اجرا را، یکی در هر خط، بدون هیچ گونه اطلاعات یا هدر اضافی فهرست می‌کند

مثال پیشرفته: فهرست کردن تصاویر با ویژگی های خاص
در اینجا نحوه فهرست کردن تصاویر، نشان دادن تنها مخزن، برچسب و اندازه آنها در قالب جدول آمده است:
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

این دستور یک جدول با فرمت منظم از تصاویر Docker شما ایجاد می کند که فقط نام مخزن، برچسب و اندازه تصویر را نشان می دهد


چه وقتی از قالب بندی خروجی داکر CLI استفاده کنیم
اسکریپت و اتوماسیون: زمانی که نیاز به تجزیه خروجی های دستور Docker در اسکریپت ها یا ابزارهای اتوماسیون دارید

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

خروجی ساد: زمانی که می خواهید خروجی را برای وضوح ساده یا تمرکز بر جزئیات خاص ساده کنید

بهترین رویکرد
الگوسازی Go را درک کنید: برای استفاده مؤثر از گزینه‌های قالب‌بندی، با نحو قالب‌بندی Go آشنا شوید

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

ترکیب با سایر ابزارهای یونیکس: برای پردازش قدرتمندتر، خروجی داکر فرمت شده را با ابزارهای یونیکس مانند grep، awk یا jq برای خروجی های JSON ترکیب کنید

دام‌های رایج
پیچیدگی بیش از حد: از ایجاد الگوهای بیش از حد پیچیده که خواندن و نگهداری آنها سخت است خودداری کنید. آن را تا حد امکان برای کار در دست ساده نگه دارید

قالب بندی ناسازگار: هنگام استفاده از فرمت های سفارشی در میان اسکریپت ها یا ابزارهای مختلف، برای جلوگیری از سردرگمی، سازگاری را حفظ کنید

لینک وبسایت

#docker

@code_crafters
Property and Descriptor-Based Attributes

Property
پایتون به شما امکان می‌دهد رفتاری شبیه به تابع را بر روی اتریبیوت های موجود در کلاس اضافه کنید و آن‌ها را به اتریبیوت های مدیریت‌شده (managed attribute) تبدیل کنید. این نوع ویژگی از بروز تغییرات اساسی در APIیعنی همان اینترفیس عمومی های شما جلوگیری می‌کند.

به عبارت دیگر، با اتریبیوت های مدیریت شده، شما می‌توانید همزمان از رفتار شبیه به تابع و دسترسی شبیه به اتریبیوت بهره‌مند شوید. نیازی به تغییر APIهای خود با جایگزین کردن اتریبیوت ها با متدها نیست، که ممکن است کد کاربران‌تان را دچار مشکل کند.
برای ایجاد یک اتریبیوت مدیریت شده با رفتار شبیه به تابع در پایتون، شما می‌توانید از یک property یا یک descriptor استفاده کنید، بسته به نیازهای خاص خود.
به عنوان مثال، به کلاس Circle خود برگردید و فرض کنید که نیاز دارید شعاع را تایید کنید تا اطمینان حاصل شود که فقط اعداد مثبت ذخیره می‌شوند. چگونه این کار را بدون تغییر اینترفیس کلاس انجام می‌دهید؟ سریع‌ترین روش برای حل این مشکل استفاده از یک property و پیاده‌سازی منطق ولیدیشن( اعتبارسنجی) در متد setter است.


import math

class Circle:
def __init__(self, radius):
self.radius = radius

@property
def radius(self):
return self._radius

@radius.setter
def radius(self, value):
if not isinstance(value, int | float) or value <= 0:
raise ValueError("positive number expected")
self._radius = value

def calculate_area(self):
return round(math.pi * self._radius**2, 2)

برای تبدیل اتریبیوت radius به یک پراپرتی، از دکوریتور property استفاده میکنیم یک متد getter بنویسیم. این متد هنگامی اجرا میشه که میخواهیم مقدار اتریبیوت radius رو مشاهده کنیم، پس قطعا باید مقدار شعاع رو به ما ریترن(return) کنه.
برای اینکه یک متد setter برای پراپرتی شعاع مون بنویسم از دکوریتور @ attr_name.setter استفاده میکنیم.
حال داخل متد setter میایم و منطق اعتبارسنجی که نیاز داشتیم رو پیاده میکنیم و اگر عدد طبق چیزی که انتظار داشتیم نبود به ما خطا میدهد در غیر این صورت در یک اتریبیوت non-public به نام _radius ذخیره میکنیم. حالا اتریبیوت radius ما تبدیل به یک پراپرتی شده و هرموقع که نیاز به مشاهده مقدار یا تغییر مقدار ان بودیم خود پایتون اتومات، ابتدا با توجه به عملیات یکی از متد های getter یا setter رو کال میکنه.
نحوه کارکرد اون به شکل زیر هست.
>>> from circle import Circle

>>> circle_1 = Circle(100)
>>> circle_1.radius
100
>>> circle_1.radius = 500
>>> circle_1.radius = 0
Traceback (most recent call last):
...
ValueError: positive number expected

>>> circle_2 = Circle(-100)
Traceback (most recent call last):
...
ValueError: positive number expected

>>> circle_3 = Circle("300")
Traceback (most recent call last):
...
ValueError: positive number expected


میبینید که با اتریبیوت radius دارید به طور عادی رفتار میکنید اما در پشت قضیه، یک رفتار متد مانند دارد و اگر مقدار نامعتبر دهید خطا میدهد.
منبع
#Property #Python
@Code_Crafters
2🔥1👏1