<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Roham</title>
        <link>https://virgool.io/feed/@h.agharezaei</link>
        <description>پیدا کردن خودم توی نوشته ها برام جذابه بهم یه حس خوب بودن می ده مخصوصا وقتی با طعم علم و خلاقیت همراه باشه هر روز که بیشتر با این دنیا آشنا می شم حس بهتری برای بیشتر دونستن و یاد دادن درونم رشد می کنه</description>
        <language>fa</language>
        <pubDate>2026-06-15 23:03:49</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/55210/avatar/YNeF4e.png?height=120&amp;width=120</url>
            <title>Roham</title>
            <link>https://virgool.io/@h.agharezaei</link>
        </image>

                    <item>
                <title>به عنوان یک معمار نرم‌افزار، STRIDE را باید بشناسید</title>
                <link>https://virgool.io/@h.agharezaei/stride-j7a6kc6aqjdb</link>
                <description>وقتی صحبت از معماری نرم‌افزار می‌شود، بسیاری از ما به مقیاس‌پذیری، کارایی، قابلیت نگهداری و طراحی سیستم فکر می‌کنیم. اما یکی از مهم‌ترین مسئولیت‌های یک معمار، در نظر گرفتن امنیت از همان مراحل ابتدایی طراحی است.یکی از شناخته‌شده‌ترین چارچوب‌ها برای تحلیل تهدیدات امنیتی، STRIDE است. این مدل توسط مایکروسافت معرفی شده و به تیم‌های فنی کمک می‌کند تا تهدیدات احتمالی را پیش از پیاده‌سازی یا استقرار سیستم شناسایی کنند.کلمه STRIDE از حروف اول شش دسته تهدید امنیتی تشکیل شده است:S — Spoofing (جعل هویت)در این نوع حمله، مهاجم خود را به جای یک کاربر، سرویس یا سیستم معتبر جا می‌زند.نمونه‌ها:سرقت توکن‌های دسترسی (Access Token)استفاده از رمز عبور لو رفتهجعل هویت سرویس‌های داخلیراهکارها:احراز هویت چندمرحله‌ای (MFA)مدیریت صحیح توکن‌هااستفاده از مکانیزم‌های قوی احراز هویتT — Tampering (دستکاری داده)در این سناریو مهاجم تلاش می‌کند داده‌ها را بدون مجوز تغییر دهد.نمونه‌ها:تغییر اطلاعات ارسالی بین کلاینت و سروردستکاری داده‌های ذخیره‌شده در پایگاه دادهتغییر پیام‌های ارسال‌شده بین سرویس‌هاراهکارها:استفاده از HTTPSامضای دیجیتالکنترل یکپارچگی داده‌هاR — Repudiation (انکار عملیات)کاربر یا مهاجم پس از انجام یک عملیات، آن را انکار می‌کند و سیستم نیز مدرکی برای اثبات آن ندارد.نمونه‌ها:انکار انجام تراکنش مالیانکار حذف یا تغییر اطلاعاتراهکارها:ثبت لاگ‌های دقیقAudit Trailامضای دیجیتال عملیات حساسI — Information Disclosure (افشای اطلاعات)در این حالت اطلاعاتی که باید محرمانه باشند در اختیار افراد غیرمجاز قرار می‌گیرند.نمونه‌ها:نشت اطلاعات کاربرانافشای اطلاعات کارت بانکینمایش Stack Trace در محیط Productionراهکارها:رمزنگاری داده‌هاکنترل دسترسی مناسبحذف اطلاعات حساس از لاگ‌هاD — Denial of Service (از دسترس خارج کردن سرویس)هدف مهاجم مصرف منابع سیستم و جلوگیری از ارائه سرویس به کاربران واقعی است.نمونه‌ها:حملات DDoSارسال تعداد زیادی درخواست به APIمصرف بیش از حد منابع پردازشی یا دیتابیسراهکارها:Rate LimitingLoad Balancingاستفاده از CDN و WAFE — Elevation of Privilege (افزایش سطح دسترسی)مهاجم موفق می‌شود دسترسی‌هایی بیشتر از سطح مجاز خود به دست آورد.نمونه‌ها:تبدیل یک کاربر عادی به مدیر سیستمدسترسی به منابعی که نباید قابل مشاهده باشندراهکارها:اصل حداقل دسترسی (Least Privilege)کنترل دسترسی مبتنی بر نقش (RBAC)بازبینی مداوم مجوزهاچرا STRIDE برای معماران مهم است؟بسیاری از آسیب‌پذیری‌های امنیتی نه در مرحله توسعه، بلکه در مرحله طراحی سیستم ایجاد می‌شوند. اگر در جلسات طراحی معماری، برای هر کامپوننت و هر جریان داده، شش سؤال زیر را مطرح کنید، بخش بزرگی از ریسک‌های امنیتی را قبل از تولید محصول شناسایی خواهید کرد:آیا امکان جعل هویت وجود دارد؟آیا داده‌ها قابل دستکاری هستند؟آیا امکان انکار عملیات وجود دارد؟آیا اطلاعات محرمانه افشا می‌شوند؟آیا سرویس قابل از دسترس خارج شدن است؟آیا امکان افزایش سطح دسترسی وجود دارد؟STRIDE یک چک‌لیست ساده نیست؛ بلکه یک طرز فکر امنیتی است که به شما کمک می‌کند امنیت را از روز اول وارد معماری سیستم کنید، نه اینکه پس از وقوع حادثه به دنبال رفع مشکل باشید.امنیت چیزی نیست که بعداً به سیستم اضافه شود؛ امنیت باید بخشی از طراحی باشد.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Wed, 10 Jun 2026 21:47:47 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی رسمی Go 1.26 — نسخه جدید زبان Go منتشر شد</title>
                <link>https://virgool.io/@h.agharezaei/go-1-26-evcx7mhaha8h</link>
                <description>Go 1.26تیم توسعه زبان Go در فوریه ۲۰۲۶ نسخه‌ی Go 1.26 را به‌طور رسمی منتشر کرد — نسخه‌ای که با تمرکز بر بهبود عملکرد، امنیت بیشتر، ابزارهای مدرن و گسترش استاندارد لایبرری عرضه شده است. نسخه‌ی جدید همچنان تعهد کامل به سازگاری Go 1 را حفظ می‌کند، به‌گونه‌ای که تقریباً تمام برنامه‌های Go موجود بدون تغییر قابل اجرای مجدد خواهند بود.تغییرات در زبان (Language Changes)نسخه ۱.۲۶ دو تغییر مهم در سطح زبان ارائه می‌دهد که کدنویسی را ساده‌تر و قدرتمندتر می‌کند:۱. تابع new با پشتیبانی از عبارت (Expression)در Go 1.26، تابع داخلی new دیگر فقط نوع را قبول نمی‌کند — بلکه می‌تواند عبارات را به‌عنوان آرگومان بپذیرد تا مقدار اولیه را نیز تعیین کند. این ویژگی مخصوصاً زمانی مفید است که بخواهیم به‌صورت مستقیم اشاره‌گر به مقداری را ایجاد کنیم (مثلاً در هنگام سریال‌سازی JSON یا پروتکل‌بافرها).ptr := new(int64(300))این قابلیت کد را کوتاه‌تر و خواناتر می‌کند و نیاز به توابع کمکی شخصی‌سازی‌شده را کاهش می‌دهد.۲. پشتیبانی از Type Parameterهای بازگشتی به خود نوع (Self-Referencing Generics)قیدهای نوع (type constraints) اکنون می‌توانند به‌طور مستقیم به نوع اصلی اشاره کنند — چیزی که پیش‌تر مجاز نبود. این امکان باعث ایجاد الگوهای پیچیده‌تر و ایمن‌تر برای داده‌های Generic می‌شود.بهبود در ابزارها (Tooling Changes)نسخه جدید ابزارهای توسعه Go نیز بهبود یافته‌اند:بازنویسی کامل go fixابزار go fix که برای اصلاح خودکار کد استفاده می‌شود، بازنویسی شده تا از چارچوب تحلیل Go بهره ببرد. اکنون شامل تعدادی modernizer است که به‌طور خودکار کدهای قدیمی را به الگوهای جدیدتر تبدیل می‌کند بدون اینکه رفتار برنامه تغییر کند.تغییر رفتار go mod initحالا وقتی ماژول جدیدی با نسخه Go 1.N.X ایجاد می‌شود، مقدار پیش‌فرض نسخه در go.mod به پایین‌ترین نسخه‌ی پشتیبانی‌شده کاهش پیدا می‌کند (برای تشویق به سازگاری بیشتر). برای مثال، ابزار نسخه ۱.۲۶، مقدار پیش‌فرض را به ۱.۲۵.۰ تنظیم می‌کند.حذف go tool docابزار go tool doc حذف شده و go doc می‌تواند به‌عنوان جایگزین کامل آن استفاده شود.runtime &amp; performance – بهینه‌سازی‌های کلیدیGo 1.26 روی عملکرد و کارایی نیز تمرکز ویژه‌ای داشته است:Green Tea Garbage Collector به‌طور پیش‌فرض فعال شداین جمع‌کننده زباله جدید که در نسخه قبلی به‌صورت آزمایشی ارائه شده بود، حالا به‌طور پیش‌فرض فعال است. هدف آن کاهش زمان صرف‌شده در GC و بهبود محلی‌سازی حافظه و مقیاس‌پذیری روی CPU است که در بسیاری از برنامه‌ها منجر به کاهش ۱۰ الی ۴۰٪ هزینه GC می‌شود.کاهش ۳۰٪ در سربار cgoتماس‌های cgo که به‌طور معمول در برنامه‌های Go که از کد C استفاده می‌کنند اتفاق می‌افتد، اکنون سریع‌تر اجرا می‌شوند.تصادفی‌سازی آدرس Heapبرای افزایش امنیت حافظه، آدرس پایه Heap در زمان اجرای برنامه روی معماری‌های ۶۴ بیت به‌صورت تصادفی انتخاب می‌شود؛ این ویژگی به کاهش احتمال حملات حافظه کمک می‌کند.پروفایل نشت Goroutines (Experimental)یک نوع پروفایل جدید جهت شناسایی Goroutineهای نشت‌یافته در حالت آزمایشی وجود دارد که می‌تواند در ابزارهای تحلیل عملکرد مفید باشد.استاندارد لایبرری – چیزهای جدیدنسخه ۱.۲۶ همچنین شامل به‌روزرسانی‌های متعدد در کتابخانه استاندارد است، از جمله:بسته جدید crypto/hpkeپیاده‌سازی Hybrid Public Key Encryption مطابق با استاندارد RFC 9180 که از روش‌های ترکیبی پیش‌کوآنتومی نیز پشتیبانی می‌کند.بسته‌های experimental simd/archsimd و runtime/secretاین بسته‌ها به ترتیب برای عملیات SIMD (برداری) و پاک‌سازی امن حافظه‌ی حساس طراحی شده‌اند و فعلاً در حالت آزمایشی قرار دارند.تغییرات جزئی در دیگر بسته‌هااز جمله اضافه شدن متد Buffer.Peek در bytes، بهبود عملکرد io.ReadAll، بهبود API در crypto، و متدهای جدید در reflect که گردش روی فیلدها و متدها را ساده‌تر می‌کند.راهنمای مهاجرت از Go 1.25 به Go 1.26خبر خوب این است که Go همچنان Backward Compatible باقی مانده است.اما در پروژه‌های Production بهتر است این مراحل را انجام دهید:به‌روزرسانی نسخه Gogo version
# بررسی نسخه فعلی

# نصب نسخه جدید
# از طریق package manager یا دانلود مستقیم از go.devسپس در پروژه:go mod tidy
go mod verifyبررسی مقدار نسخه در go.modدر Go 1.26 رفتار go mod init کمی تغییر کرده و نسخه پیش‌فرض پایین‌تر تنظیم می‌شود.پیشنهاد:اگر پروژه Production است، نسخه را به صورت صریح تنظیم کنید:go 1.26اجرای تست‌ها با GC جدیددر 1.26، Garbage Collector جدید به صورت پیش‌فرض فعال است.قبل از انتشار:go test ./... -bench=.و در صورت نیاز مقایسه با نسخه قبلی:GODEBUG=gogc=off go test -bench=.بررسی کدهایی که از cgo استفاده می‌کننداگر پروژه شما از C bindings استفاده می‌کند (مثلاً OpenSSL یا کتابخانه‌های Native):عملکرد بهبود یافتهولی بهتر است تست‌های Load و Integration مجدد اجرا شوداستفاده از go fix جدیدgo fix ./...نسخه جدید می‌تواند الگوهای قدیمی‌تر را به کد مدرن تبدیل کند.بنچمارکدر تست‌های عمومی روی سرویس‌های HTTP و پردازش JSON، نتایج تقریبی به شکل زیر بوده است:بنچمارکتاثیر GC جدید در سیستم‌های واقعیدر سیستم‌های High Concurrency مثل:API GatewayMicroservices با Load بالاMessage Processing (Kafka Consumers)Real-time systemsکاهش زمان GC Pause باعث:Latency کمترThroughput بالاترمصرف CPU پایدارترمی‌شود.اگر شما روی Exchange، FinTech یا سرویس‌های Streaming کار می‌کنید، این نسخه ارزش بررسی جدی دارد.بهبودهای امنیتی مهمHeap Randomization → کاهش احتمال Exploitcrypto/hpke → آماده برای استانداردهای رمزنگاری مدرنruntime/secret → پاک‌سازی امن داده‌های حساسبرای سیستم‌های مالی یا احراز هویت، این بخش اهمیت بالایی دارد.آیا باید فوراً آپگرید کنیم؟آپگرید فوری توصیه می‌شود اگر:سیستم High Load داریداز cgo استفاده می‌کنیدPerformance-sensitive هستیدبه بهبودهای امنیتی نیاز داریدمی‌توانید صبر کنید اگر:پروژه Stable و بدون فشار Performance استRelease بحرانی در حال اجرا داریدجمع‌بندی نهاییGo 1.26 یک نسخه معمولی نیست —این نسخه تمرکز جدی روی Performance + Security + Modern Tooling دارد.مهم‌ترین نکات:GC جدید فعال به صورت پیش‌فرضکاهش محسوس هزینه cgoبهبود ابزار go fixتوسعه crypto استانداردامنیت حافظه بهتراگر در سال 2026 با Go کار می‌کنید، این نسخه پایه‌ی قدرتمندتری برای سیستم‌های مقیاس‌پذیر فراهم می‌کند.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Thu, 12 Feb 2026 09:51:50 +0330</pubDate>
            </item>
                    <item>
                <title>فقط یک زندگی معمولی</title>
                <link>https://virgool.io/@h.agharezaei/%D9%81%D9%82%D8%B7-%DB%8C%DA%A9-%D8%B2%D9%86%D8%AF%DA%AF%DB%8C-%D9%85%D8%B9%D9%85%D9%88%D9%84%DB%8C-i7owmhghvmgk</link>
                <description>این چند وقت خیلی اوضاع روحی مناسبی نداشتم و هنوز هم به این شرایط عادت نکردمیه خورده نوشتن برام سخته، فقط دنبال یک زندگی معمولی ام که هر صبح که از خواب بلند میشم دغدغم چک کردن خبر در مورد همه چیز نباشه، همیشه دوست داشتم که  بتونم هر روز بهتر از روز های قبل باشم اما الان فقط  دارم تمام تلاشم رو می کنم که از دیروزم عقب نیوفتمخیلی سخته اما تا شقایق هست زندگی باید کردسعی می کنم اگه بشه سری مقالات میکروسرویس رو ادامه بدم</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Sun, 18 Jan 2026 10:26:00 +0330</pubDate>
            </item>
                    <item>
                <title>چه زمانی باید Microservices را انتخاب کنیم؟</title>
                <link>https://virgool.io/@h.agharezaei/software-architecture-cm3qgtqcwkih</link>
                <description>MicroservicesMicroservices معمولاً به‌عنوان «معماری مقیاس‌پذیر و حرفه‌ای» معرفی می‌شود،اما واقعیت این است که بیشتر شکست‌های معماری نه به‌خاطر ضعف تکنولوژی،بلکه به‌خاطر انتخاب اشتباه در زمان اشتباه رخ می‌دهند.بسیاری از تیم‌ها:قبل از داشتن کاربر واقعیقبل از شناخت دقیق دامنهقبل از بلوغ تیمبه سمت Microservices می‌روند و بعد از مدتی متوجه می‌شوند که:سرعت توسعه کاهش یافته، هزینه‌ها افزایش پیدا کرده و Debug کردن تبدیل به کابوس شده است.هدف این مقاله این است که ذهن شما را قبل از تصمیم معماری، بالغ کند.۱. معیارهای تصمیم‌گیری برای انتخاب Microservices۱.۱ پیچیدگی واقعی دامنه (Real Domain Complexity)اولین و مهم‌ترین سوال:آیا دامنه سیستم شما واقعاً پیچیده است؟پیچیدگی واقعی یعنی:قوانین تجاری زیاد و متغیرتعامل چند زیرسیستم مستقلنیاز به مدل‌سازی دقیق مفاهیممثال دامنه پیچیده:سیستم بانکیکیف پول دیجیتالسیستم حسابداریپلتفرم مارکت‌پلیسدر این سیستم‌ها:هر بخش منطق خاص خودش را داردتغییر یک بخش نباید کل سیستم را تحت تأثیر قرار دهددر مقابل، دامنه ساده:سیستم‌های CRUD محورپنل‌های مدیریتی سادهوب‌سایت‌های محتواییدر این حالت:Microservices نه‌تنها کمک نمی‌کند، بلکه پیچیدگی غیرضروری وارد سیستم می‌کند.۱.۲ نرخ تغییرات بیزینسی (Change Frequency)یکی از مزایای واقعی Microservices:امکان تغییر مستقل بخش‌های مختلف سیستماما این مزیت فقط زمانی ارزش دارد که:بخش‌های مختلف محصول با سرعت‌های متفاوت تغییر کنندتیم‌ها نیاز به Deploy مستقل داشته باشنداگر:کل سیستم تقریباً با هم تغییر می‌کندReleaseها همزمان هستندMicroservices عملاً هیچ مزیتی ایجاد نمی‌کند.۲. تیم توسعه؛ عامل تعیین‌کننده (نه تکنولوژی)۲.۱ اندازه تیمMicroservices بدون تقسیم مسئولیت، معنا ندارد.تجربه عملی نشان می‌دهد:تیم‌های کوچک نمی‌توانند هزینه ذهنی و عملی Microservices را تحمل کنندحداقل نیازها:Backend DeveloperDevOps / Platform EngineerMonitoring &amp; Observabilityاگر یک یا دو نفر قرار است:هم کدنویسی کنندهم زیرساخت را مدیریت کنندهم دیباگ توزیع‌شده انجام دهند Microservices انتخاب اشتباهی است.۲.۲ بلوغ فنی تیمدانستن REST یا Docker کافی نیست.تیم باید درک عمیق داشته باشد از:Distributed SystemsNetwork FailureEventual ConsistencyTimeout, Retry, Circuit BreakerMicroservices یعنی:Failure یک اتفاق طبیعی است، نه استثنااگر تیم هنوز به این نگاه نرسیده:سیستم شکننده می‌شودمشکلات به‌صورت زنجیره‌ای گسترش پیدا می‌کنند۳. مقیاس؛ واقعیت یا توهم؟۳.۱ Scalability واقعی یعنی چه؟بسیاری تصور می‌کنند:Microservices = Scaleاما سوال درست این است:کدام بخش سیستم؟چه زمانی؟به چه میزان؟در بسیاری از سیستم‌ها:فقط یک بخش پرترافیک است (مثلاً جستجو یا پرداخت)اما کل سیستم Microservice می‌شوددر حالی که:Monolith هم می‌تواند Scale شودVertical Scaling و Caching هنوز بسیار قدرتمند هستند۳.۲ هزینه Scale زودهنگامScale زودهنگام یعنی:هزینه بیشترپیچیدگی بیشتربدون بازگشت سرمایهقانون معروف:Premature optimization is the root of all evilMicroservices یکی از گران‌ترین شکل‌های Optimization است.۴. هزینه‌های پنهان Microservices (جایی که اکثر تیم‌ها ضربه می‌خورند)۴.۱ هزینه عملیاتی (Operational Cost)با Microservices وارد دنیایی می‌شوید که شامل:CI/CD پیچیدهEnvironmentهای متعددMonitoring متمرکزLog AggregationAlerting هوشمنداین‌ها اختیاری نیستند.۴.۲ پیچیدگی Debug و توسعهدر Monolith:Stack Trace واضح استFlow مشخص استدر Microservices:درخواست از چند سرویس عبور می‌کندهرکدام ممکن است Fail شوندDebug بدون Tracing تقریباً غیرممکن است۵. مثال‌های شکست واقعی (بر اساس تجربه صنعت)مثال ۱: Microservices بدون Observabilityلاگ‌ها جداTrace وجود نداردErrorها غیرقابل ردیابینتیجه:سیستم از نظر ظاهری زنده است، اما عملاً غیرقابل مدیریتمثال ۲: Distributed Monolithسرویس‌ها جدادیتابیس مشترکDeploy هماهنگاین معماری:بیشترین هزینهکمترین مزیت۶. Decision Matrix دقیق‌تر (راهنمای تصمیم)Decision Matrixجمع‌بندی نهاییMicroservices:یک انتخاب استراتژیک استنه یک Trendنه یک Silver Bulletاگر:دامنه پیچیده استتیم بالغ استمحصول به ثبات نسبی رسیدهMicroservices می‌تواند یک مزیت رقابتی واقعی باشد.در غیر این صورت:ساده‌ترین راه، اغلب بهترین راه است.در مقاله بعدی (مقاله ۵)، وارد اصول طراحی Microservices می‌شویم؛جایی که اگر اشتباه کنیم، حتی بهترین تصمیم معماری هم شکست می‌خورد.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 02 Jan 2026 08:45:19 +0330</pubDate>
            </item>
                    <item>
                <title>Microservices چیست؟</title>
                <link>https://virgool.io/@h.agharezaei/microservices-architecture-eqhy5zzk1feq</link>
                <description>MicroservicesMicroservices یکی از بیشترین بدفهمی‌ها را در دنیای معماری نرم‌افزار دارد.برای بعضی‌ها:Microservices یعنی «خیلی مدرن»برای بعضی یعنی «Kubernetes + Docker»برای بعضی یعنی «هر API یک سرویس»اما واقعیت این است که بیش از ۶۰٪ پروژه‌هایی که با نام Microservices شروع می‌شوند، یا شکست می‌خورند یا به Distributed Monolith تبدیل می‌شوند.دلیل اصلی؟ تعریف اشتباه Microservices.در این مقاله قرار نیست Microservices را تبلیغ کنیم؛ قرار است دقیق، فنی و بدون اغراق آن را تعریف کنیم.Microservices چیست؟ Microservices یک سبک معماری نرم‌افزار است که در آن:سیستم به مجموعه‌ای از سرویس‌های مستقل تقسیم می‌شودکه هر سرویس مسئول پیاده‌سازی یک قابلیت مشخص از کسب‌وکار (Business Capability) استو می‌تواند به‌صورت مستقل توسعه، تست، دیپلوی و مقیاس‌دهی شود.این تعریف چند نکته‌ی بسیار مهم دارد که معمولاً نادیده گرفته می‌شوند:1. تمرکز روی Business CapabilityMicroservice بر اساس نیاز بیزینس شکل می‌گیرد، نه بر اساس:EntityTableControllerAPIمثلاً:«پرداخت»«ثبت سفارش»«مدیریت موجودی»«احراز هویت کاربر»نه:PaymentControllerOrderTableUserAPI2. استقلال واقعی، نه ظاهریاستقلال یعنی:وابستگی مستقیم به دیتابیس سرویس دیگر نداردبدون دیپلوی بقیه سرویس‌ها می‌تواند تغییر کندخرابی آن، کل سیستم را Down نمی‌کنداگر سرویس‌هایت بدون هم زنده نیستند، Microservice نیستند.3. ارتباط از طریق شبکهدر Microservices:فراخوانی‌ها Local Method Call نیستهمه چیز از طریق Network Call انجام می‌شودLatency، Timeout، Retry و Failure بخشی از واقعیت سیستم هستندبه همین دلیل:Microservices ذاتاً پیچیده‌تر از Monolith است.Microservices چه چیزی نیست؟ بخش بزرگی از پروژه‌های شکست‌خورده، دقیقاً از اینجا شروع می‌شوند. Microservices مخالف API زیادداشتن API زیاد هیچ ربطی به Microservices ندارد.اگر:همه APIها در یک Repository هستندهمه با هم Build می‌شوندهمه به یک دیتابیس وصل‌اندیک تغییر کوچک نیاز به دیپلوی کل سیستم دارد این Monolith است، حتی اگر اسمش Microservices باشد. Microservices مخالف RESTREST فقط یک روش ارتباط است، نه تعریف معماری.در دنیای واقعی Microservices:بعضی سرویس‌ها REST دارندبعضی فقط Event تولید می‌کنندبعضی فقط Message مصرف می‌کنندبعضی اصلاً API عمومی ندارند  Microservices مخالف KubernetesKubernetes یک ابزار Orchestration است.Microservices بدون Kubernetes هم ممکن استKubernetes بدون Microservices هم بسیار رایج استابزار ≠ معماریتفاوت عمیق Microservices و MonolithMonolith چگونه فکر می‌کند؟یک سیستمیک تیمیک دیتابیسیک دیپلویتغییر کوچک = ریسک بزرگMicroservices چگونه فکر می‌کند؟چند سیستم کوچکتیم‌های مستقلدیتابیس‌های مستقلدیپلوی مستقلتغییر کوچک = محدوده‌ی کنترل‌شدهاما با یک واقعیت مهم:Microservices مشکل طراحی بد را حل نمی‌کند فقط آن را پخش می‌کند.مثال واقعی: سیستم فروش آنلاین فرض کن یک فروشگاه آنلاین داریم با این نیازها:کاربران ثبت‌نام می‌کنندمحصولات را می‌بینندسفارش ثبت می‌کنندپرداخت انجام می‌دهندمعماری Monolithدر Monolith:همه ماژول‌ها داخل یک اپلیکیشن هستندOrder مستقیم Payment را صدا می‌زندProduct موجودی را Sync آپدیت می‌کندهمه چیز به یک دیتابیس وصل استمشکل کجاست؟تغییر در Payment باعث ریسک کل سیستممقیاس Order باعث مقیاس کل سیستمباگ در Payment  باعث Down شدن فروشمعماری Microservicesدر Microservices:Order Serviceفقط مسئول ثبت و مدیریت سفارشPayment Serviceفقط مسئول پرداختProduct Serviceفقط مسئول موجودی و قیمتUser Serviceفقط اطلاعات کاربرارتباط:Order یک Event ثبت می‌کندPayment آن را مصرف می‌کندبعد از پرداخت موفق، Event منتشر می‌شودOrder وضعیت را به Paid تغییر می‌دهدهیچ سرویس:دیتابیس دیگری را نمی‌بیندفرض نمی‌کند سرویس دیگر همیشه سالم استMicroservice ≠ REST API فرض کن Payment Service:API عمومی نداردفقط Event OrderCreated را گوش می‌دهدبعد از پرداخت Event PaymentCompleted منتشر می‌کنداین:کاملاً Microservice استحتی بدون RESTچرا تعریف درست Microservices حیاتی است؟چون انتخاب اشتباه:هزینه زیرساخت را چند برابر می‌کندنیاز به DevOps قوی داردDebug را سخت می‌کندنیاز به Monitoring حرفه‌ای داردMicroservices برای:تیم بالغمحصول در حال رشدنیاز واقعی به Scaleپیچیدگی بیزینس بالاطراحی شده است.جمع‌بندی نهاییMicroservices یک سبک معماری بالغ استمناسب همه پروژه‌ها نیستپیچیدگی را حذف نمی‌کند، مدیریت می‌کندبدون نیاز واقعی، خطرناک استو دقیقاً به همین دلیل، در مقاله بعدی بررسی می‌کنیم:چه زمانی باید Microservices را انتخاب کنیم و چه زمانی نه؟</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 26 Dec 2025 18:51:06 +0330</pubDate>
            </item>
                    <item>
                <title>Monolith چیست و چرا هنوز استفاده می‌شود؟</title>
                <link>https://virgool.io/@h.agharezaei/software-architecture-monolithic-osulvaw6ibet</link>
                <description>Software Architecture  Monolithدر دنیای توسعه نرم‌افزار، واژه‌ی Monolith معمولاً با بار منفی استفاده می‌شود؛انگار هر سیستمی که Monolithic باشد «قدیمی»، «بد»، یا «غیرقابل‌توسعه» است.اما واقعیت این است که:بخش بزرگی از سیستم‌های موفق دنیا هنوز Monolithic هستند و به دلایل منطقی از آن استفاده می‌کنند.Monolith یک معماری ساده، عملی و قابل‌اعتماد برای بسیاری از پروژه‌هاست، به شرطی که در زمان و مقیاس مناسب استفاده شود.در این مقاله،  بررسی می‌کنیم:Monolithic Architecture دقیقاً چیست؟چرا هنوز استفاده می‌شود؟چه مزایا و معایبی دارد؟چه زمانی بهترین انتخاب است؟Monolithic Architecture چیست؟معماری Monolithic به سیستمی گفته می‌شود که:کل اپلیکیشن به‌صورت یک واحد یکپارچه (Single Deployable Unit) ساخته می‌شود.تمام ماژول‌ها شامل Business Logic، API، Authentication، UI، Data Access در یک کدبیس و یک فرآیند اجرایی قرار دارند.معمولاً از یک دیتابیس مشترک استفاده می‌کند.تعریف ساده:Monolith یعنی همه‌چیز با هم است، با هم بیلد می‌شود و با هم دیپلوی می‌شود.مثال ملموس:فرض کنید یک اپلیکیشن سفارش آنلاین داریم:کاربر سفارش ثبت می‌کندسیستم موجودی را بررسی می‌کندپرداخت را انجام می‌دهدایمیل تأیید ارسال می‌کنددر معماری Monolith، همه این مراحل در یک اپلیکیشن اجرا می‌شوند و در یک سرور یا کانتینر دیپلوی می‌شوند.ساختار معمول یک Monolithیک Monolith معمولاً شامل لایه‌های زیر است:Presentation Layer (UI / API)جایی که درخواست کاربر دریافت و پاسخ داده می‌شود.Business Logic Layerقوانین کسب‌وکار و فرآیندهای اصلی سیستم.Data Access Layerارتباط با دیتابیس و مدیریت داده‌ها.Databaseمعمولاً یک دیتابیس واحد برای همه بخش‌ها. این ساختار غلط نیست و سال‌ها استاندارد صنعت بوده است. بسیاری از پروژه‌های موفق، ده‌ها سال با همین مدل کار کرده‌اند.مزایای Monolithic Architecture1. سادگی در توسعهیک کدبیس، یک Repositoryتوسعه‌دهنده جدید به سرعت می‌تواند پروژه را درک کندDependency Management ساده استبرای تیم‌های کوچک، این سادگی یک مزیت بزرگ است و باعث می‌شود MVP یا محصولات اولیه سریع‌تر آماده شوند.2. دیپلوی آسانتنها یک واحد قابل دیپلویبدون نیاز به هماهنگی بین سرویس‌هابدون نیاز به Service Discovery یا Message Brokerساده برای Rollback در صورت بروز خطا برای پروژه‌های کوچک یا MVP، این ساده‌ترین و کم‌هزینه‌ترین راه است.3. دیباگ و تست ساده‌ترتمام ماژول‌ها در یک پروسهTrace یک درخواست از ابتدا تا انتها ساده استلاگ‌ها یکجا هستندتست‌های Integration آسان‌ترمثلاً اگر کاربر یک سفارش ثبت کند، بررسی مسیر درخواست از UI تا DB در یک پروسه امکان‌پذیر است، بدون نیاز به ردیابی بین سرویس‌های مختلف.4. Performance بهتر در مقیاس کوچکفراخوانی داخلی تابع = بسیار سریع‌تر از شبکهبدون Serialization / Deserializationمناسب برای سیستم‌هایی با کاربران کم تا متوسطمعایب Monolithic Architecture1. Coupling بالابخش‌های مختلف به هم وابسته‌اندتغییر در یک بخش می‌تواند باعث بروز مشکل در بخش‌های دیگر شودDeploy یک Feature کوچک → Deploy کل سیستم2. Scalability محدودنمی‌توان تنها یک بخش پر مصرف را Scale کردمجبور به Scale کل سیستمهزینه‌ی زیرساخت بالا می‌رود3. توسعه تیمی سخت‌ترConflict در کد در تیم‌های بزرگوابستگی شدید بین تیم‌هاRelease Cycle کند4. ریسک بالا در تغییراتیک باگ کوچک می‌تواند کل سیستم را Down کندRollback سخت‌ترتوسعه Feature جدید ممکن است باعث خطا در Featureهای دیگر شودچه زمانی Monolith بهترین انتخاب است؟Monolith انتخاب خوبی است اگر: تیم کوچک (۱ تا ۵ نفر) محصول در مراحل اولیه (MVP) عدم قطعیت بالا در نیازمندی‌ها تمرکز روی سرعت توسعه منابع محدود DevOps در این شرایط، Microservice معمولاً Over Engineering است و پیچیدگی اضافه ایجاد می‌کند.مثال واقعی: یک استارتاپ کوچکفرض کنید یک استارتاپ دارید با این ویژگی‌ها:سیستم سفارش‌گیریپرداخت آنلاینپنل ادمین سادهروزانه حدود ۱۰۰۰ کاربرمزیت‌های Monolith در این سناریو:توسعه سریع و کم هزینهآسان برای تست و دیباگنیاز کمتر به زیرساخت‌های پیچیده بسیاری از استارتاپ‌های موفق، با Monolith شروع کرده‌اند و بعد از رشد، بخش‌های ضروری را به Microservices تبدیل کرده‌اند.نکته مهم Monolith ≠ Bad Architecture Microservice ≠ Good Architecture انتخاب معماری باید بر اساس شرایط، تیم و محصول باشد، نه ترند بازار.جمع‌بندیMonolithic Architecture هنوز زنده و کاربردی است و در بسیاری از پروژه‌ها بهترین انتخاب ممکن است.مشکل از Monolith نیست؛ مشکل زمانی شروع می‌شود که:سیستم بزرگ شده ولی معماری بدون بازنگری باقی مانده است.مقاله بعدی در این سریMicroservices چیست؟تفاوت واقعی با Monolith را دقیق و فنی بررسی می‌کنیم.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 19 Dec 2025 13:46:52 +0330</pubDate>
            </item>
                    <item>
                <title>معماری نرم‌افزار چیست و چرا اهمیت دارد؟</title>
                <link>https://virgool.io/@h.agharezaei/software-architecture-hej802sgzuzy</link>
                <description>معماری نرم‌افزار چیستوقتی صحبت از ساخت نرم‌افزار می‌شود، اغلب تمرکز ما روی زبان برنامه‌نویسی، فریم‌ورک یا دیتابیس است. اما تجربه نشان داده است که بزرگ‌ترین عامل موفقیت یا شکست یک سیستم نرم‌افزاری، معماری آن است، نه ابزارهایی که در آن استفاده می‌کنیم.در این مقاله، به‌عنوان اولین قدم از سری مقالات معماری Microservices، ابتدا باید به یک سؤال اساسی پاسخ دهیم:معماری نرم‌افزار چیست و چرا باید از همان روزهای اول به آن فکر کنیم؟معماری نرم‌افزار چیست؟معماری نرم‌افزار (Software Architecture) مجموعه‌ای از تصمیمات کلان درباره ساختار سیستم است؛ تصمیماتی که تعیین می‌کنند:سیستم از چه اجزایی تشکیل شده استاین اجزا چگونه با هم ارتباط دارندهر بخش چه مسئولیتی داردسیستم چگونه توسعه، نگهداری و مقیاس‌پذیر می‌شودبه‌صورت ساده‌تر:معماری نرم‌افزار، اسکلت اصلی سیستم است؛ چیزی که تغییر آن بعد از بزرگ شدن پروژه، بسیار پرهزینه و گاهی غیرممکن است.تفاوت Architecture و Designیکی از اشتباهات رایج، یکی دانستن Architecture و Design است.تفاوت Architecture و Design معماری، مسیر را مشخص می‌کند؛ طراحی، جزئیات حرکت در این مسیر را.چرا معماری اهمیت دارد؟شاید در پروژه‌های کوچک، اهمیت معماری چندان به چشم نیاید، اما با رشد سیستم، مشکلات معماری خودشان را نشان می‌دهند.مشکلات سیستم‌هایی با معماری ضعیف:توسعه هر فیچر جدید سخت‌تر می‌شوددیپلوی سیستم ریسک بالایی داردتغییر یک بخش، بخش‌های دیگر را می‌شکندتیم توسعه دچار اصطکاک می‌شودسیستم به‌سختی مقیاس‌پذیر استدر مقابل، یک معماری مناسب باعث می‌شود:توسعه سریع‌تر و امن‌تر انجام شودسیستم قابل نگهداری باقی بماندتیم‌ها مستقل‌تر کار کنندهزینه تغییرات در آینده کاهش یابدمعماری لایه‌ای (Layered Architecture)یکی از رایج‌ترین و قدیمی‌ترین معماری‌ها، معماری لایه‌ای است.ساختار معمول:Controller
Service
Repository
Database
مزایا:ساده و قابل فهممناسب پروژه‌های کوچک و متوسطیادگیری آسانمعایب:وابستگی زیاد لایه‌ها به همسختی مقیاس‌پذیری در پروژه‌های بزرگتبدیل شدن تدریجی به Monolith سنگین بسیاری از سیستم‌هایی که امروز نیاز به Microservices پیدا کرده‌اند، با همین معماری شروع شده‌اند.یک مثال واقعی از رشد یک سیستمفرض کنید یک استارتاپ با یک سیستم ساده شروع می‌کند:ثبت‌نام کاربرسفارشپرداختدر ابتدا:همه چیز در یک پروژهیک دیتابیسیک تیم کوچکاما با رشد محصول:تیم بزرگ‌تر می‌شودفیچرهای مالی پیچیده‌تر می‌شوندحجم کاربران افزایش پیدا می‌کنددر این مرحله، معماری اولیه دیگر پاسخگو نیست و مشکلاتی مثل:Deploy پرریسککدهای به‌شدت وابستهباگ‌های زنجیره‌ایشروع می‌شوند.اینجاست که مفاهیمی مثل Monolith و Microservices وارد بازی می‌شوند.آیا معماری را می‌توان بعداً تغییر داد؟از نظر تئوری بله، اما در عمل:پرهزینه استزمان‌بر استنیازمند تجربه بالا استمعمولاً با ریسک بالا همراه استبه همین دلیل، انتخاب معماری مناسب در زمان مناسب اهمیت حیاتی دارد.جمع‌بندیدر این مقاله به موارد زیر پرداختیم:معماری نرم‌افزار چیستچرا مهم‌تر از ابزارهاستتفاوت Architecture و Designمعماری لایه‌ای چه مزایا و معایبی داردچرا با رشد سیستم، معماری به چالش کشیده می‌شوددر مقاله بعدی، وارد یکی از مهم‌ترین مباحث می‌شویم:Monolithic Architecture چیست و چرا هنوز هم در بسیاری از پروژه‌ها بهترین انتخاب است؟</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Sun, 14 Dec 2025 20:24:10 +0330</pubDate>
            </item>
                    <item>
                <title>Green Tea GC: نسل جدید جمع‌کننده زباله در زبان Go</title>
                <link>https://virgool.io/@h.agharezaei/go-greenteagc-wfchbrd5chlj</link>
                <description>Green Tea Garbage Collectorدر اکتبر ۲۰۲۵، تیم توسعه Go قابلیت جدیدی به نام Green Tea Garbage Collector را معرفی کرد که به‌عنوان یک سیستم جمع‌آوری زباله (GC) آزمایشی در نسخهٔ Go 1.25 قابل استفاده است. این به‌روزرسانی می‌تواند نحوهٔ مدیریت حافظه در برنامه‌های Go را به‌طور قابل‌توجهی بهبود دهد و مسیر زبان را به سمت کارایی بالاتر در آینده ترسیم کند.چرا به Garbage Collector نیاز داریم؟در هر برنامه‌ای که از حافظهٔ heap استفاده می‌کند، مشخص کردن زمان آزاد کردن حافظه‌ای که دیگر استفاده نمی‌شود، یکی از مهم‌ترین چالش‌هاست. در Go، این کار به‌صورت خودکار توسط GC انجام می‌شود تا توسعه‌دهنده مجبور به مدیریت دستی حافظه نباشد.قبلاً Go از الگوریتم «mark-and-sweep» مبتنی بر اشاره‌گرها (tri-color) استفاده می‌کرد که هم‌زمان با اجرای برنامه فعالیت می‌کرد و سعی داشت زمان «pause» (توقف) را به حداقل برساند.Green Tea GC چیست؟Green Tea GC یک پیاده‌سازی جدید و آزمایشی برای جمع‌آوری زباله در Go است که روی کارایی، مقیاس‌پذیری و استفادهٔ بهتر از معماری حافظهٔ مدرن تمرکز دارد. در این روش، به‌جای اسکن تک‌تک اشیاء در heap، واحد اسکن به «spans» (بلاک‌های حافظه) تغییر می‌کند.span: بلوکی از حافظه که چندین شیء هم‌اندازه را در خود جای می‌دهد و واحد اساسی مدیریت حافظهٔ Go است.چگونه Green Tea کار می‌کند؟الگوریتم جدید به‌جای دنبال کردن اشاره‌گرها از شیء به شیء، کل spanها را به‌عنوان واحد کاری در نظر می‌گیرد. این رویکرد چند مزیت مهم دارد:۱. بهبود کارایی استفاده از cacheپردازش کل span باعث می‌شود حافظه‌هایی که در نزدیکی هم هستند در cache پردازنده بارگذاری شوند، در نتیجه تعداد cache missها کاهش می‌یابد و عمل اسکن حافظه سریع‌تر می‌شود.۲. کاهش هم‌زمانی و هماهنگی بین threadهابه جای کار با اشیاء پراکنده، کار روی spans به threadها اجازه می‌دهد کارهای بزرگ‌تر و منسجم‌تری انجام دهند، که این موضوع میزان هماهنگی (synchronization) بین threadها را کمتر می‌کند.۳. بهبود مصرف CPUدر اغلب تست ها، Green Tea توانسته بین ۱۰٪ تا ۴۰٪ مصرف CPU مرتبط با GC را کاهش دهد — در نتیجه برنامه‌ها زمان کمتری را در GC صرف می‌کنند.نتایج واقعیتست‌های اولیه نشان داده‌اند که:در بسیاری از برنامه‌ها، GC کمتر از گذشته CPU را درگیر می‌کند.در برخی سناریوها بهبودها چشم‌گیر است، اما در workloadهایی که اشیاء پراکنده‌اند ممکن است تأثیر کمتری مشاهده شود.مزایا و معایب Green Teaنقاط قوت✔ کاهش مصرف CPU در GC✔ بهتر شدن locality حافظه و عملکرد cache✔ آماده شدن برای استفاده در معماری‌های multi-core مدرنمحدودیت‌هااین قابلیت هنوز آزمایشی است و برای برخی برنامه‌ها ممکن است تأثیر کمی داشته باشد. تا زمانی که به‌عنوان گلوبال در نسخه‌های پایدار به‌کار نرود، نیاز به ارزیابی دقیق برای استفادهٔ در پرداکشن دارد.چگونه آن را امتحان کنیم؟برای استفاده از Green Tea در پروژهٔ خود، کافیست هنگام کامپایل Go از متغیر محیطی زیر استفاده کنید:GOEXPERIMENT=greenteagc go build
بدون نیاز به تغییر در کد برنامه.جمع‌بندیGreen Tea GC نشان‌دهندهٔ یک جهش بزرگ در مدیریت حافظهٔ Go است. با تمرکز بر طراحی موازی، بهینه‌سازی cache و کاهش سربار GC، این قابلیت می‌تواند راهنما و پیش‌درآمدی برای آیندهٔ Go باشد. اگر شما هم با برنامه‌های بزرگ، سیستم‌های توزیع‌شده یا workloadهای پر حافظه کار می‌کنید، Green Tea می‌تواند اجرای برنامه‌ها را روان‌تر و سریع‌تر کند — هر چند باید قبل از استفادهٔ در پرداکشن آن را به‌خوبی آزمایش کنید.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 12 Dec 2025 20:44:15 +0330</pubDate>
            </item>
                    <item>
                <title>NATS چیست؟ توضیح ساده و کاربردی برای برنامه‌نویسان Golang</title>
                <link>https://virgool.io/@h.agharezaei/nats-go-mohnexe2wcb6</link>
                <description>NATS and GoNATS چیه؟NATS یک سیستم پیام‌رسانی (Message Broker / Messaging System) فوق‌العاده سریع، سبک و ساده است که کمک می‌کند سرویس‌ها و برنامه‌ها با هم حرف بزنند بدون اینکه مستقیم همدیگر را صدا بزنند.یعنی چی؟یعنی به جای اینکه سرویس A مستقیم به سرویس B درخواست بدهد، پیامش را می‌فرستد به NATS و B هر وقت آماده بود پیام‌ها را دریافت می‌کند.مثل:یک پستچی خیلی سریع و قابل اعتماد بین سرویس‌هاارتباط بدون نیاز به اینکه سرویس‌ها آدرس هم را بدانندمناسب سیستم‌های میکروسرویس، realtime، IoT، event-drivenNATS چه کار می‌کند؟NATS چند مدل ارتباطی دارد:1) Publish / Subscribeمثل رادیویک سرویس پیام می‌فرستد (publish)چند سرویس می‌توانند همان پیام را گوش کنند (subscribe)2) Request / Replyمثل HTTP ولی به‌صورت پیام‌رسانA درخواست می‌دهد → B جواب می‌دهد(با سرعت خیلی بیشتر از REST)3) Queue Groupsبرای load-balancingچند سرویس در یک گروه باشند → هر پیام فقط به یکی از آنها می‌رسد.4) JetStreamسیستم پیام‌رسانی با Persistencyپیام‌ها ذخیره می‌شوند، Ack دارند، re-delivery دارند(مثل Kafka ساده اما خیلی سبک‌تر)چرا NATS پرطرفدار شده؟سرعت وحشتناک بالا (میلیون‌ها پیام در ثانیه)مصرف RAM بسیار کمنصب ساده: فقط یک binaryارتباط امن و پایدارمناسب برای سیستم‌های real-timeمناسب معماری event-driven و microservicesدر Golang چه کاری با NATS می‌شود کرد؟گولنگ بهترین زبانیه که برای NATS وجود دارد، چون خود NATS هم با Go نوشته شده.در Go می‌تونی:پیام publish / subscribe کنیnc, _ := nats.Connect(nats.DefaultURL)
nc.Subscribe(&quot;orders.created&quot;, func(m *nats.Msg) {
    fmt.Println(&quot;Order received:&quot;, string(m.Data))
})
nc.Publish(&quot;orders.created&quot;, []byte(&quot;Order #123&quot;))
سیستم Request/Reply بسازی// Server
nc.Subscribe(&quot;get.time&quot;, func(m *nats.Msg) {
    m.Respond([]byte(time.Now().String()))
})

// Client
resp, _ := nc.Request(&quot;get.time&quot;, nil, time.Second)
fmt.Println(&quot;Server time:&quot;, string(resp.Data))
از JetStream برای ذخیره پیام‌ها استفاده کنیذخیره، بازپخش، مصرف پیام‌ها با ack:js, _ := nc.JetStream()
js.Publish(&quot;events&quot;, []byte(&quot;hello&quot;))
برای میکروسرویس‌ها event-driven مناسب استارسال رویداد paymentاطلاع‌رسانی ایجاد کاربرپردازش asynchronousهماهنگی سرویس‌ها خلاصه خیلی سادهNATS یک پیام‌رسان سریع برای اتصال سرویس‌هاست.در Golang می‌توانی با آن Publish/Subscribe، Request/Reply، Queue، JetStream و انواع ارتباط‌های real-time را بسازی.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Sun, 07 Dec 2025 19:58:17 +0330</pubDate>
            </item>
                    <item>
                <title>Context در Golang چیست؟ آموزش کامل + مثال عملی</title>
                <link>https://virgool.io/@h.agharezaei/go-context-kqovs6sbv8sb</link>
                <description>Context در گولنگ چیست و چگونه به مدیریت کانسل‌کردن، تایم‌اوت و کنترل جریان درخواست‌ها کمک می‌کندمقدمهدر برنامه‌نویسی Go، زمانی که با عملیات هم‌زمان (goroutine)، درخواست‌های شبکه‌ای، اتصال به دیتابیس یا سیستم‌های توزیع‌شده سروکار داریم، باید بتوانیم اجرای یک عملیات را در موقعیت‌های مختلف متوقف یا کنترل کنیم.Context دقیقاً برای همین هدف ساخته شده است.در این مقاله به‌صورت کامل و عملی یاد می‌گیرید:Context دقیقاً چیست و چرا وجود دارد؟انواع Context: Background, TODOContext با timeout، deadline، cancelContext برای مدیریت goroutineهاارسال اطلاعات در Contextیک مثال کاملاً عملی: API با تایم‌اوت و لغو عملیاتContext در Go چیست؟Context یک مکانیزم استاندارد در Go است که برای موارد زیر استفاده می‌شود:۱. لغو (Cancelation) عملیاتوقتی یک درخواست لغو می‌شود، تمام goroutineهای مرتبط با آن باید متوقف شوند.۲. تنظیم deadline / timeoutبرای جلوگیری از بلاک شدن سیستم.۳. ارسال مقدار (Value Propagation)اطلاعات سبک (مثل request id) را می‌توان به صورت امن در Context جا‌به‌جا کرد.۴. مدیریت کارهای وابستهوقتی والد لغو شود، همه کارهای فرزند نیز لغو می‌شوند.🔹 Context چگونه کار می‌کند؟در Go، Context یک interface با ۴ تابع اصلی است:type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() &lt;-chan struct{}
    Err() error
    Value(key any) any
}
معنی هر کدام:Context یک interface با ۴ تابع اصلیانواع Context ابتداییcontext.Background()ریشهٔ درخت Context. معمولاً برای شروع اپلیکیشن.context.TODO()وقتی هنوز نمی‌دانیم چه Context لازم داریم.ساخت Context قابل لغوctx, cancel := context.WithCancel(context.Background())
defer cancel()
لغو عملیات:cancel()
Context با Timeoutctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
بعد از 3 ثانیه، ctx.Done() بسته می‌شود.Context با Deadlinedeadline := time.Now().Add(2 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), deadline)
defer cancel()
ارسال مقدار در Contextطبق مستندات Go:فقط اطلاعات سبک، غیر حساس و غیر ضروری باید در Context ذخیره شود.برای داده‌های سنگین یا state از آن استفاده نکنید.مثال:ctx := context.WithValue(context.Background(), &quot;requestID&quot;, &quot;ABC-123&quot;)
مثال عملی: مدیریت Timeout در یک APIدر این مثال یک API می‌سازیم که درخواست‌های سنگین را با Context مدیریت می‌کند.هدف مثالوقتی کار بیش از حد طول کشید → خودکار قطع شوداگر کلاینت درخواست را لغو کرد → Goroutine‌ها هم لغو شوندهمراه با log و requestIDکد کامل مثالpackage main

import (
    &quot;context&quot;
    &quot;fmt&quot;
    &quot;log&quot;
    &quot;net/http&quot;
    &quot;time&quot;
)

func main() {
    http.HandleFunc(&quot;/process&quot;, handler)
    fmt.Println(&quot;Server running on :8080&quot;)
    log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    // ساخت context با timeout
    ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second)
    defer cancel()

    // اضافه کردن requestID به context
    ctx = context.WithValue(ctx, &quot;requestID&quot;, time.Now().UnixNano())

    resultChan := make(chan string)

    // شروع یک عملیات سنگین
    go func() {
        // شبیه‌سازی کار ۵ ثانیه‌ای
        time.Sleep(5 * time.Second)
        resultChan &lt;- &quot;Operation Completed&quot;
    }()

    select {
    case &lt;-ctx.Done():
        // Timeout یا لغو شدن
        log.Println(&quot;Canceled:&quot;, ctx.Value(&quot;requestID&quot;), ctx.Err())
        http.Error(w, &quot;Request Timeout&quot;, http.StatusRequestTimeout)
        return

    case result := &lt;-resultChan:
        // موفقیت‌آمیز
        fmt.Fprintln(w, result)
    }
}
برای دسترسی به سورس‌کد کامل مثال Context در Golang، به ریپازیتوری اختصاصی این مقاله در GitHub مراجعه کنید:https://github.com/h-agharezaei/go-context-02.gitتحلیل دقیق مثالزمان پیش‌فرض عملیات ۵ ثانیه است ولی Context فقط ۳ ثانیه فرصت می‌دهد.بنابراین:عملیات به اتمام نمی‌رسدctx.Done() بعد از ۳ ثانیه بسته می‌شوددرخواست لغو می‌شودGoroutine پاک‌سازی می‌شودویژگی مهماگر کلاینت (مثلاً Postman) درخواست را Cancel کند، سرویس Go به‌طور خودکار Context را Cancel می‌کند.Best Practices استفاده از Context در Go✔ همیشه Context را در اولین آرگومان تابع قرار دهید:func fetchData(ctx context.Context) {}
✔در توابع سطح پایین (service، repo، helper)، نباید از Background ، TODO یا WithCancel برای ساختن context استفاده کنید. Context باید از caller بیاید.✔ از Context برای انتقال اطلاعات مهم یا ساختارهای سنگین استفاده نکنید✔ برای database، http، grpc حتماً از Context استفاده کنید✔ Context باید توسط caller مدیریت شود، نه calleeجمع‌بندیContext یکی از مهم‌ترین ابزارهای Go برای مدیریت:زمان اجرای عملیاتلغو کارهاکنترل goroutineهاجلوگیری از memory leakارتباط بهتر بین لایه‌های نرم‌افزاردر این مقاله یاد گرفتید:Context چیست و چرا استفاده می‌شودانواع ContextTimeout، Deadline و Cancelانتقال مقداریک مثال واقعی در سطح production</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Thu, 04 Dec 2025 23:10:34 +0330</pubDate>
            </item>
                    <item>
                <title>Channel در Go: یک راهنمای جامع برای انتقال داده همزمان</title>
                <link>https://virgool.io/@h.agharezaei/go-channel-ev6ct1lzz8dg</link>
                <description>Channel در GoChannel یکی از کلیدی‌ترین مؤلفه‌های مدل همزمانی در زبان Go است. در حالی که Goroutine‌ها امکان اجرای موازی و سبک‌وزن را فراهم می‌کنند، این Channel‌ها هستند که ارتباط کنترل‌شده و امن بین آن‌ها را ممکن می‌سازند. بدون Channel، مدیریت هماهنگی میان Goroutine‌ها می‌تواند بسیار پیچیده و خطاپذیر باشد.در این مقاله، به صورت کاملاً عملی و دقیق بررسی می‌کنیم که Channel چیست، چگونه کار می‌کند و چه الگوهایی در توسعه همزمان با آن استفاده می‌شود.Channel چیست و چرا مهم است؟Channel یک سازوکار داخلی در Go است که امکان ارسال و دریافت داده را بین Goroutine‌ها فراهم می‌کند. Channel نوع‌محور است؛ یعنی تنها داده‌ای از یک نوع مشخص را قبول می‌کند. به بیان ساده:Channel = لوله‌ای برای عبور داده بین goroutineها به‌صورت هم‌زمان و ایمن.Channel دو ویژگی مهم دارد:همگام‌سازی (Synchronization)ارسال‌کننده و گیرنده برای انتقال داده همگام می‌شوند.ایمن از رقابت (Race-Free)چون Channel کنترل ارسال و دریافت را مدیریت می‌کند، نیاز به لاک و Mutex در بسیاری از سناریوها کاهش می‌یابد.ایجاد یک Channelch := make(chan int)
این دستور یک Channel از نوع int ایجاد می‌کند.ارسال و دریافت دادهارسال داده:ch &lt;- 10
دریافت داده:value := &lt;-ch
ارسال‌کننده تا زمانی که گیرنده آماده دریافت نباشد، بلوکه می‌شود و بالعکس.یک مثال سادهpackage main

import (
    &quot;fmt&quot;
)

func main() {
    ch := make(chan string)

    go func() {
        ch &lt;- &quot;Hello from goroutine&quot;
    }()

    msg := &lt;-ch
    fmt.Println(msg)
}
در این مثال، داده از یک Goroutine به Goroutine اصلی منتقل می‌شود.Channelهای Buffered vs UnbufferedUnbuffered Channelبه صورت پیش‌فرض، Channel فاقد بافر است. یعنی:ارسال و دریافت باید هم‌زمان انجام شوندحالت کاملاً همگام استch := make(chan int)
Buffered ChannelChannel می‌تواند یک بافر داخلی داشته باشد:ch := make(chan int, 3)
در این حالت:ارسال تا زمانی که بافر پر نشده بلوکه نمی‌شوددریافت تا زمانی که بافر خالی نشده بلوکه نمی‌شودمثال:ch := make(chan int, 2)
ch &lt;- 1
ch &lt;- 2  // OK
ch &lt;- 3  // بلوکه می‌شود
بستن Channelاز close() برای اعلام پایان ارسال داده استفاده می‌شود.close(ch)
نکات مهم:بعد از close امکان ارسال وجود ندارددریافت‌کننده می‌تواند با بررسی مقدار دوم بفهمد Channel بسته شده استمثال:v, ok := &lt;-ch
if !ok {
    fmt.Println(&quot;channel closed&quot;)
}
range روی Channelبرای دریافت داده تا زمان بسته شدن Channel:for v := range ch {
    fmt.Println(v)
}
الگوهای همزمانی رایج با Channel1. الگوی Worker PoolChannel برای توزیع کار میان چند Goroutine استفاده می‌شود.2. الگوی Fan-out / Fan-inیک منبع داده به چند Goroutine پخش (fan-out) می‌شود و سپس نتایج در یک Channel جمع‌آوری (fan-in) می‌شود.3. هماهنگی و سیگنال‌دهیChannel می‌تواند برای نشانه‌گذاری پایان یک کار یا شروع عملیات استفاده شود.4. Multiplexing با selectاستفاده از select برای مدیریت چند Channelselect به شما اجازه می‌دهد از چند منبع هم‌زمان داده دریافت یا ارسال کنید.select {
case v := &lt;-ch1:
    fmt.Println(&quot;received:&quot;, v)
case ch2 &lt;- 10:
    fmt.Println(&quot;sent to ch2&quot;)
default:
    fmt.Println(&quot;no communication&quot;)
}
Best Practices برای استفاده از ChannelChannel را فقط ارسال‌کننده ببندداز Buffer زمانی استفاده کنید که دلیل مشخص داریدبرای جلوگیری از deadlock همیشه سناریوی دریافت‌کننده/ارسال‌کننده را به‌دقت طراحی کنیداز select همراه با timeout استفاده کنیدمثال timeout:select {
case v := &lt;-ch:
    fmt.Println(v)
case &lt;-time.After(time.Second):
    fmt.Println(&quot;timeout&quot;)
}
جمع‌بندیChannel یکی از قدرتمندترین ابزارهای همزمانی در Go است که امکان ارتباط ایمن، ساده و کارآمد بین goroutineها را فراهم می‌کند. استفاده صحیح از channelها می‌تواند معماری همزمان برنامه شما را بسیار تمیزتر و قابل‌نگهداری‌تر کند.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Sun, 23 Nov 2025 22:26:59 +0330</pubDate>
            </item>
                    <item>
                <title>Goroutine در Golang: معماری همزمانی سبک، سریع و بهینه</title>
                <link>https://virgool.io/@h.agharezaei/goroutine-ihmgicu0rw9t</link>
                <description>Goroutine در Golangزبان Go از ابتدا با هدف ساده‌سازی ساخت نرم‌افزارهای مقیاس‌پذیر و پرکاربرد طراحی شد. یکی از مهم‌ترین مؤلفه‌هایی که این زبان را از سایر زبان‌ها متمایز می‌کند، Goroutine است؛ سازوکاری بسیار سبک‌وزن برای اجرای همزمان (Concurrency) که به شکل مستقیم توسط runtime خود Go مدیریت می‌شود.در این مقاله، به ساختار Goroutine، نحوه اجرای آن در runtime، رابطه‌اش با Scheduler، تفاوت آن با Threadهای سیستم‌عامل و نکات کلیدی در استفاده حرفه‌ای از آن می‌پردازیم.Goroutine چیست؟گوروتین یک واحد اجرای همزمان در Go است که به‌صورت بسیار سبک‌وزن ایجاد و مدیریت می‌شود. برخلاف Threadهای معمولی سیستم‌عامل که ایجاد آن‌ها هزینه بالایی دارد (Memory + Context Switching)، گوروتین‌ها با مصرف حافظه بسیار کم (در حد چند کیلوبایت) ساخته می‌شوند و در صورت نیاز به‌طور خودکار رشد یا کاهش می‌یابند.به طور ساده:Thread = سنگین، هزینه‌بر، وابسته به سیستم‌عاملGoroutine = سبک، سریع، مدیریت‌شده توسط Go runtimeمعماری اجرای گوروتین در Go Runtime (M:N Scheduler)Go از یک معماری M:N Scheduler استفاده می‌کند که در آن:M = تعداد Threadهای سیستم‌عاملN = تعداد GoroutineهاScheduler گوروتین‌ها را روی Threadهای سیستم‌عامل قرار می‌دهد و بدون دخالت برنامه‌نویس، عملیات زمان‌بندی، تعویض context و مدیریت دوره‌ای را تنظیم می‌کند.سه مفهوم کلیدی در Scheduler عبارت‌اند از:1. G – Goroutineکدی که باید اجرا شود.2. M – MachineThread سیستم‌عاملی که واقعاً اجرا را انجام می‌دهد.3. P – Processorمنبع منطقی برای اجرای Goroutineها که شامل Run Queue است.وجود Processorها به runtime کمک می‌کند تا load balancing و work stealing را بهتر مدیریت کند.نحوه ساخت یک Goroutineساخت یک Goroutine بسیار ساده است؛ تنها کافی است قبل از فراخوانی تابع، کلمه کلیدی go را قرار دهید:func main() {
    go doSomething()
    println(&quot;Main finished&quot;)
}

func doSomething() {
    println(&quot;Hello from goroutine&quot;)
}
نکات:اجرای main بلافاصله ادامه پیدا می‌کند.اگر main تمام شود، تمام گوروتین‌های دیگر نیز خاتمه می‌یابند.مدیریت همزمانی بین گوروتین‌ها نیازمند سازوکارهایی مانند Channel یا sync است.اندازه اولیه Stack در Goroutineبرخلاف Threadها که معمولاً Stack با حجم 1MB یا بیشتر دارند، گوروتین‌ها با یک Stack کوچک و داینامیک (حدود 2KB) شروع می‌شوند.زمانی که حجم Stack مورد نیاز بیشتر شود، runtime آن را دوبرابر می‌کند. این کاهش هزینه اولیه و مدیریت پویا، دلیل اصلی سبک‌وزنی گوروتین‌هاست.تفاوت میان Goroutine و Threadتفاوت میان Goroutine و Threadدر عمل، می‌توان میلیون‌ها گوروتین را روی چند Thread سیستم‌عامل اجرا کرد.ارتباط Goroutineها با Channelsبرای هماهنگ‌سازی و انتقال داده بین گوروتین‌ها، زبان Go از سازوکاری قدرتمند به نام Channel استفاده می‌کند که الگوی CSP (Communicating Sequential Processes) را پیاده‌سازی می‌کند.نمونه ساده:func main() {
    ch := make(chan string)
    go func() {
        ch &lt;- &quot;message from goroutine&quot;
    }()
    msg := &lt;-ch
    println(msg)
}
Best Practices در استفاده از Goroutine1. نشتی گوروتین (Goroutine Leak) را جدی بگیریداگر گوروتین منتظر یک channel است اما هیچ‌گاه داده‌ای به آن ارسال نمی‌شود، هرگز متوقف نخواهد شد.از context‌ها یا timeoutها برای مدیریت طول عمر گوروتین استفاده کنید.2. از WaitGroup برای همگام‌سازی استفاده کنیداین روش استاندارد برای صبر کردن جهت پایان گوروتین‌هاست.var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    doWork()
}()
wg.Wait()
3. از تعداد بیش از حد گوروتین خودداری کنیداگرچه گوروتین‌ها سبک هستند، اما بی‌برنامه ایجاد کردن تعداد زیاد، ممکن است باعث فشار روی حافظه و Scheduler شود.4. از Worker Pool برای بارهای سنگین استفاده کنیدبرای جلوگیری از تولید بیش از حد گوروتین، الگوی Worker Pool را به‌کار ببرید.خطاهای رایج هنگام استفاده از Goroutineاستفاده از مقادیر loop variable در گوروتین‌هافراموش کردن close کردن channelهامتوقف نشدن گوروتین‌های بلاک‌شدهعدم مدیریت context در سرویس‌های شبکه‌اینتیجه‌گیریGoroutine یکی از کلیدی‌ترین ویژگی‌های زبان Go است که امکان ساخت اپلیکیشن‌های مقیاس‌پذیر، سریع و همزمان را با هزینه بسیار کم فراهم می‌کند. معماری scheduler سبک، مدیریت خودکار Stack، و یکپارچگی با Channelها باعث شده Go یکی از بهترین انتخاب‌ها برای سیستم‌های توزیع‌شده، سرویس‌های وب، پردازش همزمان و میکروسرویس‌ها باشد.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Sat, 22 Nov 2025 21:21:39 +0330</pubDate>
            </item>
                    <item>
                <title>آشنایی کامل با Struct در زبان Go</title>
                <link>https://virgool.io/@h.agharezaei/golang-struct-bp4zib9szrnt</link>
                <description>Struct در Go ابزاری برای تعریف نوع داده‌ای سفارشی استراهنمای کاربردی برای توسعه‌دهندگان Goیکی از مهم‌ترین مفاهیم در زبان برنامه‌نویسی Go، ساختارها یا Struct‌ها هستند. Struct در Go ابزاری برای تعریف نوع داده‌ای سفارشی است که می‌تواند مجموعه‌ای از فیلدهای مرتبط را در کنار هم نگه دارد. Struct پایه‌ای‌ترین راه برای مدل‌سازی موجودیت‌ها در زبان Go محسوب می‌شود، زیرا Go برخلاف برخی زبان‌ها از برنامه‌نویسی شیءگرا با کلاس‌ها پشتیبانی نمی‌کند و Structها نقش غالباً مشابهی را ایفا می‌کنند.در این مقاله با مفهوم Struct، کاربردها، بهترین الگوهای طراحی و نکات پیشرفته آن آشنا می‌شویم.Struct چیست؟Struct در Go یک نوع داده ترکیبی است که از چندین فیلد تشکیل می‌شود. هر فیلد دارای یک نام و یک نوع است. تعریف یک Struct معمولاً زمانی استفاده می‌شود که بخواهیم داده‌های مرتبط را در یک واحد منطقی گروه‌بندی کنیم.مثال ساده تعریف Struct:type User struct {
    Name  string
    Age   int
    Email string
}
در مثال بالا نوع داده‌ای جدیدی به نام User تعریف کرده‌ایم که شامل سه فیلد است.ایجاد یک نمونه (Instance) از Structبرای ساخت نمونه‌ای از Struct می‌توان از روش‌های مختلفی استفاده کرد.۱. استفاده مستقیم از مقداردهی ساختاریu := User{
    Name:  &quot;Ali&quot;,
    Age:   30,
    Email: &quot;ali@example.com&quot;,
}
۲. بدون مقداردهی اولیهvar u User
u.Name = &quot;Sara&quot;
u.Age = 25
u.Email = &quot;sara@example.com&quot;
۳. استفاده از اشاره‌گر به Structu := &amp;User{
    Name: &quot;Reza&quot;,
}
با استفاده از اشاره‌گر، دسترسی به فیلدها همچنان با u.Name امکان‌پذیر است و نیازی به (*u).Name نیست؛ Go به صورت خودکار dereference انجام می‌دهد.توابع و متدها برای StructGo از متدهای متصل به Struct پشتیبانی می‌کند. این قابلیت یکی از جایگزین‌های کلاس در زبان Go محسوب می‌شود.نمونه یک متد روی Struct:func (u User) Info() string {
    return fmt.Sprintf(&quot;%s (%d years old)&quot;, u.Name, u.Age)
}
تفاوت Receiver مقداری و اشاره‌گریReceiver مقداری: یک کپی از Struct دریافت می‌شود.Receiver اشاره‌گری: تغییرات روی نمونه اصلی اعمال می‌شود.مثال با pointer receiver:func (u *User) IncreaseAge() {
    u.Age++
}
Anonymous Struct (ساختارهای بی‌نام)گاهی نیاز نیست Struct را با نام مشخص تعریف کنیم.user := struct {
    Name string
    Age  int
}{
    Name: &quot;Hasan&quot;,
    Age:  40,
}
این روش معمولاً برای تست‌ها یا ساخت داده‌های موقت استفاده می‌شود.Embedding در Struct (ترکیب به‌جای وراثت)Go از وراثت پشتیبانی نمی‌کند، اما از ترکیب (Composition) استفاده می‌کند. با Embedding یک Struct در Struct دیگر، فیلدها و متدهای Struct داخلی در Struct بیرونی قابل استفاده می‌شوند.type Address struct {
    City  string
    Phone string
}

type Employee struct {
    Name string
    Address
}
اکنون:e := Employee{Name: &quot;Maryam&quot;, Address: Address{City: &quot;Tehran&quot;}}
fmt.Println(e.City)
تگ‌های Struct (Struct Tags)Struct Tagها برای متادیتا به‌کار می‌روند و در عملیات‌هایی مانند JSON، پایگاه‌داده، API و Validation کاربرد دارند.مثال:type Product struct {
    ID    int    `json:&quot;id&quot;`
    Name  string `json:&quot;name&quot;`
    Price int    `json:&quot;price,omitempty&quot;`
}
ویژگی omitempty باعث می‌شود فیلدهای خالی در JSON مخفی شوند.مقایسه Struct با کلاس در زبان‌های OOPGo کلاس ندارد، اما Struct+Methodها نقش مشابهی ایجاد می‌کنند.ویژگیStruct در Goکلاس در زبان‌های OOPوراثتنداردداردمتدداردداردسازنده (Constructor)ندارد، اما الگوهای پیشنهادی داردداردEncapsulationنسبی با حروف بزرگ/کوچککامل توسط modifierهاالگوی متداول Constructor در Gofunc NewUser(name, email string) *User {
    return &amp;User{
        Name:  name,
        Email: email,
        Age:   0,
    }
}
نکات پیشرفته۱. Equalityاگر تمامی فیلدها قابل مقایسه باشند، Struct نیز قابل مقایسه است.۲. Memory LayoutStructها به صورت contiguous در حافظه ذخیره می‌شوند، بنابراین ترتیب فیلدها در بهینه‌سازی حافظه مؤثر است.۳. استفاده از Struct به عنوان Map Keyدر صورتی که فیلدها قابل مقایسه باشند، Struct می‌تواند کلید یک Map باشد.جمع‌بندیStructها در Go پایه اصلی مدل‌سازی داده‌ها هستند و امکانات پیشرفته‌ای همچون متدها، ترکیب، تگ‌ها و الگوهای ساخت آبجکت را فراهم می‌کنند. استفاده درست از Structها باعث طراحی ساخت‌یافته، خوانا و توسعه‌پذیر در پروژه‌های Go می‌شود.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 21 Nov 2025 21:16:26 +0330</pubDate>
            </item>
                    <item>
                <title>مستندسازی در مهندسی نرم‌افزار: چرا مهم است و چه استانداردهایی دارد؟</title>
                <link>https://virgool.io/@h.agharezaei/software-architecture-documentation-tayugda8mtrk</link>
                <description>در دنیای پیچیده و در حال تحول مهندسی نرم‌افزار، مستندسازی یکی از حیاتی‌ترین بخش‌های چرخه توسعه محصول است. وجود مستندات دقیق و استاندارد، به تیم‌های نرم‌افزاری کمک می‌کند تا محصولی قابل نگهداری، قابل توسعه و قابل‌فهم ایجاد کنند. در این مقاله به صورت جامع بررسی می‌کنیم که مستندسازی چیست، چرا اهمیت دارد، چه انواعی دارد و بر اساس چه استانداردهایی انجام می‌شود.بررسی کامل مستندسازی در مهندسی نرم‌افزار، انواع مستندات، استانداردها، مدل C4، UML و ابزارهای حرفه‌ای. راهنمایی جامع برای توسعه‌دهندگان و مدیران پروژه.مستندسازی در مهندسی نرم‌افزار چیست؟مستندسازی به فرآیند ثبت و سازمان‌دهی اطلاعات مرتبط با تحلیل، طراحی، توسعه، تست، اجرا و نگهداری نرم‌افزار گفته می‌شود. هدف اصلی مستندات این است که دانش تولیدشده در طول پروژه برای همه افراد تیم و نسل‌های بعدی توسعه‌دهندگان قابل دسترس باشد.چرا مستندسازی اهمیت دارد؟دلایل زیر نشان می‌دهند که چرا پروژه‌های حرفه‌ای بدون مستندسازی محکوم به شکست هستند:انتقال دانش بین تیم‌ها و افرادسهولت در نگهداری و توسعه سیستمکاهش وابستگی به توسعه‌دهندگان کلیدیامکان مدیریت تغییرات در طول پروژهافزایش کیفیت و قابلیت اعتماد سیستمتسهیل در تست و رفع خطادر پروژه‌هایی که مستندات وجود ندارد، معمولاً هزینه نگهداری، باگ‌گیری و توسعه بسیار بیشتر می‌شود.انواع مستندسازی در مهندسی نرم‌افزارمستندات را می‌توان به دو گروه اصلی تقسیم کرد:۱. مستندسازی فرآیندی (Process Documentation)این دسته شامل مستنداتی است که چرخه توسعه و تصمیمات مهم پروژه را شرح می‌دهند:● سند چشم‌انداز (Vision Document)اهداف کلان، کاربران هدف، و مشکلاتی که محصول حل می‌کند.● SRS – Software Requirement Specificationمهم‌ترین سند نیازمندی‌ها؛ شامل نیازهای کارکردی و غیرکارکردی.● Use Case / User Story Documentationتعریف نحوه تعامل کاربران با سیستم.● Architecture Documentطراحی سطح بالای سیستم شامل:دیاگرام‌های معماریالگوهای طراحیساختار ماژول‌ها● Test Documentationبرنامه تست، سناریوها، موارد تست و گزارش‌ها.● DevOps Documentationمستندات CI/CD، کانفیگ سرورها، Docker و Kubernetes.۲. مستندسازی محصول (Product Documentation)این دسته شامل مستنداتی است که به کاربران نهایی یا توسعه‌دهندگان جدید کمک می‌کنند:● User Manualراهنمای استفاده از سیستم.● Installation Guideنحوه نصب و راه‌اندازی محصول.● Developer Guideراهنمای شروع به کار برای توسعه‌دهندگان جدید.● API Documentationمستندات سرویس‌ها، Endpointها، ورودی‌ها و خروجی‌ها (مانند Swagger).استانداردهای مهم مستندسازیدر صنعت نرم‌افزار مجموعه‌ای از استانداردهای معتبر برای مستندسازی استفاده می‌شود:۱. IEEE 830 – استاندارد SRSاین استاندارد برای تولید سند نیازمندی‌های نرم‌افزار استفاده می‌شود. شامل بخش‌های:معرفی سیستمتعریف واژه‌هانیازمندی‌های کارکردینیازمندی‌های غیرکارکردیمحدودیت‌هاUse Caseها۲. IEEE 1016 – استاندارد معماری نرم‌افزاراین استاندارد نحوه مستندسازی معماری را مشخص می‌کند و شامل Viewهای:ContextContainerComponentDeployment۳. UML – زبان مدل‌سازی استانداردUML مجموعه‌ای از دیاگرام‌های استاندارد برای نمایش ساختار و رفتار سیستم است:Use Case DiagramClass DiagramActivity DiagramSequence DiagramDeployment Diagramاستفاده از UML باعث یکپارچگی و شفافیت در مستندسازی طراحی می‌شود.۴. C4 Model – روش مدرن مستندسازی معماریامروزه بسیاری از شرکت‌های بزرگ از مدل C4 به دلیل سادگی و قابلیت فهم بالا استفاده می‌کنند. این مدل شامل چهار سطح است:Context DiagramContainer DiagramComponent DiagramCode Diagramاین روش برای پروژه‌های مدرن مثل Microservices و سیستم‌های مبتنی بر Cloud بسیار کاربردی است.ابزارهای حرفه‌ای برای مستندسازیبرای تولید و مدیریت مستندات می‌توان از ابزارهای زیر بهره برد:Confluence (استاندارد سازمانی)NotionGitHub WikiDocusaurus (برای پروژه‌های React/Next.js)Swagger / OpenAPIPlantUML یا MermaidJS (برای رسم دیاگرام‌ها)MkDocsانتخاب ابزار به اندازه تیم شما، نوع پروژه و نیاز به همکاری بستگی دارد.اصول طلایی در مستندسازیبرای داشتن مستندات کارآمد:مستندات باید همیشه به‌روز نگه داشته شوند.تا حد امکان کوتاه، دقیق و قابل فهم باشند.در کنار کد و با Version Control نگهداری شوند.از دیاگرام به جای متن طولانی استفاده شود.مخاطب هر سند مشخص باشد.جمع‌بندیمستندسازی یکی از اصلی‌ترین ستون‌های مهندسی نرم‌افزار است. بدون مستندات دقیق و استاندارد، هیچ پروژه‌ای(حتی اگر عالی توسعه یافته باشد)در بلندمدت قابل نگهداری، توسعه یا انتقال نیست. استفاده از استانداردهایی مانند IEEE 830, IEEE 1016, UML و مدل C4 کمک می‌کند مستندات شما حرفه‌ای، قابل فهم و قابل اتکا باشند.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Wed, 19 Nov 2025 23:07:45 +0330</pubDate>
            </item>
                    <item>
                <title>TOON: قالب داده‌ای کارا برای تعامل با مدل‌های زبانی</title>
                <link>https://virgool.io/@h.agharezaei/httpsvirgooliohagharezaeitoon-xk7a9h3biz3v</link>
                <description>(Token-Oriented Object Notation)Token-Oriented Object Notationدر دنیای امروز، که مدل‌های زبانی بزرگ (LLMها) بیش از پیش در جریان داده‌ها و پردازش اطلاعات به کار گرفته می‌شوند، انتقال ساختار یافتهٔ داده به این مدل‌ها به یک چالش تبدیل شده است. قالب‌های متداول مانند JSON یا YAML علی‌رغم قابلیت بالا، از نظر «هزینه توکنی» (token cost) برای مدل‌ها اصلا بهینه نیستند. TOON با هدف کاهش هزینه توکن و بهبود فهم مدل‌ها برای ورودی‌های بزرگ طراحی شده است.چرا TOON؟در مستند TOON آمده است که: «TOON قالبی human-readable و فشرده برای سریال‌سازی داده‌های ساختار یافته است که برای ارسال به مدل‌های زبانی طراحی شده و می‌تواند به‌طور معنی‌داری تعداد توکن‌های مصرف‌شده را کاهش دهد.»مثالی از JSON و تبدیل مشابه آن به TOON:{
  &quot;users&quot;: [
    { &quot;id&quot;: 1, &quot;name&quot;: &quot;Roham&quot;, &quot;role&quot;: &quot;admin&quot; },
    { &quot;id&quot;: 2, &quot;name&quot;: &quot;Ziba&quot;,   &quot;role&quot;: &quot;user&quot;  }
  ]
}
در TOON به این شکل است:users[2]{id,name,role}:
  1,Roham,admin
  2,Ziba,user
بنابراین، وقتی شما داده‌ای دارید با آرایه‌های بزرگ که ساختار یکنواخت دارند (مثلاً رکوردهای کاربران یا آیتم‌های فروش)، TOON می‌تواند ۳۰٪ تا ۶۰٪ تعداد توکن‌ها را در مقایسه با JSON کاهش دهد.ویژگی‌های کلیدی TOONدر ادامه مهم‌ترین ویژگی‌های TOON را مرور می‌کنیم:فشردگی توکنی: کاهش چشمگیر تعداد توکن‌های مصرفی در ورودی مدل‌های زبانی.خوانایی نسبی برای انسان: قالبی که ترکیبی از YAML-مانند (برای داده های تودرتو) و CSV-مانند (برای آرایه‌های یکنواخت) .ساختار صریح: شامل نمایش طول آرایه‌ها ([N]) و تعیین صریح فیلدها {field1,field2,...} برای آرایه‌های یکنواخت.سینتکس بسیار مختصر: حذف بسیاری از کروشه‌ها، براکت‌ها و به‌کارگیری حداقلی از نقل‌قول‌ها.سازگار با استفاده به عنوان ورودی LLM: هدف اصلی نه ذخیره‌سازی یا API بلکه تغذیه داده به مدل‌های زبانی است.چه زمانی TOON مناسب نیست؟بله — هیچ قالب داده‌ای کامل نیست. TOON هم محدودیت‌هایی دارد که باید آن‌ها را شناخت. مستند رسمی آن‌ها را این‌گونه معرفی می‌کند:وقتی داده‌های شما عمیقاً تودرتو (deep nested) هستند و ساختار یکنواخت ندارند: در این حالت JSON ممکن است گزینه بهتری باشد.وقتی آرایه‌های شما نیمه‌ یکنواخت (semi-uniform) هستند: یعنی بعضی آیتم‌ها فیلدهای متفاوت دارند یا ساختار متفاوت دارند.وقتی داده کاملاً تجریدی و ساده (مثل یک جدول کاملاً صاف) باشد: در آن صورت ممکن است CSV یا دیگر فرمت‌های مختصرتر حتی کاراتر باشند.زمانی که سازگاری با اکوسیستم‌های موجود (مثلاً APIهای آماده، ذخیره‌سازی، پایگاه‌داده) اهمیت بیشتری از توکن‌کاهش داشته باشد.معماری و نحوهٔ کارکرد TOONعملکرد TOON را می‌توان در دو قسمت اصلی توضیح داد:آرایه‌های یکنواخت (Tabular Arrays): وقتی شما مجموعه‌ای از آبجکت‌ها دارید که تمام آن‌ها دقیقاً همان فیلدها را دارند، TOON با اعلام آن فیلدها یک‌بار، سپس ارائهٔ رکوردها به صورت مقادیر جدا شده با کاما، بسیار بهینه عمل می‌کند. مثال بالا نشان می‌دهد.ساختارهای تودرتو و اسکالرها: برای مقادیر منفرد، آرایه‌های ساده یا اشیاء با ساختار تودرتو، TOON سینتکس خود را دارد — مانند استفاده از «key: value» مشابه YAML، یا نمایشی از آرایه با [N]: سپس مقادیر.سینتکس مختصر مثال:tags[3]: admin,ops,dev
یاuser:
  id: 123
  profile:
    name: Roham
کاربردها و سناریوهای مناسباگر بخواهم در زبان ساده بگویم: اگر شما با داده‌هایی سروکار دارید که قرار است به مدل زبانی بروند — مثلاً خروجی از یک دیتابیس، نتایج تحلیل، داده‌های ارسال به API مدل — و این داده‌ها آرایه‌های بزرگ با ساختار یکسان هستند، TOON می‌تواند گزینه بسیار خوبی باشد.در مقابل، اگر دارید داده‌ای می‌فرستید به سیستم ذخیره‌سازی، بانک اطلاعات، یا API که همه ابزارها JSON را انتظار دارند، ممکن است همان JSON گزینه بهتری باشد.شروع سریع با TOONبرای شروع کار با TOON کافی است:اگر دادهٔ ای را به فرمت JSON داشته باشیدبا ابزارها یا کتابخانه‌های TOON آن را به فرمت TOON تبدیل کنیدبه مدل زبانی ارسال کنید یا از آن دریافت کنیدبه عنوان مثال (در جاوااسکریپت):import { encode, decode } from &#039;@toon-format/toon&#039;;

const data = { 
  items: [
    { id: &#039;A1&#039;, qty: 2, price: 9.99 },
    { id: &#039;B2&#039;, qty: 1, price: 14.50 }
  ]
};

const toonText = encode(data);
console.log(toonText);
// items[2]{id,qty,price}:
// A1,2,9.99
// B2,1,14.50
همچنین مستندات رسمی نکاتی مثل تغییر جداکننده (delimiter) برای توکن‌های کمتر، بررسی تعداد توکن‌ها و برگشت از TOON به JSON را بیان کرده‌اند.جمع‌بندیTOON را می‌توان به عنوان یکی از ابزارهای جدید در جعبه ابزار مهندسی داده برای تعامل با مدل‌های زبانی دانست:اگر دادهٔ شما یکنواخت»، ساختارمند»، ارسالی به LLM دارد، TOON می‌تواند صرفه‌جویی توکنی زیادی به همراه آورد.اگر داده شما پیچیده، گردش‌کاری (workflow) برنامه‌ای سنتی یا ذخیره‌سازی است، شاید بهتر باشد از قالب‌های رایج‌تر استفاده کنید.در نهایت، TOON نه تهدیدی برای JSON است، بلکه مکملی برای موقعیت‌های خاص است. اگر در پروژه‌‌ی شما ارسال داده به مدل‌های زبانی بخش مهمی است، توصیه می‌کنم حتماً یک آزمایش با TOON انجام دهید و تعداد توکن‌ها، سرعت تحلیل مدل و خطاها را مقایسه کنید.منابع و لینک‌ها۱. مخزن رسمی TOON در گیت‌هابhttps://github.com/toon-format/toon</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 14 Nov 2025 21:49:08 +0330</pubDate>
            </item>
                    <item>
                <title>پترن های مهم هم‌زمانی در گولنگ - قسمت اول</title>
                <link>https://virgool.io/@h.agharezaei/%D9%BE%D8%AA%D8%B1%D9%86-%D9%87%D8%A7%DB%8C-%D9%85%D9%87%D9%85-%D9%87%D9%85-%D8%B2%D9%85%D8%A7%D9%86%DB%8C-%D8%AF%D8%B1-%DA%AF%D9%88%D9%84%D9%86%DA%AF-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-ntxindj1xlhq</link>
                <description>Pattern 1: Fan-out / Fan-inFan-out / Fan-inبریم سراغ اولین پترن: Fan-out / Fan-in — یکی از پایه‌ای‌ترین و در عین حال قدرتمندترین الگوهای هم‌زمانی در گولنگ. توضیحوقتی یک goroutine داده تولید می‌کنه و چند goroutine هم‌زمان اون داده‌ها رو پردازش می‌کنن (fan-out)،و بعد نتایج همه‌شون به یک کانال نهایی جمع می‌شه (fan-in).تعریف سادهFan-out یعنی: چند goroutine به‌صورت موازی از یک منبع داده (channel) داده می‌خوانند.Fan-in یعنی: نتایج چند goroutine در یک channel نهایی ادغام می‌شود.دیاگرام ذهنی            +------------+
            |   Source   |
            +------------+
                   |
                   v
     +-----------------------------+
     |       Fan-out Workers       |
     | +--------+ +--------+ +--------+
     | |Worker1 | |Worker2 | |Worker3 |
     | +--------+ +--------+ +--------+
     +-----------------------------+
        \         |         /
         \        |        /
          \       |       /
           v      v      v
            +------------+
            |   Collector |
            +------------+
مثال کدفرض کن می‌خوای اعداد ۱ تا ۳۰ رو بررسی کنی که آیا عدد اول (prime) هستن یا نه.برای اینکه کار سریع‌تر انجام بشه، از ۳ goroutine استفاده می‌کنیم که هم‌زمان این کار رو انجام بدنpackage main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
)

// تابعی برای بررسی عدد اول بودن
func isPrime(n int) bool {
	if n &lt; 2 {
		return false
	}
	for i := 2; i*i &lt;= n; i++ {
		if n%i == 0 {
			return false
		}
	}
	return true
}

// تولید اعداد
func generateNumbers(nums ...int) &lt;-chan int {
	out := make(chan int)
	go func() {
		for _, n := range nums {
			out &lt;- n
		}
		close(out)
	}()
	return out
}

// worker که عدد می‌گیره و اگر اول بود، در خروجی می‌فرسته
func checkPrime(in &lt;-chan int) &lt;-chan int {
	out := make(chan int)
	go func() {
		for n := range in {
			if isPrime(n) {
				out &lt;- n
			}
		}
		close(out)
	}()
	return out
}

// ادغام چند channel خروجی در یک channel
func merge(cs ...&lt;-chan int) &lt;-chan int {
	var wg sync.WaitGroup
	out := make(chan int)

	output := func(c &lt;-chan int) {
		for n := range c {
			out &lt;- n
		}
		wg.Done()
	}

	wg.Add(len(cs))
	for _, c := range cs {
		go output(c)
	}

	go func() {
		wg.Wait()
		close(out)
	}()
	return out
}

func main() {
	// Fan-out: چند goroutine روی یک ورودی مشترک کار می‌کنن
	in := generateNumbers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)

	c1 := checkPrime(in)
	c2 := checkPrime(in)
	c3 := checkPrime(in)

	// Fan-in: ادغام همه‌ی خروجی‌ها
	out := merge(c1, c2, c3)

	for n := range out {
		fmt.Println(n)
	}
}
توضیح عملکردgenerateNumbers() → اعداد را تولید می‌کند و در channel می‌فرستد.checkPrime() → چند بار اجرا می‌شود (۳ worker داریم). هر worker از channel in می‌خواند و اگر عدد اول بود، در خروجی خودش می‌فرستد.merge() → تمام خروجی‌های workerها را یکی می‌کند (fan-in).در آخر، main تمام نتایج را از out می‌خواند.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Tue, 04 Nov 2025 22:38:24 +0330</pubDate>
            </item>
                    <item>
                <title>چرا تیم ها شکست می خورند</title>
                <link>https://virgool.io/@h.agharezaei/%DA%86%D8%B1%D8%A7-%D8%AA%DB%8C%D9%85-%D9%87%D8%A7-%D8%B4%DA%A9%D8%B3%D8%AA-%D9%85%DB%8C-%D8%AE%D9%88%D8%B1%D9%86%D8%AF-bx0y4fbwctry</link>
                <description>چرا تیم ها شکست می خورندسلام،تیم را می توانیم مجموعه از آدم های بدانیم که کنار هم جمع می شوند تا یک هدف خاص را دنبال کنند و همه اعضا روی آن هدف اتفاق نظر دارند و مهمترین شاخصه آنها رسیدن به هدف مشترک است.اما گاهی پیش می آید که این تیم ها موفق نمی شوند به هدفشان دست پیدا کنند در این پست می خواهم دلایلی که باعث شکست یک تیم می شود را با هم بررسی کنیم عدم داشتن دورنمای یکسان از هدف، اولین چیزی که باعث شکست یک تیم می شود نداشتن یک تصویر یکسان از هدف می باشد یعنی هر مدام از اعضای تیم تصویری متفاوت از هم دارند و شاید هم بعضی از اعضا تصویری مبهم از هدف داشته باشند. برای اینکه بتوانیم یک تیم موفق  داشته باشیم ابتدا باید تصویر واضح و شفافی برای همه اعضا تیم ار هدف ایجاد کنیم.بی احترامی، هر عضو تیم یک شخصیت و حریم برای خود دارد رفتار های که باعث ایجاد بر هم زدن این حریم شود تاثیر منفی در ادامه همکاری ایجاد می کند همواره اعضای تیم باید احترام دیگر اعضا را رعایت کنند.عجز در بخشش یکدیگر، همواره در هر اجتماعی که شکل می گیرد سو تفاهماتی اتفاق می افتد اگر اعضا تیم نتوانند همدیگر را ببخشند بازنده اصلی تمام تیم خواهد بود.رهبری و مدیریت ضعیف، گرد هم نگه داشتن  انسان ها بعلت تفاوت های که هر شخص دارد کار سختی می باشد داشتن هدف مشخص دلیل جمع شدن افراد دور همدیگر و ایجاد تیم است و رهبری و مدیریت دلیل کنار هم ماندن افراد تا رسیدن به هدف می باشد هر چه ضعف های رهبری کمتر باشد تیم موفق تری خواهیم داشت.تعصب بی جا، یکی از افت های مهم در هر تیم خود سر بودن و تعصب بی جای افراد می باشد که باعث فروپاشی تیم می گردد.مواردی که در این نوشتار مطرح شد تعداد اندکی از دلایل شکست تیم ها است. اگر شما هم موردی دارید در یادداشت ها با من در میان بگذارید.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Wed, 25 Nov 2020 14:41:14 +0330</pubDate>
            </item>
                    <item>
                <title>زبان های برنامه نویسی ابزار های ما هستند</title>
                <link>https://virgool.io/fboard/%D8%B2%D8%A8%D8%A7%D9%86-%D9%87%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%A7%D8%A8%D8%B2%D8%A7%D8%B1-%D9%87%D8%A7%DB%8C-%D9%85%D8%A7-%D9%87%D8%B3%D8%AA%D9%86%D8%AF-ikzq71f0iihz</link>
                <description>زبان های برنامه نویسی ابزار های ما هستندتعصب روی یک زبان برنامه نویسی برای بعضی از افراد حکم خاصی دارد مخصوصا برای افرادی که تازه شروع به کار برنامه نویسی کرده اند و در این مسیر اول راه هستند، زبان های برنامه نویسی برای یک برنامه نویس مانند ابزار های هستند که هر کدام با توجه به پروژه می توانند باعث تسریع روند انجام پروژه شوند. مانند یک مکانیک که ست ابزار های کاملی دارد و بعضی از ابزار ها را به ندرت در طول عمری کاریش مورد استفاده قرار می دهد یک برنامه نویس نیز باید با تمام زبان های برنامه نویسی آشنایی داشته باشد و با توجه به کسب و کاری که در آن کار می کند به یک زبان تسلط کامل داشته باشد که به آن مهارت T شکل گفته می شود.هر زبان برنامه نویسی برای حل یک گروه از مشکلات بهینه شده است و بهترین ابزار برای حل آن نوع مشکل می باشد، درست است که شاید با یک زبان بتوان همه نوع مسئله ای را حل کرد و برای آن کد نوشت ولی اگر به زمانی که صرف کدنویسی و پرفورمنسی که کد نوشته شده دارد دقت کنیم می بینیم که کار درستی انجام نداده ایم.نرم افزار های بزرگ متشکل از کامپوننت های هستند که شاید هر کدام منطق خاص خود را داشته باشند و با یک زبان خاصی پیاده سازی شده باشند.بهتر است برای کد نویسی بجای تعصب به یک زبان روی حل مشکل با بهینه ترین حالت تمرکز کنیم تا یک ابزار مناسب(زبان برنامه نویسی) را انتخاب کنیم .نکته آخر اینکه در خصوص پایگاه های داده نیز مطالب بالا صادق است.روز خوبی داشته باشید.</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Tue, 17 Sep 2019 09:20:30 +0430</pubDate>
            </item>
                    <item>
                <title>تابع جستجوی دودویی در php</title>
                <link>https://virgool.io/@h.agharezaei/%D8%AA%D8%A7%D8%A8%D8%B9-%D8%AC%D8%B3%D8%AA%D8%AC%D9%88%DB%8C-%D8%AF%D9%88%D8%AF%D9%88%DB%8C%DB%8C-%D8%AF%D8%B1-php-kdwp43rhdg6i</link>
                <description>جستجوی دودویییکی از الگوریتم های خوب برای جستجو ، الگوریتم جستجوی دودویی هست پیاده سازی این الگوریتم رو در زبان php در زیر براتون آوردم&lt;?php function binarySearch(Array $arr, $x) { 	// check for empty array 	if (count($arr) === 0) return false; 	$low = 0; 	$high = count($arr) - 1; 	while ($low &lt;= $high) { 		// compute middle index 		$mid = floor(($low + $high) / 2);                 // element found at mid 		if($arr[$mid] == $x) { 			return true; 		}                 if ($x &lt; $arr[$mid]) { 			// search the left side of the array 			$high = $mid -1; 		} 		else { 			// search the right side of the array 			$low = $mid + 1; 		} 	} 		// If we reach here element x doesnt exist 	return false; } // Driver code $arr = array(1, 2, 3, 4, 5); $value = 5; if(binarySearch($arr, $value) == true) { 	echo $value.&quot; Exists&quot;; } else { 	echo $value.&quot; Doesnt Exist&quot;; } ?&gt; </description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Fri, 19 Jul 2019 22:12:00 +0430</pubDate>
            </item>
                    <item>
                <title>گرفتن همه متد های یک کلاس در php</title>
                <link>https://virgool.io/@h.agharezaei/%DA%AF%D8%B1%D9%81%D8%AA%D9%86-%D9%87%D9%85%D9%87-%D9%85%D8%AA%D8%AF-%D9%87%D8%A7%DB%8C-%DB%8C%DA%A9-%DA%A9%D9%84%D8%A7%D8%B3-%D8%AF%D8%B1-php-pxob0v47f6ln</link>
                <description>php class methodsگاهی وقت ها نیاز هست تا تمام متد های یک کلاس را بدست بیاوریم مثلا زمانی که از یک کتابخانه خارجی داریم استفاده می کنیم$object = new {class()};
$array_methods = get_class_methods($object);
print_r($array_methods);</description>
                <category>Roham</category>
                <author>Roham</author>
                <pubDate>Thu, 18 Jul 2019 21:34:41 +0430</pubDate>
            </item>
            </channel>
</rss>