uz
Feedback
CodeCrafters

CodeCrafters

Kanalga Telegram’da o‘tish
710
Obunachilar
Ma'lumot yo'q24 soatlar
Ma'lumot yo'q7 kunlar
Ma'lumot yo'q30 kunlar
Postlar arxiv
2-الگوی مش سرویس تصور کنید تو یه شهر شلوغ هستید که پر از ماشین‌ها (میکروسرویس‌ها) است که می‌خوان با هم ارتباط برقرار کنن. اگه هر ماشین بخواد خودش مسیرش رو پیدا کنه، ترافیک قفل می‌شه، تصادف پیش میاد و هیچ‌کس به موقع به مقصد نمی‌رسه. حالا مش سرویس مثل یه سیستم هوشمند مدیریت ترافیک عمل می‌کنه. این سیستم یه شبکه‌ی اختصاصی از «پروکسی‌ها» (مثل چراغ‌های راهنمایی یا پلیس‌های ترافیک) داره که تمام ارتباطات بین ماشین‌ها رو هدایت، کنترل و بهینه می‌کنه. تصویر سوم این لایه‌ی واسطه (که معمولاً با ابزارهایی مثل Istio یا Linkerd پیاده‌سازی می‌شه) مسئولیت کارهای زیر رو به عهده می‌گیره: هدایت ترافیک: تصمیم می‌گیره درخواست‌ها از کدوم مسیر برن. مثلاً اگه یه سرویس شلوغ باشه، درخواست‌ها رو به یه نمونه‌ی دیگه از همون سرویس می‌فرسته. تعادل بار (Load Balancing): بار کاری رو بین نسخه‌های مختلف یه سرویس تقسیم می‌کنه تا هیچ سرویسی بیش از حد تحت فشار نباشه. امنیت: ارتباط‌ها رو رمزنگاری می‌کنه (مثلاً با TLS) و مطمئن می‌شه فقط سرویس‌های مجاز بتونن با هم حرف بزنن. نظارت و رصد: اطلاعاتی مثل زمان پاسخ‌گویی، تعداد درخواست‌ها یا خطاها رو جمع‌آوری می‌کنه تا تیم توسعه بتونه عملکرد سیستم رو تحلیل کنه. مدیریت خطا: اگه یه سرویس از کار بیفته، مش سرویس می‌تونه درخواست‌ها رو به‌طور خودکار به یه سرویس سالم هدایت کنه یا یه پیام خطای مناسب برگردونه. مثال واقعی: فرض کنید تو یه اپلیکیشن خرید آنلاین، سرویس «پرداخت» و سرویس «سبد خرید» باید با هم کار کنن. بدون مش سرویس، هر کدوم از این سرویس‌ها باید خودشون منطق ارتباطی، مثل مدیریت خطاها یا رمزنگاری، رو پیاده‌سازی کنن. اما با مش سرویس، یه لایه‌ی پروکسی (مثلاً Envoy تو Istio) بین این دو سرویس قرار می‌گیره و تمام این کارها رو به‌صورت خودکار انجام می‌ده. اینجوری تیم توسعه می‌تونه روی منطق اصلی سرویس‌ها تمرکز کنه و نگران پیچیدگی‌های ارتباطی نباشه. مزیت بزرگ: مش سرویس کد سرویس‌ها رو ساده‌تر می‌کنه، چون منطق شبکه‌ای (مثل retry، timeout یا رمزنگاری) از سرویس‌ها جدا می‌شه و به لایه‌ی مش منتقل می‌شه. اما یه نکته هم داره: راه‌اندازی و مدیریت مش سرویس ممکنه خودش پیچیدگی‌هایی به سیستم اضافه کنه، مخصوصاً تو محیط‌های کوچک‌تر. #microservice #design_patterns @code_crafters

میکروسرویس‌ها یه روش جدید و مدرن برای طراحی نرم‌افزاره که برنامه‌های پیچیده رو به تکه‌های کوچک‌تر و مستقل تقسیم می‌کنه. این تکه‌ها (یا همون سرویس‌ها) هر کدوم یه کار خاص انجام می‌دن و می‌تونن جداگونه توسعه داده بشن، مستقر بشن و بزرگ‌تر بشن. این روش باعث می‌شه کار توسعه سریع‌تر، انعطاف‌پذیرتر و مقاوم‌تر باشه. ولی برای اینکه بتونیم میکروسرویس‌ها رو درست پیاده‌سازی کنیم، باید چالش‌های سیستم‌های توزیع‌شده رو خوب بشناسیم. دیزاین پترن ها راه‌حل‌های آماده و امتحان‌شده‌ای هستن که بهمون کمک می‌کنن این چالش‌ها رو راحت‌تر حل کنیم. تو این مجموعه قراره تو ۵ بخش، ۱۰ دیزاین پترن مهم برای ساختن میکروسرویس قوی و مقیاس‌پذیر رو توضیح بدم. تو بخش اول، می‌ریم سراغ اینکه میکروسرویس‌ها چی هستن؟ چرا دیزاین پترن ها مهم هستن؟، و دو تا الگوی خاص به اسم Service Service Registry Pattern(رجیستری سرویس) و Service Mesh Pattern(مش سرویس) رو بررسی می‌کنیم. میکروسرویس‌ها چی هستن؟
میکروسرویس‌ها یه سبک طراحی نرم‌افزارن که به جای یه برنامه بزرگ و یکپارچه، برنامه رو به یه سری سرویس‌های کوچیک و مستقل تقسیم می‌کنن. هر سرویس روی یه کار مشخص تمرکز داره، مثلاً مدیریت سفارش‌ها یا پردازش پرداخت. این سرویس‌ها می‌تونن جداگونه نوشته بشن، اجرا بشن و حتی با زبان‌ها و ابزارهای مختلف ساخته بشن. تصویر اول این سرویس‌ها با هم از طریق API باهم ارتباط برقرار میکنند و معمولاً از روش‌های ساده‌ای مثل HTTP یا از مسیچ بروکر هایی (مثل RabbitMQ) استفاده می‌کنن. این روش باعث می‌شه: - سیستم انعطاف‌پذیرتر باشه، چون هر سرویس جداگونه قابل‌تغییره. - سریع‌تر بتونی تغییرات رو اعمال کنی. - اگه یه سرویس خراب بشه، کل سیستم از کار نمی‌افته (مثل وقتی یه قطعه پازل خراب بشه، کل تصویر خراب نمی‌شه).
چرا ادیزاین پترن ها مهم‌ان؟
دیزاین پترن ها مثل یه جعبه‌ابزار برای توسعه‌دهنده‌ها هستن. دلایل اهمیت‌شون: - استفاده دوباره و مقیاس‌پذیری: این الگوها مشکلات تکراری رو حل کردن، پس می‌تونی از راه‌حل‌های آماده استفاده کنی و کدهات رو طوری بنویسی که بعداً راحت بتونی سیستمت رو بزرگ‌تر کنی. مثلاً میکروسرویس‌ها بهت کمک می‌کنن با اضافه کردن سرویس‌های جدید، سیستم رو مقیاس‌پذیر کنی. - نگهداری و انعطاف: الگوها یه ساختار استاندارد به کدها می‌دن که باعث می‌شه کدت تمیزتر و قابل‌فهم‌تر باشه. اینجوری اگه بخوای چیزی رو تغییر بدی، کل سیستم به هم نمی‌ریزه. مثلاً الگوهایی مثل Observer یا Strategy بهت کمک می‌کنن کدت رو مدولار و قابل‌تغییر نگه داری. - بهینه‌سازی و زبان مشترک: بعضی الگوها کمک می‌کنن سیستمت سریع‌تر کار کنه، حافظه کمتری مصرف کنه یا امن‌تر باشه. ضمناً این الگوها یه زبان مشترک بین توسعه‌دهنده‌ها ایجاد می‌کنن که بتونن راحت‌تر با هم درباره سیستم‌های پیچیده حرف بزنن.
دیزاین پترن میکروسرویس‌ها 1- رجیستری سرویس برای درک بهتر الگوی رجیستری سرویس، فرض کنید یه شهر بزرگ دارید که پر از مغازه‌ها و خدمات مختلفه. هر مغازه (که اینجا نماینده یه میکروسرویسه) باید به مشتری‌ها (یا سرویس‌های دیگه) بگه کجاست و چی ارائه می‌ده. حالا اگه هیچ سیستم مرکزی وجود نداشته باشه، هر مغازه باید خودش بره دنبال مغازه‌های دیگه، که این کار خیلی زمان‌بر و پیچیده می‌شه. اینجاست که رجیستری سرویس مثل یه دفتر اطلاعات شهری عمل می‌کنه. هر مغازه وقتی شروع به کار می‌کنه، می‌ره و خودش رو تو این دفتر ثبت می‌کنه. مثلاً می‌گه: «من مغازه قهوه‌فروشی‌ام، تو این آدرس کار می‌کنم و این خدمات رو ارائه می‌دم.» بعد، اگه یه مغازه دیگه (مثلاً یه شیرینی‌فروشی) بخواد قهوه سفارش بده، به جای گشتن تو کل شهر، مستقیم می‌ره به این دفتر اطلاعات و آدرس قهوه‌فروشی رو پیدا می‌کنه. تصویر دوم اجزای اصلی این الگو: - ثبت‌نام: هر سرویس وقتی شروع به کار می‌کنه، می‌گه "من فلان سرویسم، این آدرس شبکه‌م، اینم اطلاعاتم." اینجوری رجیستری همیشه یه لیست به‌روز از سرویس‌ها داره. - پیدا کردن سرویس: وقتی یه سرویس می‌خواد با یکی دیگه حرف بزنه، از رجیستری می‌پرسه "فلان سرویس کجاست؟" و رجیستری آدرسش رو می‌ده. - چک کردن سلامت: رجیستری مرتب چک می‌کنه که سرویس‌ها سالم و فعالن یا نه. اگه یه سرویس از کار افتاده باشه، از لیست خطش می‌زنه. - به‌روزرسانی پویا: اگه یه سرویس خاموش بشه، روشن بشه یا جاش عوض بشه، اطلاعاتش تو رجیستری به‌روز می‌شه تا همیشه اطلاعات درست باشه. مثال: Netflix Eureka Eureka یه ابزار کشف سرویس ساخته نتفلیکسه. سرورش طوری طراحی شده که همیشه در دسترس باشه و چند تا سرور بتونن اطلاعات سرویس‌های ثبت‌شده رو با هم به اشتراک بذارن.

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

تصویر اول در کامنت‌ها
اگر سرمایه گذاری توجیه دارد در حالت حفظ قرار می‌گیریم، این سناریو زمانی رخ می‌دهد که یکی از محصولات جاری را بازنگری کنیم در غیر این صورت باید رو سه حالت دیگر تصمیم گرفت اگر محصول کمینه ویژگی‌های قابل انتشار را داراست حالت تحویل، در غیر این صورت مسیر اشتباه پیش رفته‌ایم، و اگر فکر کنیم مسیر دیگری ارزش اکتشاف داشته باشد حالت تغییر مسیر، اگر سرمایه گذاری توجیه ندارد و از موقعیت خود نیز رضایت نداریم حالت توقف
هیچگاه اجازه ندهید که تصمیمات حسابداری شما را به رفتار نابخردانه بکشاند 
#scrum @code_crafters

این رویکرد زمانی مناسب است که با عدم قطعیت بالا در سازمان روبرو باشیم اغلب سازمان‌ها برنامه استراتژیک سالانه خود را در سه ماه سوم سال برگذار می‌کنند و یکی از این نتایج فهرست محصولاتی است که می‌خواهند روی آن کار کنند. این محصولات باهم در بک‌لاگ سبد محصول وارد شده و موجب اختلال در برنامه ریزی سبد محصول می‌شوند رویکرد استراتژیک خوب است اما نباید موجب اختلال در تصمیم گیری بک‌لاگ سبد محصول شود که تصمیمی برگشت ناپذیر است. این تصمیم‌ها زمانی گرفته می‌شود که با عدم قطعیت بالا روبرو هستیم و موجب نقض اصل باز نگه داشتن انتخاب‌های تا لحظه آخر هم می‌شود. از طرفی انتخاب همه اقلام بک‌لاگ سبد محصول اصل انتخاب اقتصادی اندازه بسته‌ها را نیز لغو می‌کند. این پردازش بسته بزرگ کار بیهوده و کم هزینه است. در سبد کوچکتر هر ترکیب با اندکی دقت کاملا اقتصادی و به صرفه است بهترین کار بجای ورود ناگهانی، بلکه ورود اندک و در بازه‌های مشخص کوتاه مدت است که منجر به کاهش هزینه و حجم کار بازنگری هم می‌شود همچنین بهتر است روی محصولات کوچکتر تمرکز کنیم تا جریان ورودی و خروجی توازن داشته باشد. در حجم بالا می‌توان از فیلترها و معیارهای پذیرش، سنجشی و اقتصادی سختگیرانه‌تری بهره ببریم که جریان ورودی را کنترل کند و موجب آزاد شدن محصول بعدی از بک‌لاگ سبد محصول با آهنگ منظمی گردد ۳-استقبال از فرصت نو ظهور در برنامه ریزی سبد فرصت طلب باشید. فرصت نوظهور را بپذیرید. فرصتی که قبلا ناشناخته بوده یا احتمال وقوع آن به قدری کم بوده که تا به امروز ارزش سرمایه‌گذاری نداشته است. اقدام دیر در قبال فرصت‌ها موجب می‌شود بخش بزرگ ارزش اقتصادی را از دست بدهید. شما نیاز دارید بک برنامه منظم و پیوسته همراه فیلتر اقتصادی موثر داشته باشید و در کنار آن از انتشارهای کوچک و سقف کار در جریان نیز بهره ببرید ۴-برنامه ریزی برای انتشارهای کوچک و زود به زود انتشارات کوچکتر توجیه اقتصادی بهتری دارند و همواره موجب افزایش سود چرخه عمر محصول می‌شود. علاوه بر این از ایجاد «اثر کاروانی» نیز جلوگیری می‌کند، تصور کنید یک اسکانیا در مسیر وجود دارد و موجب شده که ماشین‌های کوچکتر وشت سر او صف طولانی تشکیل دهند این همان اثر کاروانی است که با ورود محصول بزرگ ایجاد می‌شود و دلیل آن استفاده از تمام ظرفیت جاده و مسیر است. محصولات بزرگ منابع زیاد و طولانی نیاز دارند و موجب صف تاخیر می‌شود که خود هزینه بردار است. راه جلوگیری از آن اعمال سیاست سازمانی است بزای مثال هیچ محصولی با حجم کاری بیش از نه ماه پذیرفته نمیشود مگر راه حلی برای شکستن آن در انتشارات کوچک‌تر پیدا شود. همچنین تصور عدم وجود انتشار دوم موجب می‌شود که جانب احتیاط را گرفته و ویژگی‌هایی اضافه کنیم که موجب بزرگ شدن محصول می‌شود استراتژی جریان خروجی این استراتژی به سازمان‌ها کمک می‌کند تا تصمیم بگیرند چه زمانی یک محصول را از سبد محصول خارج کنند، سه استراتژی در این بخش
۱-توجه به کارهای ناتمام به جای افراد بیکار
۲-تعیین سقف برای کار در جریان
۳-منتظر ماندن برای تشکیل یک تیم کاما
استراتژی اول بجای افراد بیکار به کارهای ناتمام توجه کنید. این اصل بیان می‌کند اتلاف منابع و خسارت ناشی از کارهای ناتمام بیشتر از بیکاری افراد به مراتب بیشتر است. شیوه مدیریت سبد محصول در اغلب سازمان‌ها با این اصل در تناقض است. شیوه رایج اما اشتباه شروع توسعه محصول:
۱-محصول ردیف اول بک‌لاگ را بردارید و افرادی را برای انجام آن تعیین کنید
۲-آیا همه وقتشان پر شده است، اگر خیر گام اول را تکرار کنید
این رویکرد همه افراد را مشغول نگه می‌دارد. نتیجه دیگر آن خطاپذیری و کند شدن کاری است که روی هر یک از محصولات انجام می‌شود. رویکرد بهتر انتخاب و شروع کار روی محصولی است که جریان کار مناسبی دارد و جریان کار دیگر محصولات جاری را مختل نمی‌کند، که ارتباط تنگاتنگی با استراتژی دوم دارد استراتژی دوم هرگز نباید محصولی را از سبد برداشت که فراتر از توان ماست (مدیر باهوش)، این رفتار منجر می‌شود ظرفیت اختصاص داده شده به هر محصول کاهش یابدکه منجر در تاخیر و کاهش کیفیت در تمامی محصولات می‌شود. تعیین سقف مناسب کار در جریان چگونه است؟ قبلا گفتیم تیم‌ها واحد اندازه گیری هستند و باید از آن‌ها استفاده نمود (اطلاع از تعداد تیم‌های اسکرام و توانایی آنها به ما کمک می‌کند تا تعداد و نوع فعالیت‌های که می‌توان همزمان انجام داد را تعیین کنیم) استراتژی سوم قبل از شروع کار بر روی یک محصول منتظر بمانید تا تیم اسکرام کامل تشکیل شود (تیم ناقص، تیمی است که تخصص کافی برای تکمیل ویژگی‌ها را ندارد) اکثر سازمان‌ها به اشتباه فقط دنبال پر کردن تایم و مشغول نگه داشتن تیم هستند و این منجر می‌شود که اجازه ورود محصول دیگری را بدهند که منجر به کند شدن و اتلاف میشود #scrum @code_crafters

محاسبه هزینه تاخیر در مرتب سازی محصولات در سبد باید توجه داشت که تمامی محصولات باهم شروع نمی‌شوند و تاخیر در شروع به معنای تاخیر در تحویل است و این یعنی صرف هزینه کردن که مبلغ آن قابل محاسبه است. هزینه تاخیر موجب تصمیم گیری آگاهانه می‌شود و با این وجود سازمان‌ها عاجز از پاسخ دادن به این سوال هستند که اگر یک محصول یکماه تاخیر داشته باشد چقدر هزینه بردار است؟ اکثر سازمانها در این شرایط کار بر روی محصول با بازدهی بیشتر را شروع میکنند که تفکری خوب اما اشتباه است، با یک مثال پیش برویم دو محصول داریم که اولی هزینه بازگشتی بیشتری نسبت به دومی دارد، در این حالت میگوییم که خب ابتدا توسعه اولی را آغاز کنیم. اما اگر هزینه تاخیر اولی ۵ هزار واحد و دومی ۷۵ هزار واحد باشد آنگاه متوجه میشوید که محاسبه هزینه تاخیر تاثیر بسیار زیادی در رویکرد سازمان و ترتیب اقلام خواهد داشت. هزینه تاخیر نشانگر این است که زمان بشدت روی متغیرهای ما تاثیر گذار است. در مثال ما متغیرهای تحت تاثیر زمان عبارت‌اند از: ۱- زمان شروع و پایان توسعه ۲- میزان منابع در دسترس در زمان توسعه ۳- هزینه منابع ۳- مبلغی که افراد حاضر به پرداخت آن برای محصول هستند ۴- ریسک‌های موجود ۵- احتمال وقوع این ریسک‌ها و میزان تاثیر آن‌ها بر هزینه تاخیر و تسریع در شروع توسعه و مقادیر بالا بر سود محصول تاثیرگذار است بنابراین هزینه تاخیر تنها عامل تعیین کننده اولویت دهی اقلام سید نیست و باید زمان را که تاثیری بر مقادیر هزینه، سود، دانش و ریسک را دارد نیز در نظر گرفت. یکی از راه‌های محاسبه هزینه تاخیر برابر با جمع سه عامل زیر است: ۱- ارزش کاربری: ارزش بالقوه از نگاه کاربر ۲- ارزش زمانی: چگونگی کاهش «ارزش کاربری» با گذشت زمان ۳- ارزش ناشی از کاهش ریسک یا استفاده از فرصت به هر یک از این گزینه‌ها عددی مابین ۱ تا ۱۰ داده شده و جمع نهایی این سه برابر با جمع هزینه تاخیر است که می‌توان با آن پروفایل هزینه تاخیر را بررسی کرد‌. تصویر اول در کامنت
برخی سازمانها تحت تاثیر قوانین خاص و سخت گیرانه نظارت شده هستند مانند سازمانهای تولید کننده محصولات پزشکی و بهداشتی، در این سازمان این عوامل می‌تواند از متغییرهای تاثیر گذار بر هزینه تاخیر باشد. برای مثال استاندارد ICD-10-CM نظام پزشکی ایالات متحده و رعایت قوانین U.S.HIPAA است
هزینه تاخیر عامل بسیار مهمی در اولویت بندی اقتصادی سبد بازسازی محصولات است برآورد صحیح، نه دقیق برای زمان بندی درست اقلام در بک لاگ سبد باید نسبت حجم کار به هزینه هر محصول را بدانیم. در ابتدای برآورد اطلاعات کمی در اختیار داریم لذا در برآورد هر قلم بدنبال صحت هستیم، نه دقت در بخش‌های قبلی گفتیم سازمان‌ها برای برآورد اقلام بجای اعداد از سایز استفاده می‌کنند (تصویر دوم در کامنت) که معادل هزینه محصول هستند که شامل حقوق و دستمزد کارکنان، مخارج سرمایه‌ای و سایر هزینه‌های تولید محصول است که معمولا بیشترین هزینه مربوط به حقوق است. مزیت رویکرد استفاده از سایز به اندازه مافی دقیق بودن آن است و اطلاعات مفیدی برای تصمیم گیری در سطح سبد محصول فراهم می‌کند استراتژی‌های جریان ورودی ترسیم چشم انداز به ما اطلاعات مفید و مورد نیاز برای تصمیم گیری اقتصادی در مورد ادامه یا توقف محصول فراهم می‌کند. و استراتژی جریان ورودی به ما در نحوه چگونگی اعمال فیلتر اقتصادی برای توقف یا ادامه محصول را می‌دهد و به موارد زیر نیز می‌پردازد
- ایجاد توازن بین نرخ ورود محصولات به سبد و نرخ خروج از آن
- روش استفاده از فرصت‌های نوظهور و جلوگیری از ایجاد گلوگاه در سبد محصول با استفاده از انتشارهای کوچک‌تر و زود به زود
۱- اعمال فیلتر اقتصادی خروجی ترسیم چشم انداز، عبارت است از سند چشم‌انداز محصول و اطلاعات لازم برای شفاف سازی. این خروجی شامل داده‌های مربوط به محصول جدید است که بعنوان ورودی برنامه ریزی استفاده می‌شود که سازمان بر اساس آن تصمیم به ادامه یا توقف محصول را می‌گیرد. هر سازمان فیلترهای اقتصادی مخصوص بخود را دارد اما یک فیلتر خوب باید فرصت‌هایی که نسبت ارزش به هزینه آنها چشم گیر است را به سرعت تایید کند و هرچیزی غیر از این را رد کند مگر در شرایط خاص (اگر ارزش محصول هزینه را پوشش می‌دهد آن را در سبد محصول قرار دهید، اگر بحث مبلغ ناچیز است آن را رد کنید) ۲- ایجاد توازن بین نرخ ورود و نرخ خروج در عمل انتظار داریم یک جریان پیوسته در ورود اقلام به سبد و خروج آن برقرار باشد و از طرفی هم نمی‌خواهیم افزودن یکباره تعداد زیادی از محصولات، بک لاگ محصولات را شلوغ کنیم، چنین کاری فشار قابل توجهی به سیستم وارد می‌کند. اکثر سازمان‌ها تصمیمات اقتصادی خود را در سه ماهه سوم سال با یک رویداد برگزار میکنند و محصولات زیادی را در سبد قرار می‌دهند که منجر به اختلال می‌شود #scrum @code_crafters

برنامه ریزی سبد محصول بسیاری از سازمانها بر روی تولید چند محصول همزمان کار می‌کنند که نیازمند رویکردی هستند تا تجربه خود را با چابکی ادغام کنند در غیر این صورت شکاف عمیقی بین برنامه ریزی و مدیریت سبد محصول بوجود می‌آید. در این بخش ۱۱ استراتژی مورد استفاده را در قالب ۳ گروه زمانبندی، جریان ورودی محصول و جریان خروجی محصول توضیح داده و روشی جهت تصمیم‌گیری بابت ادامه یا توقف سرمایه گذاری روی محصولات را بررسی خواهیم کرد نگاه کلی برنامه ریزی سبد محصول فعالیتی است که طی آن مشخص می‌شود روی چه اقلامی از بک‌لاگ به چه ترتیبی و چه مدتی کار انجام شود. یک قلم از سبد می‌تواند یک محصول، بخش قابل عرضه از یک محصول یا یک پروژه باشد زمان انجام برنامه ریزی سبد محصول فعالیتی است که هیچگاه به پایان نمی‌رسد و تا زمانیکه بیش از یک محصول داریم این روند. برنامه ریزی سبد کلان‌تر از برنامه ریزی محصول است اما به معنای تقدم بر آن نیست. ترسیم چشم انداز محصول میتواند ورودی خوبی برای برنامه ریزی سبد باشد. ابتدا بر روی سرمایه گذاری روی محصول و بعدا در کجا قرار گرفتن محصول در بک لاگ تصمیم گرفته می‌شود. برنامه ریزی سبد فقط برای محصولات جدید نیست بلکه در بازه‌های زمانی منظم و برنامه ریزی شده برای بازنگری محصولات جاری (در حال توسعه، عملیاتی شده، در حال فروش) نیز انجام می‌شود شرکت کنندگان از آنجا که برنامه ریزی سبد هم با محصولات جدید و جاری در ارتباط است لازم است مالکان به‌همراه ذینفعان داخلی، معماران ارشد و مدیران فنی در آن شرکت داشته باشند. بهتر است ذینفعان درک درستی از کسب و کار داشته باشند تا در اولویت بندی بک‌لاگ خوب عمل کنند در برخی سازمان‌ها گروهی با عنوان هیئت نظارت بر این فرآیند نظارت می‌کنند. مالکان در برنامه ریزی سبد به‌عنوان نماینده محصول خود شرکت کرده تا منابع مورد نیاز خود را اعلام کرده و از آن دفاع کنند. جهت اطمینان از قید فنی مهم در تصمیم گیری‌ها معماران ارشد یا مدیران فنی حضور دارند فرآیند برنامه ریزی سبد شامل محصولات جاری و محصولاتیست که چشم انداز آنها به تازگی ترسیم شده است. محصولات جدید به همراه داده‌هایی مانند هزینه، مدت تولید، ارزش و ریسک به برنامه ریزی سبد وارد می‌شوند که موارد در مرحله ترسیم چشم انداز محصول بدست می‌آیند. محصولات جاری نیز به همراه بازخورد مشتریان میانی، بهای تمام شده، زمان بندی، محدوده برآورد شده محصول، میزان بدهی فنی و اطلاعات بازار وارد برنامه ریزی سبد محصول می‌شوند که در تعیین مسیر آینده محصولات تاثیر گذارند. تصویر اول در کامنت فعالیت برنامه ریزی سبد دو خروجی دارد ۱- بک‌لاگ سبد محصول که فهرست اولویت بندی شده از محصولات آتی است که تایید شده‌ اما توسعه آنها هنوز شروع نشده ۲- مجموعه‌ای از محصولات فعال است که دو دسته هستند، دسته اول محصولات جدید تایید شده که در انتظار شروع توسعه هستند، دسته دوم محصولاتی که در لیست محصولات جاری قرار گرفته و ادامه سرمایه گذاری آنها تایید شده است برای رسیدن به این خروجی‌ها چهار فعالیت انجام می‌شود: زمان بندی، مدیریت جریان ورودی، مدیریت جریان خروجی، و مدیریت محصولات جاری. تصویر دوم در کامنت
استراتژی زمان بندی: کمک میکند تا ترتیب قرار گرفتن محصولات در بک‌لاگ سبد محصول تعیین شوند
استراتژی جریان ورودی: به شرکت کنندگان کمک میکند تا بدانند چه زمانی اقلام را به یک لاگ سبد اضافه کنند
استراتژی جریان خروجی: زمان خروج یک محصول از سبد را مشخص می‌کند
استراتژی محصولات جاری: تصمیم گیری درباره حفظ، تغییر مسیر، تحویل یا کنار گذاشتن محصولات جاری استفاده می‌شود
استراتژی زمان بندی باید منابع سازمان را به شیون اقتصادی به محصولات اختصاص داد. روش‌ها و استراتژی‌های گوناگونی جهت قرار دادن محصولات در سبد وجود دارد از جمله: ۱- بهینه کردن سود چرخه‌ی عمر ۲- محاسبه هزینه تاخیر ۳- برآورد صحیح، نه دقیق بهینه کردن سود چرخه‌ی عمر ابتدا باید تصمیم بگیریم از چه متغیری برای اندازه گرفتن بهینه سازی استفاده کنیم. چارچوب اقتصادی یکی از موارد پیشنهادی است که می‌توان سود چرخه‌ی عمر را بررسی کرد که بر اساس آن باید سود چرخه‌ی عمر کل سبد بیشینه باشد. سود چرخه عمر، سودیست که یک محصول برای همیشه دارد لذا در سبد این را برای کل محصولات در نظر می‌گیریم و سود برخی محصولات را کاهش می‌دهیم بنابراین استراتژی سود چرخه عمر یافتن نگترتیب قرار دادن اقلام در بک‌لاگ سبد است که موجب بیشترین سود شود. در تعیین سود چرخه عمر دو عامل هزینه‌ی تاخیر و مدت تولید دارای اهمیت می‌باشد (مدت تولید محصول شاخص جایگزین حجم کار و اندازه‌ی محصول است) براساس مشاهده این دو مورد در محصولات سه گزینه پیش روی ما است (تصویر سوم در کامنت) #scrum @code_crafters

در حیطه جستجوی متن خیلی از ما با تصور اینکه پستگرس میتونه انجام بده پیش میریم، اما حقیقت تو سازمان اصلا اینکار رو نمیکنن و سمت پلتفرم‌های مخصوص میرن که نمونه اون elasticsearch هستش (بیشتر بابت الگوریتم‌هایی که داخلشون استفاده میشه که قدرت شگرفی رو خلق میکنه، حتما راجب الگوریتم‌ها بخونید تا تفاوت رو درک کنید) زبان کوئری خاص خودش رو داره و تو حالت‌های مختلفی هم میتونید کنار هم بچینید و باهاش یک جستجوی متن حرفه‌ای ازش در بیارید بالطبع واسه جنگو هم کتابخونه جهت کار کردن باهاش موجوده ولی منتها من توصیه نمیکنم کار کردن با کتابخونه‌های سطح پایین‌تری مثه خود elasticsearch پایتونی بهتره و کلی اختیارات و دست بازتر جهت نوشتن کوئری‌هایی با پرفورمنس بهتر وجود دارد خود الاستیک کار میکنه اما یکی از نکات مهم اون سینک کردنش با دیتابیس هستش که یک چالش واسه مصاحبه‌ها و شرکت‌ها هستش دانشگاه mit یه موتور بابت این موضوع توسعه داده با اسم hystack که مخصوص جنگو هستش و علاوه بر الاستیک ، ابزارهای دیگه رو هم ساپورت میکنه، خیلی چیزهارو بهمون میده مثلا حروف اضافه رو در جستجوها و ایندکس‌ها قرار نده و بابت هر زبانی یک پکیج هم بهمون داده، نرمالایزر و ... هم بهمون میده که همه این‌هارو باید تنظیم کنید راجبش حتما بخونید من داخل دو پروژه ازش استفاده کردم و بشکل چشم گیری قدرت سرچ رو بالا برد #django @code_crafters

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

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

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

محاسبات موازی: یک عملیات روی چند هسته انجام می‌شود محاسبات همزمان: یک هسته بین چند عملیات جابجا می‌شود داریم راجب چی صحبت میکنیم؟؟؟ وقتی برنامه شما اجرا میشه، تبدیل به فرآیندهایی در سطح سیستم عامل میشه و سیستم عامل شروع میکنه به مدیریت اونها (به شکل پیشگیرانه) مطابق استاندارد خودش، اینکه چه منابعی رو و چقدر درگیر کنه یا نگه داره و یا از سر بگیره و به دیگری بده و ... واسه جماعت برنامه نویس خبر خوب اینکه هیچی دست شما نیست، و خبر بد اینکه هیچی دست شما نیست😅😅😅 در واقع این مشکل شما نیست منتها نمی‌تونید کار زیادی هم انجام بدید در پایتون دو کتابخانه داریم: یکی تردها: که بوسیله اون چندین نخ روی هسته اجرا میشه - کنترل اون رو سیستم عامل در دست میگیره - هرگاه یک نخ دچار مشکل بشه مابقی نخ‌ها توسط سیستم عامل اجرا و کار رو پیش می‌برند - مناسب کارهای ورودی خروجی هستش - پیچیدگی استفاده دارند (نمیدونیم چه اتفاقی داره میافته و اصلا نخ فعال داریم یا نه تا زمانیکه رخ دادی ازشون مشاهده کنیم مثه خونه جن زده تا اتفاقی نیافته متوجه حضورشون نمی‌شیم) - به سطح فرآیند برسند gil فعال شده و در واقع موازی سازی ندارید دلیل اون هم جلوگیری از شرایط مسابقه (race conditions) هستش ـ پر هزینه هم هستند دومی مولتی پراسس: هر فرایند روی یک هسته اجرا میشه - کنترل اون توسط سیستم عامل هست - مناسب پردازش‌های سنگین - پیچیدگی خاص خودش رو داره و اندکی کار خطرناک هستش - پر هزینه هم هستند مشکل این دو کتابخانه پیچیدگی زیاد در استفاده هستش و هر کدام در یک کتابخانه جدا تهیه شده بود که استفاده ازش دردسر خاص خودش رو داشت در نهایت کتابخانه concurrent.future اومد وسط که استخر تردها و پروسس هارو باهم داشت و در api سطح بالا بهمون کمک می‌کرد مشکلات gil در ترد سرجای خودش باقی موند منتها کار و مدیریت رو راحت‌تر میکنه برامون تا اینجا تردها به رویکرد پیشگیرانه توسط سیستم عامل عمل میکردن میرسیم به نخ‌های سبز: این نوع نخ‌ها در سطح برنامه شما (مفسر پایتون) کار میکنن - در سطح سیستم‌عامل تنها بر روی یک نخ اجرا میشوند - دسترسی بیشتری بابت مدیریت و کنترل بهمون میدن و باید خودمون مدیریت کنیم - به روش مشارکتی کار میکنن (منابع رو بر اساس نقاطی که ما مشخص کردیم بهمدیگه پاس میدن) - هزینه کمتری دارن - اما یک اشتباه از سمت ما منجر به کرش برنامه خواهد شد (دیباگ سخت) - هزینه کمتر و سبک تر و اغلب سریع‌تر از تردهای سیستم عامل هستند - در صورت ترکیب با چند پردازنده موازی سازی رخ میده (در غیر این صورت چون در یک نخ در سیستم عامل اجرا میشود تحت کنترل gil است) در موضوع بالا احتمال دیباگ و خطا منحر به کرش برنامه می‌شد بابت همین asyncio اومد وسط که کاملا از لحاظ کارایی شبیه نخ‌های سبز بود با این تفاوت که در نخ سبز نقاط پایانی و جابجایی توسط ما بود (همون جایی که ممکن بود خطا کنیم)، ناهمزمانی در یک حلقه رویداد رخ میداد و بدین ترتیب مشکل کرش بر طرف شد - اندکی سرعتش از نخ‌های سبز کمتره و نیاز به یادگیری داره در نهایت برگردیم سر وب، در وب هر فریمورکی که بر پایه و اساس starlette نوشته بشه (یک ماژول برای http) از ناهمزمانی پشتیبانی میکنه و میتونه رقیب سر سختی برای go و nodejs محسوب بشه که نمونه بارز اون fastapi هستش اما این مسائل بر علیه django خواهد بود؟ نه حقیقتا، جنگو بشدت برای برنامه‌های بزرگ و پیچیده مناسب است سعی کردم خیلی ساده براتون بگم 😂😂😂 #python #thread #gil #process @code_crafters

پروژه وقتی به مرحله پروداکشن میرسه، یه گام خیلی مهم داره که انجام اون الزام آوره لاگ گرفتن و لاگ انداختن موضوعی که تو همه پروژه‌ها از کوچیک تا بزرگش و تو هر معماری مورد نیاز هستش انواع مختلف لاگ رو داریم در سطوح مختلف و همیشه کنترل کردنش بهتره بگیم نوشتن لاگ شخصی و توسعه اون یه دردسر نسبتا بزرگ هستش مهمترین نوع لاگ در دنیای برنامه نویسی audit log (لاگ میمیزی) هستش که در سطح امنیتی و رهگیری تمامی رفتارهای کاربر در سیستم انجام میشه که با جزئیات کامل صورت میگیره در جنگو کتابخونه django-auditlog با نصب و کانفیگ (تنظیماتش خیلی راحت هستش) کردنش لاگ ممیزی رو در سیستم شما پیاده سازی میکنه و فیچرهای کنترلی زیادی رو هم بهتون میده کمتر از نیم ساعت این کتابخونه رو بخونید و خیلی راحت تو پروژه‌ها ازش بهره ببرید هم بخش امنیتی سازمان و هم پشتیبانی و مدیران رده بالا رو به رضایت از بخش لاگ گیری سیستم میرسونه #monitoring #django #log #audit_log @code_crafters

Content Negotiation تصور کنید که ما یک سایت بین‌المللی داریم که روزانه هزاران درخواست توسط افراد از سرتاسر جهان دریافت می‌کند. همه‌مان می‌دانیم که برای چنین سایت بزرگی نمی‌توانیم صرفا محتوا را به زبان انگلیسی به اشتراک بگذاریم بلکه باید از یک مکانیزم استفاده کنیم تا هر کاربر به زبان کشور خودش محتوا را دریافت کند. به این موضوع Content Negotiation می‌گوییم. در این پیام به نحوه تصمیم‌گیری برای انتخاب یک زبان می‌پردازیم. به طور کلی ما دو روش برای انتخاب زبان داریم: - Client-driven negotiation - Server-driven negotiation اکنون به Client-driven negotiation می‌پردازیم. در این مکانیزم هنکامی که کاربر به سایت codecrafters.ir درخواست می‌زنند, سرور کد کرفرترز برای کلاینت لیستی از زبان‌‌ها را ارسال می‌کند. اکنون مرورگر می‌تواند تصمیم بگیرد که کدام یک از url ها را باز کرده و به کاربر نشان دهد. همانطور که متوجه شدید, این روش اصلا مناسب نیست! چرا که باید ۲ برابر ریکوئست ارسال شود و این موضوع latency را به شدت افزایش می‌دهد. پس بهتر است به فکر یک روش دیگری باشیم تا دیگر کلاینت این‌همه درگیر انتخاب زبان نباشد. برای حل این موضوع Server-side negotiation بوجود آمد. وب‌سرور به ۲ روش تصمیم می‌گیرد که کدام یک از زبان‌ها را انتخاب کند. ۱- استفاده از header هایی مانند Accept-language و Accept-charset. ۲- استفاده از User-agent کاربر. شاید این سوال برایتان پیش‌ بیاید که چرا مورد دوم را بررسی می‌کنیم. در جواب این سوال باید بدانیم که گاهی تنها زبان مهم نیست بلکه مهم این است که اطلاعات درست به کاربر نمایش داده شود. تصور کنید که یک وبسایت در صفحاتش از جاوااسکریپت استفاده می‌کند و مرورگر قدیمی ما از جاوا اسکریپت پشتیبانی نمی‌کنید. پس سرور باید محتوای درستی که از JS استفاده نمی‌کند را با زبان درست برای کاربر ارسال کنید. گاهی Http اجازه می‌دهد که کاربران یک لیست از انتظارات خود ارسال کنند. تصور کنید ما می‌خواهیم به سایت codecrafters.ir درخواست بزنیم اما نمی‌دانیم که آیا زبان المانی پشتیبانی می‌شود یا خیر. پس ما در هدر Accept-language مقدار زیر را ارسال می‌کنیم: Accept-language: en;q=0.5, fr;q=0.0., du;1.0. هنگامی که سرور این پیام را دریافت می‌کند, اینگونه برداشت می‌‌کند که محتوا باید المانی باشد, اگر چنین چیزی موجود نبود, انگلیسی نیز می‌پذیرد. اما باید توجه داشته باشد که هیچگاه محتوای فرانسوی ارسال نکند. گاهی نیز این تصمیمات را بر عهده proxy می‌سپاریم. این proxy server است که تصمیم می‌گیرد به کدام resource درخواست بزند و اطلاعات لازم را به کاربر ارسال کند. #http_guideline @code_crafters

یکی از مواردی که این روزها خیلی نیازمند هستش در داخل برنامه نویسی تحت وب و وب اپلیکیشن حضور و وجود تسک‌های ناهمگام و زمان بندی و برنامه ریزی شده هستش اخیرا هم تو مراحل مصاحبه و استخدامی هم از این سوالات زیاد پرسیده میشه فریمورک fastapi چون پیش فرض و در دل خودش asyncio هستش این مورد هندل میکنه اما برای django ما از ترکیب celery با (rabbitmq ، redis) استفاده میکردیم اما این خودش یکمقدار افزونه و کار بیشتر اضافه میکرد پکیج django_q اومده و کار رو راحت کرده هم برای تسک‌ها ناهمگام و هم برای تسک‌های زمان بندی شده و برنامه ریزی شده پیش فرض و پرفورمنس اون با ردیس هستش اما توان اتصال به سایر ابزارهایی که بتونن بعنوان بروکر استفاده بشند رو هم داره (حتی بروکر کاستوم و شخصی خودتون) خیلی راحت‌تر و سبک تر از سلری هستش و هیچگونه پیچیدگی خاص اجرایی و کار کردی نداره میتونید باهاش در پس زمینه یا برنامه ریزی شده ارسال ایمیل و پیامک داشته باشین، تصاویر و فایل‌هارو ذخیره کنید (حتی بصورت chunk) و علاوه بر این می‌تونید لایه‌کوئری رو هم باهاش به صورت ناهمگام با orm اجرا کنید بچه‌های جنگو کار حتما این کتابخونه رو در حد چند ساعت بخونن هم پرفورمنسی و زمانی بکارتون میاد بشدت #django @code_crafters

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

بچه‌های asp و vue js هم رزومه بدن

Http Internationalization روزانه میلیاردها انسان در جهان document هایی را به زبان‌های مختلفی در اینترنت به اشتراک می‌گذارند. همانطور که از اسم world-wide web مشخص است, این شبکه برای تمام افراد جهان با هر زبانی است. پس باید راهی باشد که بتوانیم به نوعی تمامی این اطلاعات را منتقل کنیم هرگاه یک درخواستی ارسال می‌شود, یک هدر accept-language نیز با آن ارسال می‌شود. با این هدر کلاینت به سرور می‌گوید که من انتظار دارم پیامی که دریافت می‌کنم, زبانش این باشد. پس از اینکه سرور با توجه به این هدر ریسپانس را فراهم و ارسال کرد, در آن یک هدر به نام content-language ارسال می‌کند. اینگونه کلاینت می‌تواند با استفاده از آن محتوای پیام را باز کرده و از ان استفاده کند. اما چگونه این اطلاعات باینری تبدیل به متون قابل خواندن می‌شود؟ برای درک این موضوع ابتدا باید به مفهوم Charset ها بپردازیم. درواقع این charset ها هستند که می‌گویند این مقدار باینری را به کدام یک از کاراکتر های کدام زبان وصل کنیم. هنگامی که ریسپانس را دریافت می‌کنیم, در هدر content-type یک charset نیز ثبت شده است. مثال: Content-Type: text/html; charset=iso-8859-6 این به این معنی است که داده ما به صورت ۸ بیتی map می‌شود (که احتمالا یا لاتین است یا عربی!) حالا کار این character set ها چیست؟ کرکتر ست ها درواقع دو کار را انجام می‌دهند. ۱- تبدیل باینری به کد کاراکتر ۲- تبدیل کد کاراکتر به کلمه برای مثال ما می‌خواهیم به کمک کرکتر ست ها مقدار زیر را به کاراکتر تبدیل کنیم. 11100001 ابتدا این را به کاراکتر کد ۲۲۵ تبدیل می‌‌کنیم و سپس کد ۲۲۵ را به کلمه اصلی خود مپ می‌کنیم که درواقع کاراکتر «ف» است. پس: 11100001 -> 225 -> ف حالا که متوجه شدیم تمامی این کارها را کرکتر ست ها انجام می‌دهند, پس چرا هدر content-language ارسال می‌کنیم؟ کاراکتر ست ها صرفا الگوریتم هایی هستند که صرفا بر اساس زبان, می‌توانند کد ها را به کلمات مپ کنند. برای مثال کرکتر کد ۲۲۵ در زبان‌های مختلف شکل های مختلفی دارد. در زبان لاتین a و در زبان عربی «ف» است و در زبان یونانی «الفا». به عنوان نکته پایانی باید درنظر داشت که کاراکتر‌ها می‌توانند فرم‌های گوناگونی داشته باشند. برای مثال کاراکتر «ع» می‌تواند گاهی «عـ» نیز باشد. اینجا نیاز است که مفهوم glyph را درک کنیم. هنگامی که کاراکتر کد به یک کاراکتر مپ می‌شود, نوع نشان دادن آن مشخص نمی‌شود. ما صرفا می‌دانیم که 225 عدد کاراکتر «ف» است. حال نمایش دادن این عبارات بر عهده glyph است. اگر بخواهیم موشکافانه تر به قضیه نگاه کنیم, فرایند تبدیل بصورت زیر خواهد بود: 11100001 -> 225 -> "ARABIT LETTER FEH" -> glyph shows «ف» #http_guideline @code_crafters

پک خوش آمدگویی شرکت جدید وقتی مدیرفنی روحیاتت رو میدونه
پک خوش آمدگویی شرکت جدید وقتی مدیرفنی روحیاتت رو میدونه

حادثه تلخ انفجار در بندر رجایی کشته و مجروح شدن هم‌وطنان عزیزانمون نام و یاد کشته شدگان این حادثه ماندگار و طلب صبر برای بازماندگان 🖤🖤🖤 آرزوی بهبود مجروحان و بازگشت به کانون گرم عزیزان خود💔💔💔 یک ایران دلواپس و همراه غم و اندوه شماست 🌹🌹🌹🌹