آشنایی به عناوین و سلسهمراتب سازمانی مهندسی نرمافزار، توانمندیها و مسئولیتها. و اینکه از کجا بفهمیم سازمان ما چه سطوحی رو نیاز داره...
Please open Telegram to view this post
VIEW IN TELEGRAM
سلسلهمراتب مهندسی نرمافزار موضوع مهمیه، هم برای سازمان که بخواد با ساختار مناسب به اهداف و برنامههاش برسه و بهرهوریاش رو بهبود بده؛ هم افراد انگیزه برای رشد و یادگیری و رقابت داشته باشن. پس داشتن یه ساختار سازمانی درست + ساز و کار ارزیابی و رشد سرمایهانسانی، نه تنها حیاتیه، بلکه یه چالش بُرد-بُرد برای سازمان و افراده.
قبل از توضیح در مورد انواع سلسلهمراتب مهندسی نرمافزار، باید بدونیم » چجوری ساختار سازمانی مناسب رو انتخاب کنیم؟
آیا هر چی گوگل، اپل، متا یا... داره رو کپی کنیم؟ یا هر کاری هزاردستان و اسنپ و دیجیکالا کردن رو کپی کنیم؟ (حتی لحن سوالم نشون میده فقط یکی از انواع مدیران جواگره چنین کاری رو میکنه 😁)
موارد زیر تنها تعدادی از مولفههای مورد بررسی برای طراحی ساختار سازمانی مهندسی نرمافزاره، برای هر کدوم دو مورد مثال ذکر میکنم.
توجه داشته باشید که هم مولفههای بیشتری دخیله، هم مثالهای متنوعتری میشه از انواع هر مولفه زد که از حوصله پست تلگرامی خارجه.
۱. اندازه شرکت
۲. پیچیدگی محصول
۳. فرهنگ سازمانی
۴. اهداف رشد
۱. نیازسنجی (Gap Analysis):
۲. مقایسه با شرکتهای مشابه (Benchmarking):
۳. تعریف نقشه راه (Roadmap):
۴. انعطافپذیری:
این بخش اول بود، لازم بود توضیح بدم که نقشها و انواع سلسه مراتبی که در قسمت بعدی معرفی خواهم کرد، فقط نمونههاییه که سازمانهای مختلف بر اساس نیاز و شرایطشون ایجاد کردن. مثلا Distinguished Engineer یا Developer Advocate نقشهایی است که برخی سازمانها بنا به ضرورت، اهداف و نیازشون ایجاد کردن و دارن، دلیل نمیشه همه داشته باشن.
از اون طرف اگر ما نقشها و مسئولیتها رو درست نشناسیم در انتخاب مسیر شغلی شاید انتخابهای غیر بهینهای کنیم. پس افراد باید بدونن مسیر رشدهای مختلف چیه تا هم نقشه رشدشون رو ترسیم کنن هم سازمان متناسب رو برای کار کردن انتخاب کنن. از طرفی سازمانها هم باید تکلیفشون مشخص باشه تا بتونن چرخه تربیت و رشد سرمایهانسانی رو ترسیم و اجرا کنن. شما برای تربیت نیروی انسانی باید افرادی رو داشته باشی که «بلد باشن و شایستگی» هدایت نیروی انسانی رو داشته باشن. نه اینکه هر وقت مدیر رفت نفر بعدی رو مدیر کنی! یا هر کی شوآف بیشتری داشت ارتقاء بدی!
🌱 لطفا دقت شود: «هدایت» با «راهنمایی» بسیار فرق داره! هدایت یعنی من دست شما رو بگیرم ببرمتون به مقصد مشخص برسونم. ولی راهنمایی یعنی بهتون آدرس رو بگم. لیدرشیپ نوعی از هدایت است، وگرنه راهنمایی توی اینترنت زیاده!
دوست دارید ادامه بدم و قسمت دوم و بعدترش رو داشته باشیم؟
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
کوییز: تنها ۲ درصد افراد قادر به حل این کوییز هستن که جزو نوابغ ناسا به شمار میان.
کدام گزینه نابودکنندهترین اقدام برای «حال و آینده» یک مهندس نرمافزار است؟
کدام گزینه نابودکنندهترین اقدام برای «حال و آینده» یک مهندس نرمافزار است؟
Anonymous Quiz
2%
رها نمودن پیانو از بالای ساختمان وقتی در حال عبور است
1%
وارد کردن وی داخل چرخ گوشت و دریافت دهها مهندس کوچولوی رشته رشته
2%
تنها گذاردن وی داخل اتاقی مملو از کروکودیل گرسنه
5%
وصلت وی با عمهی بیوه کیمجونگاون که همسر مرحومش تابآوری کافی در مقابل شلیک گلوله توپ کیم را نداشت
70%
ارتقاء وی به پوزیشن لیدرشیپ یا تصمیمگیر وقتی تجربه و دانش کافی را ندارد
20%
با یک سال سابقه، طی فرایند شایستهگزینی قحطالرجال/قحطالنساء شدم انجینیرینگمنجر اومدم نتیجه ببینم
🤣24👍1🔥1
خب حالا که فهمیدیم انتخاب ساختار سازمانی بستگی به نیازها و شرایط داره، بریم سراغ یه نمونه واقعی: گوگل!
گوگل یکی از شرکتهاییه که ساختار مهندسی مدون و تعریفشدهای داره و خیلیها تو مسیر شغلیشون دوست دارن بدونن که این مسیر رشد توی گوگل چطوره. البته دوباره تأکید کنم: ساختار گوگل برای گوگل خوبه! کپی کردنش بدون توجه به اندازه، اهداف، و فرهنگ سازمانی شما مثل این میمونه که کت و شلوار سایز ۳XL بخری ولی قدت ۱۲۰ باشه! 😁
۱. سطح Software Engineer I (L3)
📌 تجربه و دانش: معمولاً تازهواردها، فارغالتحصیلان دانشگاه یا کسانی که صفر تا دو سال تجربه دارن
۲. سطح Software Engineer II (L4)
📌 تجربه و دانش: معمولاً چند سال (۲ تا ۵ سال) تجربه کاری در پروژههای واقعی
۳. سطح Senior Software Engineer (L5)
📌 تجربه و دانش: معمولاً ۵ تا ۱۰ سال تجربه، فرد باید بتونه راهحلهای فنی جامع و بهینه ارائه بده؛ یا کل پروژه رو از صفر تا صد هدایت کنه
۴. سطح Staff Software Engineer (L6)
📌 تجربه و دانش: معمولاً بالای ۱۰ سال تجربه، کسی که بتونه تصمیمات کلیدی فنی بگیره
۵. سطح Senior Staff Engineer (L7)
📌 تجربه و دانش: ۱۵+ سال تجربه، این سطح برای متخصصین عمیق در یک حوزه فنی در نظر گرفته شده (مهندسینی که در صنعت شناخته شدهاند)
۶. سطح Principal Engineer (L8)
📌 تجربه و دانش: عموما ۲۰+ سال تجربه و سطحی که فقط تعداد کمی از مهندسان بهش میرسن
۷. سطح Distinguished Engineer / Google Fellow (L9 - L10)
📌 تجربه و دانش: یکی از بالاترین جایگاههای مهندسی که فقط تعداد محدودی بهش میرسن
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2 1
جمعبندی:
سلسلهمراتب گوگل برای شرکتی با ۱۷۰ هزار کارمند و محصولات جهانی طراحی شده. اگر سازمان شما ۵۰ نفر است، دنبال استخدام L8 نباشید! 😂
موفقیت در گوگل (و هر شرکتی) به تاثیرگذاری (Impact) وابسته است، نه صرفاً سالهای تجربه. پس به جای تقلید کورکورانه، ساختاری طراحی کنید که متناسب با قد و بالای سازمان شما باشه!
💬 شرکت بعدی چی باشه؟ (کامنت کنید)
بوکینگ؟ مایکروسافت؟ اپل؟ Miro؟ ING؟ Meta؟ Ayvens؟
اگر مثال شرکتهای دیگه رو ادامه بدم، ریاکشن:⚙️
اگر این بحث کافیه، ریاکشن:🤪
سلسلهمراتب گوگل برای شرکتی با ۱۷۰ هزار کارمند و محصولات جهانی طراحی شده. اگر سازمان شما ۵۰ نفر است، دنبال استخدام L8 نباشید! 😂
موفقیت در گوگل (و هر شرکتی) به تاثیرگذاری (Impact) وابسته است، نه صرفاً سالهای تجربه. پس به جای تقلید کورکورانه، ساختاری طراحی کنید که متناسب با قد و بالای سازمان شما باشه!
بوکینگ؟ مایکروسافت؟ اپل؟ Miro؟ ING؟ Meta؟ Ayvens؟
اگر مثال شرکتهای دیگه رو ادامه بدم، ریاکشن:
اگر این بحث کافیه، ریاکشن:
Please open Telegram to view this post
VIEW IN TELEGRAM
مقدمه: یکی از چالشهای متعدد و اساسی جامعه ما اینه که «سوال نداریم» خصوصا «سوال خوب»!! شاید روزی مفصل نوشتم در موردش... فعلا بگذریم...
امروز یک سوال «خوب» در مورد مطلب قبلی طرح شد؛ ممنون از آقا یا خانم NaN که پرسیدن:
به احترام پرسش خوب ایشون سعی میکنم در حد بضاعت پست تلگرامی توضیح بدم.
توی مباحث لیدرشیپ فنی، ۳ تا کلمه داریم که دونستن معانی اونها مهمه:
💡 در مورد Output (خروجی)
تعریف: خروجی، محصول مستقیم و قابلاندازهگیری فعالیتها یا وظایفه. درواقع، ماحصل بلافصل کاریه که انجام میدهیم؛ مثلاً کدنویسی، طراحی، مستندسازی یا تولید نسخه اولیه نرمافزار. عملا فعالیتها یا محصولات ملموسی که تیم تولید میکند.
⚙️ مثال:
===========================
💡 در مورد Outcome (نتیجه)
تعریف: نتیجه به تأثیرات و تغییراتی اشاره داره که به واسطهٔ یک خروجی در رفتار یا وضعیت کاربران، کسبوکار یا فرایندهای داخلی به وجود مییاد. Outcome معمولاً روی «ارزش» تمرکز داره؛ اینکه خروجی تولیدشده چه مشکلی را حل کرده یا چه بهبودی ایجاد کرده.
⚙️ مثال:
===========================
💡 در مورد Impact (تأثیر یا اثرگذاری کلان)
تعریف: Impact سطحی کلانتر از «نتیجه» است که نشون میده تغییرات ایجادشده چه اثرات عمیق یا پایدار در جامعه، بازار، استراتژی کلان شرکت یا حتی صنعتی که شرکت توش فعالیت میکنه، داشته است. Impact فراتر از یک «دوره کوتاه» یا «مقیاس کوچک» است و غالباً در بلندمدت ارزیابی میشود.
⚙️ مثال:
===========================
لذا این خیلی خیلی مهمه که «ملاک سنجش و ارزشگذاری» عملکردمون «استاندارد و جهانی» باشه... وگرنه: «خود گویی و خود خندی... عجب مرد هنرمندی!»
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10 4👍2
حالا که گوگل رو مرور کردیم، و مفهوم impact در سازمان رو دیدیم، بنا به نظر و پیشنهاد شما، بریم سراغ مایکروسافت ۲۲۸هزار کارمند داره که متناسب با ساختار و نیازهاش، نردبان شغلی خاص خودش رو داره:
۱. سطح L59 - Software Development Engineer I (SDE I)
📌 تجربه و دانش: فارغالتحصیلهای تازهکار یا ۰ تا ۲ سال تجربه.
۲. سطح L60 - Software Development Engineer II (SDE II)
📌 تجربه و دانش: معمولاً ۲ تا ۵ سال تجربه، کسی که بتونه مشکلات فنی پیچیدهتر و پروژههای کوچیک رو حل کنه.
۳. سطح L61-L62 - Senior Software Engineer (SSE)
📌 تجربه و دانش: معمولاً بالای ۵ سال تجربه، کسی که بتونه استقلال بیشتری در تصمیمگیریهای فنی داشته باشه
۴. سطح L63-L64 - Principal Software Engineer
📌 تجربه و دانش: معمولاً ۸-۱۲ سال تجربه، فردی که میتونه چند تیم رو از نظر فنی هدایت کنه.
۵. سطح L65-L66 - Partner Software Engineer
📌 تجربه و دانش: یکی از بالاترین سطوح مهندسی فنی در مایکروسافت، معمولاً ۱۲+ سال تجربه.
۶. سطح L67 - Distinguished Engineer
📌 تجربه و دانش: افرادی که تأثیر مستقیمی روی کل صنعت دارن، تعداد این افراد خیلی کمه (مثال: دیوید فولر)
۷. سطح L68+ - Microsoft Technical Fellow
📌 تجربه و دانش: بالاترین سطح فنی در مایکروسافت! این افراد تأثیرگذارترین چهرههای تکنولوژی شرکت هستن (اینقدر که مدخل ویکیپدیا دارن!)
🔀 مایکروسافت دو مسیر مجزا برای پیشرفت داره:
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
tech-afternoon
📇 سلسلهمراتب مهندسی نرمافزار (بخش دوم, گوگل!)
خب حالا که فهمیدیم انتخاب ساختار سازمانی بستگی به نیازها و شرایط داره، بریم سراغ یه نمونه واقعی: گوگل!
گوگل یکی از شرکتهاییه که ساختار مهندسی مدون و تعریفشدهای داره و خیلیها تو مسیر شغلیشون دوست دارن…
خب حالا که فهمیدیم انتخاب ساختار سازمانی بستگی به نیازها و شرایط داره، بریم سراغ یه نمونه واقعی: گوگل!
گوگل یکی از شرکتهاییه که ساختار مهندسی مدون و تعریفشدهای داره و خیلیها تو مسیر شغلیشون دوست دارن…
🔥11👍1
🛠 چرا سلسلهمراتب مهندسی برای شرکتهای کوچک و متوسط مهمه؟
شرکتهای کوچک و متوسط (SMEs) معمولاً چابکتر از غولهایی مثل گوگل و مایکروسافت هستن، ولی اگر نقشها شفاف نباشه، افراد جای رشد نداشته باشن و سازمان فاقد ساختار منطقی باشه، انگیزه تیم پایین میاد و رشد شرکت متوقف میشه. آدمها میرن یا فسیل میشن! و دیگه نقطه قوت چابکی تبدیل میشه به اسباب درجا زدن...
👨💻 هدف از طراحی نردبان شغلی اینه که:
🔹 سلسلهمراتب پیشنهادی برای یک شرکت پویا و مقیاسپذیر
۱. سطح Junior Software Engineer 👶
📌 ویژگیها: ۰ تا ۲ سال تجربه، تسلط روی اصول برنامهنویسی و یکی دو تکنولوژی
🔹 مسئولیتها:
🎯 شرایط ارتقا: تسلط به ابزارهای توسعه شرکت، بهبود درک معماری نرمافزارها
۲. سطح Software Engineer 👨💻 (مهندس نرمافزار)
📌 ویژگیها: ۲ تا ۵ سال تجربه، توانایی توسعه ویژگیهای مستقل
🔹 مسئولیتها:
🎯 شرایط ارتقا: ارائه راهحلهای بهینهتر (نه شوآف!) و درک بهتر از طراحی سیستمها
۳. سطح Senior Software Engineer 🔥 (مهندس نرمافزار ارشد)
📌 ویژگیها: ۵ تا ۸ سال تجربه، مهارت در حل مشکلات پیچیده
🔹 مسئولیتها:
🎯 شرایط ارتقا: توانایی تصمیمگیریهای فنی مهم، رهبری پروژههای بزرگتر
۴. سطح Lead Engineer / Tech Lead 🚀 (رهبر فنی تیم)
📌 ویژگیها: ۷ تا ۱۰ سال تجربه، تخصص در طراحی و راهبری سیستمهای پیچیده
🔹 مسئولیتها:
🎯 شرایط ارتقا: تجربه کافی در مدیریت تیمهای مهندسی، درک استراتژی فنی
۵. سطح Software Architect 🏛 (معمار نرمافزار)
📌 ویژگیها: ۱۰+ سال تجربه، توانایی طراحی سیستمهای بزرگ و توزیعشده
🔹 مسئولیتها:
🎯 شرایط ارتقا: داشتن دیدگاه کلان و استراتژیک به سیستمهای نرمافزاری
۶. سطح Engineering Manager 🎯 (مدیر مهندسی)
📌 ویژگیها: مهارت در هم مدیریت افراد، هم درک فنی سیستمها
🔹 مسئولیتها:
🎯 شرایط ارتقا: اثبات توانایی در هدایت چند تیم و موفقیت در اجراهای استراتژیک
۷. سطح CTO (Chief Technology Officer) 🏆 (مدیر ارشد فناوری)
📌 ویژگیها: بالاترین سطح فنی، توانایی هدایت کل دپارتمان مهندسی
🔹 مسئولیتها:
🎯 شرایط ارتقا: تجربه گسترده در رهبری فناوری و ایجاد محصولات موفق
🔹 انعطافپذیری حفظ بشه! یه استارتاپ ۱۰ نفره قطعاً نیازی به CTO یا چندین سطح از روز اول نداره، ولی وقتی رشد کنه، نیازش ایجاد میشه.
🔹 جایگاههای میانی حذف نشن! بین یه Junior و یه Senior باید مسیر رشد منطقی باشه، وگرنه انگیزه تیم کم میشه.
🔹 فرهنگ یادگیری و رشد ایجاد بشه! مسیر پیشرفت افراد نباید صرفاً روی «سالهای تجربه» باشه، بلکه توانایی و خروجی مهمتره.
🔹 وقتی برخی پوزیشنها رو به هر دلیلی ندارید، هیچ اشکالی نداره از مشاور «شایسته» استفاده کنید، خیلی بهتر از اینه که چون کسی رو ندارید بهش برچسب سنیور یا معمار یا کوفت بچسبونیم.
🔹 پوزیشنهای لیدرشیپ، فقط مهارت فنی نیاز ندارن، باید بتونه تعامل سازنده و مناسب با سایرین داشته باشن و کمک به رشد بقیه کنن
😊 پایان این بحث
خوشحال میشم فیدبک بدید 🌱
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🏆2
کوییز: بهترین مسیر برای رشد شغلی و پیشرفت در مهندسی نرمافزار کدام است؟ (نمونه سوال آزمون ثلث سوم دانشگاه هاروارد، ۲ نمره)
Anonymous Quiz
9%
پاچهخواری از روبرو، زیرآبزنی از پشت 😈
1%
شیتیل بدیم کارگزینی تا جلو اسممون بنویسه مهندس 🥸
1%
نفر بالادستی، دیر یا زود مهاجرت میکنه، فرداش میشینیم رو صندلیش، میشیم رییس 😎
1%
حوصله داری عامووو، پیشرفت کنیم که کجاا رو بگیریم مثلا؟! 🥱
60%
شرکتی کار کنیم که نردبان شغلی خوبی داره، تلاش و یادگیری و اثربخشی داشته باشیم 🤓
7%
قتل تمیز یا چیزخور کردن بیسروصدای نفر بالادستی، حداکثر مشارکت در شیوَن و ناله در مراسم ۷ و چهلم💀
6%
گز ۹۸درصد پسته و کاردستی خلاقانه برای مدیرعامل عزیز و قشنگ شرکت 🙇
1%
خرید پکیج موفقیت و پی بردن به راز پیشرفت 🤪
13%
گشتن توی وبلاگها و بلغور کردن اسم تکنولوژیهای جدید، تهلهجه انگلیسی + فراموشی لغات فارسی 💅
🤣17
یه اصطلاحی برای توصیف کالاهای تندمصرف داریم به نام FMCG یا Fast-Moving Consumer Goods که سریع فروش میرن، عموما ارزون هستن. مثل مواد غذایی و نوشیدنی، لوازم نظافت و...
برای محتوای دیجیتال هم اصطلاح «محتوای زودگذر» یا ephemeral content استفاده میشه. یعنی محتوایی که مثل اینستاگرام (بهخصوص استوریها) یا مطالب تلگرام منتشر میشه، که معمولاً به سرعت توسط کاربر مصرف میشه. خیلی از این محتواها فقط برای چند ساعت یا چند روز قابل مشاهده هستن یا اهمیتشون رو از دست میدن.
چند وقته درگیر این سوال شدم که آیا اصلا تلگرام جای درستی بود برای نوشتن محتوای فنی؟ جایی که گاها مجبورم از کلمات یا علائم نگارشی حذف کنم که توی یک پست جا بشه! یا اینکه بهتر بود تلگرام برای اعلان مطلب جدید در یک پلتفرم مناسبتر مثل بلاگ استفاده میشد؟ آیا مثلا مخاطب امروز این کنال، چقدر از محتوایی که ۲ ماه پیش نوشته شده و هنوز از نظر کاربردی منقضی نشده مطلع میشه یا در معرض انتخابش قرار میگیره؟
خلاصه اینکه اگر پیشنهاد و نظری که کمک کنه داشتید خوشحال میشم بگید... 😊
برای محتوای دیجیتال هم اصطلاح «محتوای زودگذر» یا ephemeral content استفاده میشه. یعنی محتوایی که مثل اینستاگرام (بهخصوص استوریها) یا مطالب تلگرام منتشر میشه، که معمولاً به سرعت توسط کاربر مصرف میشه. خیلی از این محتواها فقط برای چند ساعت یا چند روز قابل مشاهده هستن یا اهمیتشون رو از دست میدن.
چند وقته درگیر این سوال شدم که آیا اصلا تلگرام جای درستی بود برای نوشتن محتوای فنی؟ جایی که گاها مجبورم از کلمات یا علائم نگارشی حذف کنم که توی یک پست جا بشه! یا اینکه بهتر بود تلگرام برای اعلان مطلب جدید در یک پلتفرم مناسبتر مثل بلاگ استفاده میشد؟ آیا مثلا مخاطب امروز این کنال، چقدر از محتوایی که ۲ ماه پیش نوشته شده و هنوز از نظر کاربردی منقضی نشده مطلع میشه یا در معرض انتخابش قرار میگیره؟
خلاصه اینکه اگر پیشنهاد و نظری که کمک کنه داشتید خوشحال میشم بگید... 😊
🎩 کلاسیک: تست «فقط خروجی و رفتار نهایی» رو مورد ارزیابی قرار میده؛ نیازی به دونستن جزئیات داخلی نیست. مثلاً اگر کد توابع کمکی رو تغییر بدیم ولی نتیجه نهایی تغییر نکنه، تستها تغییر نخواهند کرد و فقط اگه Assertمون پاس شه، تست پاس شده.
🎡 لندن: تستها بر اساس نحوهی فراخوانی وابستگیها و جزئیات پیادهسازی دقیق نوشته میشن. این یعنی تغییرات جزئی در داخل کلاس (حتی بدون تغییر در خروجی نهایی) ممکنه باعث شکست تستها بشه؛ حتی اگه مثلا مقدار برگشتی یک متد دقیقا همونی باشه که قبلا بوده.
🎩 کلاسیک: ممکنه چند تست باهم شکست بخورن چون وابستگیها واقعی هستند. در نتیجه پیدا کردن مشکل ممکنه کمی زمان بیشتری ببره.
🎡 لندن: چون تستها به صورت دقیق تعاملات کلاسها رو چک میکنن، در صورت خطا معمولا به سرعت متوجه میشیم که مشکل کجاست.
🎩 کلاسیک: برای تستهای واقعی باید تمامی وابستگیها پیادهسازی بشن که اگر تعدادشون زیاد باشه کار زمانبر میشه؛ ولی از طرفی این موضوع میتونه نشونهای از طراحی پیچیده یا ناسالم سیستم باشه.
🎡 لندن: با استفاده از Mockها میشه وابستگیهای «سطح اول» رو شبیهسازی کرد بدون اینکه لازم باشه کل گراف وابستگیها رو راهاندازی کنیم.
🤔 اگر کنجکاوی که با کد هم تفاوتش رو ببینی: ریاکشن
Please open Telegram to view this post
VIEW IN TELEGRAM
tech-afternoon
به احترام ⚙️ گذارهای عزیز 😁 کد مثال با 📱 و 📱 رو در کامنت مطلب قرار دادم.
💬 کامنت نظر و تجربه داری بیا بحث کنیم 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🙏3👾1
🥸 هر چیزی رو توی اینترنت دیدیم باور نکنیم، خصوصا اگر فنی «به نظر» اومد!
وقت ناهار اینو توی توییتر دیدم که به نظرم بودار 🦨 اومد. من راست بلدم و از سی خاطراتی دارم، ولی خودم رو نه راستنویس میدونم نه سینویس، بلکه به قدر نیاز و هدف.
یه چالشی چند ساله مطرحه که با زبونهای مختلف کوچکترین hello world باینری رو چجوری میشه نوشت (مثلا جایگزینی printf با puts توی سی یا جایگزینی println با syscall_write توی راست و حذف لایبریهای اضافه و بهبود لینکینگ و...
لذا نشستم کد راست رو بازنویسی کردم و با ۱۴ کیلوبایت جمع شد. ولی آیا اینکه منم یه توییت بزنم بگم دیدی کد راست (مینیمال راست) من از کد سی کوچیکتر شد، درسته؟ خیر! بلکه چرندی به چرندیات افزودهام.
چرا؟ چون اونوقت باید کد مینیمال سی رو مقایسه کنیم که احتمالا باز نسبت به کد ۱۴ کیلوبایتی راست چیزی بین نصف تا یکسوم باید کوچیکتر شه.
ولی چرا باز هم سی کوچیکتر از راسته؟ مگه قرار نبود «عصر، عصر راستنویسی» باشه؟ 😁
- راست static linking داره
- راست runtime safety داره
من سورس کدم رو توی کامنت میگذارم. ولی اصلا نکته این مطلب اینا نبود! اینه که هر چیزی رو توی اینترنت یا از همکار و دوستمون دیدیم حتی اگر با عدد و رقم و کد آمیخته بود، تفکر انتقادیمون رو نسبت بهش حفظ کنیم 😊
وقت ناهار اینو توی توییتر دیدم که به نظرم بودار 🦨 اومد. من راست بلدم و از سی خاطراتی دارم، ولی خودم رو نه راستنویس میدونم نه سینویس، بلکه به قدر نیاز و هدف.
یه چالشی چند ساله مطرحه که با زبونهای مختلف کوچکترین hello world باینری رو چجوری میشه نوشت (مثلا جایگزینی printf با puts توی سی یا جایگزینی println با syscall_write توی راست و حذف لایبریهای اضافه و بهبود لینکینگ و...
لذا نشستم کد راست رو بازنویسی کردم و با ۱۴ کیلوبایت جمع شد. ولی آیا اینکه منم یه توییت بزنم بگم دیدی کد راست (مینیمال راست) من از کد سی کوچیکتر شد، درسته؟ خیر! بلکه چرندی به چرندیات افزودهام.
چرا؟ چون اونوقت باید کد مینیمال سی رو مقایسه کنیم که احتمالا باز نسبت به کد ۱۴ کیلوبایتی راست چیزی بین نصف تا یکسوم باید کوچیکتر شه.
ولی چرا باز هم سی کوچیکتر از راسته؟ مگه قرار نبود «عصر، عصر راستنویسی» باشه؟ 😁
- راست static linking داره
- راست runtime safety داره
من سورس کدم رو توی کامنت میگذارم. ولی اصلا نکته این مطلب اینا نبود! اینه که هر چیزی رو توی اینترنت یا از همکار و دوستمون دیدیم حتی اگر با عدد و رقم و کد آمیخته بود، تفکر انتقادیمون رو نسبت بهش حفظ کنیم 😊
👍7🔥6👏2
وقتی یه سیستم بزرگ داریم با تعداد زیاد کاربر یا درخواست همزمان، یکی از چالشهای اصلی اینه که هر کاربر بتونه تغییراتی که خودش ایجاد کرده رو بلافاصله ببینه. مثلاً وقتی توی یه شبکه اجتماعی پست میذارید، انتظار دارید همون لحظه پستتون رو ببینید، نه اینکه چند ثانیه صبر کنید. به این قابلیت میگن Read Your Own Writes یا RYW (خیلیجاها own حذف میشه و در نتیجه read your writes میشه RYW).
وقتی سیستمهامون کوچیکن، کار این موضوع آسونه؛ ولی هرچی سیستم بزرگتر و کاربرها بیشتر میشن، کار پیچیدهتر میشه. مثلاً تو سیستمهای توزیعشده (خصوصا دارای پراکندگی جغرافیایی و چند دیتاسنتری)، هماهنگی تغییرات میتونه باعث تأخیر بشه. یا وقتی از eventual consistency استفاده میکنیم، ممکنه یه تغییر جدید به کاربر نشان داده نشه چون اطلاعات هنوز بهروز نشدهاند. اینجاست که باید بین سرعت عملکرد و صحت دادهها تعادل برقرار کرد.
یه روش دیگه که خیلی جالب عمل میکنه، استفاده از خواندن مبتنی برQuorum-Based Reads With Vector Clocks هست. توی این روش، وقتی میخوایم یه داده رو بخونیم، از چند سرور درخواست میدیم و آخرین نسخه رو بر اساس زمانبندی منطقی انتخاب میکنیم. همچنین تکنیکهایی مثل read repair وجود دارن که وقتی میبینیم دادهها بهروز نیستن، بهطور خودکار اونها رو دوباره از دیتابیس اصلی میخونن و تازه میکنن. (برای این مورد باید پراکنده جغرافیایی وسیعی داشته باشیم تا توجیه پیدا کنه).
در نهایت، باید بگم که رسیدن به یه سیستم با Read Your Own Writes consistency توی مقیاس بزرگ نیازمند برنامهریزی دقیق و نظارت مداوم هست. نمونههای موفق توی دنیای واقعی مثل پلتفرمهای شبکههای اجتماعی، سایتهای تجارت الکترونیک و ابزارهای همکاری آنلاین ثابت کردن که با استفاده از این تکنیکها، میشه تجربه کاربری فوقالعادهای رو تضمین کرد. ولی برای سیستمهایی که مثلا توی یک کشور و حتی توی یک دیتاسنتر هستن اگر چالش RYW داشته باشیم، احتمالا و تکیه میکنم احتمالا یه مشکلی توی طراحی و پیادهسازی داریم...
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🔥2👏1
وقتی بحث طراحی REST API میاد وسط، خیلیا فقط به CRUD فکر میکنن و اینکه یه سری endpoint که دیتا میگیرن و کوئری پاسخ میدن. اینکه API کار کنه و خطا نده کافی نیست، اگر استاندارد نباشه مشکلاتی متعاقب خودش به بار میاره که مفصله. استانداردهای طراحی API کمک میکنن که APIها قابل پیشبینی، خوانا و سازگار باشن. برای همین هم REST APIهای اصولی، معمولاً از الگوهای استاندارد استفاده میکنن.
یکی از مشکلات رایج طراحی API، مدیریت و ارسال خطاهاست. خیلی از APIها به شکلهای مختلف خطا برمیگردونن؛ یکی JSON میده، یکی XML، یکی فقط یه متن ساده، و بعضیها هم فقط یه HTTP Status Code. اینجاست که RFC 7807 وارد میشه!
تعریف RFC 7807: استاندارد کردن جزئیات خطاها توی REST API
در حقیقت RFC 7807 استانداردیه که توش تعریف شده چطور APIها میتونن جزئیات خطاها (Problem Details) رو به صورت JSON یا XML برگردونن، بهجای این که هر کی واسه خودش یه فرمتی اختراع کنه. فرمت پیشنهادی این شکلیه:
{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"status": 403,
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/transactions/67890"
}الف: type: یه URL که نشون میده این نوع خطا چیه (میشه مستندات مربوطه رو اینجا گذاشت)
ب: title: یه توضیح کوتاه و ثابت دربارهی نوع خطا
پ: status: همون HTTP Status Code که برمیگرده
ت: detail: توضیح دقیقتر در مورد این خطای خاص
ث: instance: آدرسی که خطا در اون رخ داده
🔗 متن استاندارد
#API_Design
Please open Telegram to view this post
VIEW IN TELEGRAM
پسری را به کارگه کدنویسی همی بردندی تا شیوهی کُدگری پیشه کند، استاد بگفت: «بِکُد، سپس بِتِست!» شاگرد مدتی استاده، بُکید، خسته شد؛ لَختی درنگ کرد و از برای تستیدن پرسید:
«استاد رخصت میدهی تا با MSTest بِتِستَم؟»
استاد بدو گفت: «بِتِست!»
باز مدتی بِتِستید، خسته شد، گفت: «استاد، اجازت باشد تا این بار به NUnit بگرایم و بِتِستم؟»
استاد گفت: «بِتِست!»
باز مدتی بِتِستید، باز خسته شد، گفت: «استاد، دلم هوای XUnit کرده است، رخصت میدهی تا به آن بِتِستم؟»
استاد گفت: «بِتِست!»
دیگر نایی در تنش نمانده بود، گفت: «استاد! مرا زین همه آزمون، امان ده! باشد که آخرین بار به TUnit 🧪بِتِستم و آنگاه بیاسایم؟»
* بِتِست: فعل امر تست نوشتن
* بُکید: فعل ماضی کد نوشتن، سوم شخص مفرد
حالا اگر روی این موضوع توافق داریم، ولو به «تو بِتِست، بمیر و بِتِست!» و کنجاوید بدونید TUnit آیا یه قرطیبازی جدیده و یه بابایی آخر هفته بیکار بوده یه چیزی نوشته و چهار روز دیگه هم ولش میکنه، یا اینکه نه! یه نیازی بوده که با وجود MSTest و NUnit و XUnit یه لایبری تستنویسی جدید به وجود اومد؟!
اگر سواله، بگید تا بیشتر در موردش بگم و یه مقایسه با اون ۳ تا پیرمرد داشته باشم...
ریاکشن برای توضیح بیشتر:
Please open Telegram to view this post
VIEW IN TELEGRAM
این روزها تقریبا یکسالگی TUnit است. یه کتابخونه جدید برای نوشتن Unit، Integration، Acceptance و هر جور تست دیگهای توی داتنت. حدود ۱۹۱هزار دانلود NuGet داشته و توسعهاش فعلا خیلی فعاله و جزو گیتهاب ترند هست.
ولی چرا؟
خب میدونیم که NUnit عملا پورت شدهی JUnit جاوا است، و xUnit انشعابی بهبود یافته از NUnit.
خود NUnit که باقیمانده دوران SharpTestEx و Lin Unit و NUnitEx و NUnitAsp است که حتی ریپوهاشون هم هفت کفن پوسوندن، نزدیک به ۲۰ سال قدمت داره. درسته که همواره بهروز شده و پوستاندازی داشته و امروز یه محصول بالغه؛ ولی مدتهاست تغییرات بزرگی نداره و فقط باگ و بوگ (بوگ به مفهوم باگچه، و باگ کوچک است) برطرف میکنه. (تاریخچه JUnit هم برمیگرده به یه پرواز بین زوریخ و آتلانتا در سال ۱۹۹۷! و الان نسل پنجم خودش رو تجربه میکنه)
واقعیت اینه که دنیای تست از نظر مفهوم و ساختار تغییرات انقلابی خاصی نداشته. لذا این لایبریها هم فرصت داشتن تا بالغ و پایدار بشن.
چی شد که TUnit متولد شد؟
اون لکلکی که TUnit رو توی گیتهاب git push کرد، و خودش هم میگه از NUnit و xUnit الهام گرفته، چند تا هدف داشت:
- یکی کدبیس مدرن از ابتدا
- بهبود سرعت اجرای تست
دقت کنید که این داستان «هیچ ربطی» به تیمی که هنوز توی بدیهیات تستنویسی گیر کرده و کاوریجش ۳۰ درصده نداره! بلکه برای تیمیه که میخواد از یک کتابخونه برای همه نوع تستش استفاده کنه، هزاران تست داره و سرعت اجرای تستها میتونه تجربه توسعهدهنده و دواپس رو بهبود بده.
مثلا: TUnit از source generators تا جای امکان به جای reflection استفاده میکنه و AOT رو به خوبی پشتیبانی میکنه.
مثال دوم: کدبیس مدرنش به شما Hooks, Events روی کل Lifecycles تست میده؛ یعنی قبل و بعد از ،TestDiscover ،TestSession، Assembly، Class، Test. مثلا شما با ایونت مطلع میشید تست شروع شد، تست وارد فلان مرحله شد و... این هم به درد تستنویس میخوره هم بهدرد اون بدبختی که پایپلاین DevOps شما رو توسعه میده.
مثال سوم: از بیخ به شما اجازه پاس دادن انواع داده برای تست رو میده. این به معنای ناتوانی xUnit نیست، بلکه پیادهسازی راحتتر و مدرنتره. وقتی شما سرعت 321.7 میلیثانیه TUnit در مقابل ۱۴ ثانیه xUnit به کارتون میاد، که اولا «واقعنکی» (به معنی خیلی واقعی) تست مینویسید. دوم اینکه تعداد زیادی تست دارید و... البته این تفاوت زیاد، فقط در برخی موارد است چون TUnit قابلیت AOT دارد و در خیلی از موارد تفاوت حداقل هنوز اینقدرها نیست.
ولی این سرعت توسعه مداوم و یکپارچگی با IDEها وقابلیت Analyzer درونی اونم از ابتدای راه و اقبالی که جامعه داتنت بهش داشته، آینده خوبی براش رقم میزنه. خدا از من نگذره اگر ذرهای قصد «امروزه عصر، عصر توسعه تست با TUnit است» داشته باشم... 😅 ایهاالناس: شما «بِتِست، بمیر و بِتِست!»
ریپو
مستندات
ولی چرا؟
خب میدونیم که NUnit عملا پورت شدهی JUnit جاوا است، و xUnit انشعابی بهبود یافته از NUnit.
خود NUnit که باقیمانده دوران SharpTestEx و Lin Unit و NUnitEx و NUnitAsp است که حتی ریپوهاشون هم هفت کفن پوسوندن، نزدیک به ۲۰ سال قدمت داره. درسته که همواره بهروز شده و پوستاندازی داشته و امروز یه محصول بالغه؛ ولی مدتهاست تغییرات بزرگی نداره و فقط باگ و بوگ (بوگ به مفهوم باگچه، و باگ کوچک است) برطرف میکنه. (تاریخچه JUnit هم برمیگرده به یه پرواز بین زوریخ و آتلانتا در سال ۱۹۹۷! و الان نسل پنجم خودش رو تجربه میکنه)
واقعیت اینه که دنیای تست از نظر مفهوم و ساختار تغییرات انقلابی خاصی نداشته. لذا این لایبریها هم فرصت داشتن تا بالغ و پایدار بشن.
چی شد که TUnit متولد شد؟
اون لکلکی که TUnit رو توی گیتهاب git push کرد، و خودش هم میگه از NUnit و xUnit الهام گرفته، چند تا هدف داشت:
- یکی کدبیس مدرن از ابتدا
- بهبود سرعت اجرای تست
دقت کنید که این داستان «هیچ ربطی» به تیمی که هنوز توی بدیهیات تستنویسی گیر کرده و کاوریجش ۳۰ درصده نداره! بلکه برای تیمیه که میخواد از یک کتابخونه برای همه نوع تستش استفاده کنه، هزاران تست داره و سرعت اجرای تستها میتونه تجربه توسعهدهنده و دواپس رو بهبود بده.
مثلا: TUnit از source generators تا جای امکان به جای reflection استفاده میکنه و AOT رو به خوبی پشتیبانی میکنه.
مثال دوم: کدبیس مدرنش به شما Hooks, Events روی کل Lifecycles تست میده؛ یعنی قبل و بعد از ،TestDiscover ،TestSession، Assembly، Class، Test. مثلا شما با ایونت مطلع میشید تست شروع شد، تست وارد فلان مرحله شد و... این هم به درد تستنویس میخوره هم بهدرد اون بدبختی که پایپلاین DevOps شما رو توسعه میده.
مثال سوم: از بیخ به شما اجازه پاس دادن انواع داده برای تست رو میده. این به معنای ناتوانی xUnit نیست، بلکه پیادهسازی راحتتر و مدرنتره. وقتی شما سرعت 321.7 میلیثانیه TUnit در مقابل ۱۴ ثانیه xUnit به کارتون میاد، که اولا «واقعنکی» (به معنی خیلی واقعی) تست مینویسید. دوم اینکه تعداد زیادی تست دارید و... البته این تفاوت زیاد، فقط در برخی موارد است چون TUnit قابلیت AOT دارد و در خیلی از موارد تفاوت حداقل هنوز اینقدرها نیست.
ولی این سرعت توسعه مداوم و یکپارچگی با IDEها وقابلیت Analyzer درونی اونم از ابتدای راه و اقبالی که جامعه داتنت بهش داشته، آینده خوبی براش رقم میزنه. خدا از من نگذره اگر ذرهای قصد «امروزه عصر، عصر توسعه تست با TUnit است» داشته باشم... 😅 ایهاالناس: شما «بِتِست، بمیر و بِتِست!»
ریپو
مستندات
👍18 2
معنی idempotent : شاید بشه «همانندپذیر» رو معادل خوبی براش دونست؛ توی ریاضی «عدد ۱ در عملیات ضرب» همانندپذیر هست، چون هر چند بار که یک در خودش ضرب شه، باز هم ۱ به دست میاد. ولی ۲ اینطور نیست چون ۲ اگر در خودش ضرب شه میشه ۴.
پس idempotent عملیاتی هست که چندین بار اجرا کردنش، نتیجهای مشابه با یک بار اجرا کردنش داره.
یکی از دغدغههای اصلی توی سیستمهایی مثل پرداخت یا عملیات حساس، اینه که وقتی کاربر چندبار یک درخواست رو میفرسته، سیستمو نباید چندبار اون رو پردازش کنه. به بیان سادهتر، API ما باید idempotent باشه؛ یعنی خروجی و اثرش هر بار یکسان باشه، حتی اگر درخواست رو چند بار ارسال کنیم (حالا چه سهوی، چه تعمدی و با قصد بد!) مثلا کاربر اگر API پرداخت رو چند بار فراخوانی کنه ممکنه چند بار وجه از حسابش کسر بشه یا مواردی از این دست.
روشهای طراحی APIهای Idempotent
یکی از روشهای رایج برای حل این مشکل استفاده از یک کلید منحصر به فرد به نام Idempotency-Key است. وقتی کاربر یک درخواست حساس (مثلاً پرداخت) رو ارسال میکنه، یک کلید یکتا همراه درخواست ارسال میشه. سرور وقتی درخواست رو دریافت میکنه، اول چک میکنه که آیا قبلاً درخواستی با اون کلید دریافت شده یا نه.
POST /payments
Headers: {
"Idempotency-Key": "abc123"
}
Body: {
"amount": 1000,
"currency": "IRR"
}
استفاده از کنترل همزمانی خوشبینانه (Optimistic Concurrency Control). هر موجودیت (entity) یه نسخه یا شناسه تغییر (مثلاً ETag) داره. وقتی کاربر میخواد تغییراتی رو روی اون موجودیت اعمال کنه، نسخه موجودیت رو همراه درخواست میفرسته.
اگر نسخهای که فرستاده شده با نسخه فعلی مطابقت داشته باشه، تغییر اعمال میشه؛ در غیر این صورت، یعنی کسی یا چیزی قبلاً تغییر ایجاد کرده و سرور خطا برمیگردونه.
PUT /orders/123
Headers: {
"If-Match": "v1"
}
Body: {
"status": "paid"
}
از Conditional Requests میشه استفاده کرد، یعنی با استفاده از هدرهای HTTP مثل If-None-Match یا If-Modified-Since وقتی کاربر درخواست میده، سرور بررسی میکنه که آیا دادههای موجود تغییر کرده یا نه.
اگر داده تغییر نکرده باشه، سرور یک پاسخ مشابه برمیگردونه بدون اینکه دوباره عملیات رو انجام بده. مثلا: فرض کن کاربر میخواد اطلاعات پروفایل خودش رو آپدیت کنه. همراه درخواست هدر If-Unmodified-Since ارسال میشه که نشان دهنده آخرین باریه که اطلاعات تغییر کردهاند. اگر اطلاعات بین اون زمان تغییر نکرده باشه، عملیات به درستی انجام میشه؛ در غیر این صورت، سرور خطا میده که نشان میده اطلاعات بهروزرسانی نشده یا تغییر کرده.
#API_Design
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17 5
هر از گاهی توی فضای مجازی، حالا یا فضای عمومی، یا فضای فعالین اکوسیستم خاصی مثل نرمافزار، یه رفتار، یه صحبت، یا یه ویدیو تبدیل به یک موج میشه که خیلیها رو تبدیل میکنه به یک کارشناس هفتادپُشت متخصص که با نظرات قاطع، در جایگاه قاضی یا طنزپرداز یا منتقد چند روزی به اون فرد بپردازن، یا حتی وقتی به موضوع میپردازن، باز هم یک فرد رو محور صحبت قرار بدن.
شاید خیلی از ما ترجیح ندیم که ویدیو خیلی عمومی بسازیم و خودمون رو خواسته یا ناخواسته در معرض دید عموم قرار بدیم. ولی در مقیاس محدودتر امکان داره برای هر کدوم از ما پیش بیاد. امکان داره در یک گپ ۳ نفره توی شرکت یه سوتی سهوی بدیم؛ و احتمالا نمیپسندیم اون ۲ نفر حاضر در اون جمع کوچیک؛ ما رو دستمایه مسخره کردن یا قضاوتشون قرار بدن.
حالا بیایم این شرایط و فضا رو که کموبیش دیدهایم یه مقدار بشکافیم...
- خیلی از این بازخوردهای مجازی، جز تقویت خشم و هیجان فایده و یادگیری ندارن برامون. (حتی اگر خودمون متوجه نشیم، ناخواسته توی وجودمون خشم و هیجان و تعصب رو تقویت میکنن)
- خواستگاه تعداد زیادی از این بازخوردها، ولو اینکه خیلی موجه و منطقی به نظر بیان، باز هم خشم است!
- در قبال این شرایط چند تا مولفهی قابل ارزیابی وجود داره: یکیش اینه که آیا محوریت، یک «موضوع» است یا یک «مصداق». اگر دیدیم یه نفر میاد حول یک مصداق سخنان بسیار منطقی میگه یه جای کار میلنگه! اگر برای بیان موضوع، چیزی جز اون مصداق وجود نداره، اصلا موضوعیت نداره که بخوایم لابلای این همه موضوع خوب یا مهم در دنیا به اون بپردازیم. اگر موضوع رو میشه بدون مصداق خاص طرح کرد، که دلیلی برای پرداختن به مصداق نیست...
- هیچ اظهار نظری، اعم از یک نظر اشتباه، ناقص یا حتی مضحک در مورد یک تکنولوژی؛ یا یک شیوه صحبت کردن یا یک تُپُق یا... اینقدر ناموسی و مهم نیست... چرا فکر نکنیم یک نفر از ۸ میلیارد جمعیت زمین یه نظری داده! چقدر موثره مگه؟! اگر من اومدم اینجا در مورد API Design یا ... یه مزخرفی گفتم، شما برو تحقیق کن درستش رو یاد بگیر، یا درستش رو جایی بنویس...
- این روزها و سالها جامعه ما (و حتی جهان) اینقدر آکنده از خشم و تفرقه است که ای کاش ما سهمی حتی در حد یک لایک یا کامنت ولو بامزه، در این حجم از نجاست خشم و نفرت نداشته باشیم
🌱 نقد سازنده در هر موضوعی ۴ تا مولفهی «لاینفک» داره: ۱: پرداختن به موضوع به جای مصداق ۲: همراه داشتن راهحل منطقی ۳: پرهیز از تعصب و خشم و هیجان ۴: باور به حق آزاداندیشی، هر کسی آزاده تا هر باور و نظری داشته باشه، و در صورت ضرر به دیگران، قانون باید براش تصمیم بگیره و بس.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤4