softwarephilosophy | Unsorted

Telegram-канал softwarephilosophy - Software Philosophy

3509

چکیده‌ای از مفاهیم به روز مهندسی نرم افزار برای مهندسین نرم‌افزار. معماری نوین نرم‌افزار، تکنولوژی‌های برنامه نویسی جدید

Subscribe to a channel

Software Philosophy

"I'd love an AI assistant for my listings, but I don't have a developer" is something we hear constantly from real estate agents.

Dubai Radar is proof: you don't need a developer to build this.

🔗 Try Dubai Radar:
https://crysta.live/go/dubai-radar

Here's the thing: you don't need one.

Building an AI agent for your listings doesn't take a website, a budget for custom software, or someone on staff who codes. It takes a conversation. You describe what you need, Crysta builds it, you load in your actual listings, photos and all, and it's ready.

We're building one of these live next week, start to finish, for a real estate agent. If "I'm not technical enough for this" has been the thing stopping you, come watch what it actually takes.

📌 RSVP for the live workshop:
https://www.linkedin.com/events/7510707482923823104

#CrystaCode #Realestate #BuildWithAI #AIAgent #RealEstateAI #PropTech

Читать полностью…

Software Philosophy

نگو JEV بگو System One!

دنیل کانمن (Daniel Kahneman) توی کتاب معروفش «تفکر، سریع و کند» (Thinking, Fast and Slow) ذهن انسان را به دو بخش تقسیم می‌کنه:
- سیستم ۱ (System 1): تفکر سریع، خودکار، حسی و بدون زحمت؛ مثل تشخیص سریع حالت چهره یا انتخاب مسیر همیشگی.
- سیستم ۲ (System 2): تفکر کند، تحلیلی، متمرکز و نیازمند انرژی محاسباتی؛ مثل حل یک مسئله پیچیده ریاضی.

در دنیای هوش مصنوعی، بیشتر تمرکز ما تا الان روی مدل‌های زبانی بزرگ (LLMها) بوده که بیشتر شبیه به سیستم ۲ عمل می‌کنند؛ متنی تولید می‌کنند، استدلال می‌کنند، اما سنگین، کند و پرهزینه‌اند. ولی برای تصمیم‌گیری‌های لحظه‌ای، مسیریابی درخواست‌ها (Routing) و دسته‌بندی سریع (Classification)، واقعاً نیازی به لود کردن یا فراخوانی یک LLM غول‌پیکر نداریم. یعنی برای این قبیل کارها نیازی به هزینه‌های سنگین بابت GPT و Fable و ... نداریم.

تفاوت مدل‌های System 1 با LLMها چیست؟

- هدف: به جای تولید طولانی متن (Text Generation)، تمرکز روی تصمیم‌گیری آنی، سنجش احتمالات و اکشن‌های سریع است.
- سرعت و منابع: فوق‌العاده سبک و سریع هستند و می‌توانند با کمترین تاخیر (Latency) حتی روی سیستم‌های معمولی و لوکال اجرا شوند.

ورودی این مدل‌ها چگونه‌اند؟ (خیلی ساده)

نیازی به پرامپت‌های پیچیده ندارید؛ ورودی‌ها معمولاً شامل:
۱. یک وضعیت یا متن ورودی (State/Body): مثلاً پیام کاربر.
۲. پرسش و گزینه‌ها (Questions/Choices & Criteria): معیارهای دسته‌بندی یا انتخابی که می‌خواهید مدل بین آن‌ها تصمیم بگیرد.

اما...
این حوزه فقط به یک معماری یا مدل خاص محدود نمی‌شود؛ امروزه خانواده‌ای از مدل‌های سبک و تخصصی تحت عنوان System 1 Models در حال شکل‌گیری هستند که عمدتا در مورد یک مدل از آن‌ها یعنی JEV شنیدیم ولی این سری از مدل‌ها به JEV خلاصه نمی‌شوند ...

معرفی Laya
یکی از گزینه‌های متن‌باز، سریع و کارآمد در این حوزه Laya است که می‌توانید آن را به راحتی برروی سیستم دسکتاپ خود اجرا کنید:

py3 -m pip install laya
pip install "laya[serve]"
py -m laya.serve


من یک نمونه کد ساده با C# / .NET پیاده‌سازی کردم که نحوه ارسال درخواست به سرور لوکال Laya و دریافت خروجی ساختارمند و تصمیم‌گیری آنی را نشون می‌دهد.

🔗 سورس‌کد و راهنمای کامل را می‌تونید در گیت‌هاب من ببینید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#حامد_حاجیلو (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

ورک‌شاپ «AI Agents in C# (MAF)»

در این ورک‌شاپ به بررسی امکانات جدید برنامه‌نویسی با کتابخانه‌ها و استانداردهای جدید AI در سی‌شارپ مخصوصا Microsoft Agent Framework می‌پردازیم.
با هم کد می‌زنیم و کمی حرفه‌ای‌تر، با معماری‌های مدرن این هوش‌مصنوعی در دنیای دات‌نت آشنا می‌شویم.

ارائه دهنده: مهران داودی
زمان: ۳۰ شهریور، ساعت ۲۰:۰۰ (به تایم ایران)
محل: LinkedIn Live

لینک ثبت‌نام رایگان:
https://www.linkedin.com/events/7504866466815582208

Читать полностью…

Software Philosophy

آشنایی با Attributeها در سی‌شارپ

در سی شارپ، Attributeها برای اضافه کردن metadata یا اطلاعات اضافی به بخش‌های مختلف برنامه استفاده می‌شوند.

این اطلاعات می‌توانند به عناصری مثل:
▫️کلاس‌ها (Classها)
▫️متدها (Methodها)
▫️ویژگی‌ها (Propertyها)
▫️فیلدها (Fieldها)
▫️اسمبلی‌ها (Assemblyها)

اضافه شوند و توسط Compiler یا با استفاده از Reflection در زمان اجرا خوانده شوند.

در سی‌شارپ Attributeهای مختلفی وجود دارند که هرکدام کاربرد خاصی دارند. برای مثال:

CLSCompliantAttribute
برای مشخص کردن این موضوع استفاده می‌شود که آیا کد با Common Language Specification (CLS) سازگار است یا نه. رعایت CLS باعث می‌شود کد بتواند در زبان‌های مختلف .NET مورد استفاده قرار بگیرد.

[assembly: CLSCompliant(true)]

public class Demo
{
public static void Main()
{
Console.WriteLine("This code is CLS-compliant");
}
}


FlagsAttribute

برای مشخص کردن اینکه یک enum می‌تواند به عنوان یک bit field استفاده شود و با عملیات bitwise ترکیب شود.
[Flags]
enum ColorsFlags
{
Red = 1,
Blue = 2,
Green = 4
}

با استفاده از [Flags]، مقدار ترکیبی enum به شکل خواناتری نمایش داده می‌شود.

ObsoleteAttribute
برای مشخص کردن کدهای قدیمی (deprecated) استفاده می‌شود. کامپایلر می‌تواند هنگام استفاده از این بخش‌ها هشدار یا خطا ایجاد کند.

[Obsolete("Use NewMethod instead", true)]
static void OldMethod()
{
}


همچنین در سی‌شارپ امکان ساخت Custom Attributeها وجود دارد.
برای این کار:
یک کلاس از System.Attribute ارث‌بری می‌کنیم. با AttributeUsage مشخص می‌کنیم Attribute کجا قابل استفاده است. Constructor و Propertyهای مورد نیاز را تعریف می‌کنیم.مثال:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class InfoAttribute : Attribute
{
public string Author { get; }
public string Version { get; }

public InfoAttribute(string author, string version)
{
Author = author;
Version = version;
}
}


🔗 جزئیات بیشتر را در این لینک بخوانید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#کامیار_شکیب (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

ایجنت‌ها دارن بزرگ می‌شن، از پرامپت تا لوپ تا گراف

اولش همه‌چیز ساده بود: یه پرامپت می‌دادیم، یه جواب می‌گرفتیم. اما کم‌کم کارها پیچیده‌تر شدن؛ چند مرحله، چند ابزار، چند تصمیم. اینجا بود که Agent Loop وارد شد و به ایجنت‌ها «قدرت ادامه دادن» داد.

اما یک حقیقت مهم وجود دارد: بعضی کارها ساختار خودشان را دارند.

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

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

گراف ایجنت را باهوش‌تر نمی‌کند. فقط کار را از حدس زدن نجات می‌دهد و اجرای ایجنت را قابل اعتماد، قابل کنترل و قابل پیش‌بینی می‌کند.
وقتی کار موازی است، وقتی چند شاخه دارد، وقتی verification لازم دارد، وقتی retry محدود دارد، وقتی human approval لازم دارد، لوپ دیگر جواب نمی‌دهد. اینجا باید کار را به گراف ارتقا داد.

🔗 در این مقاله موارد گفته شده به خوبی توضیح داده شده است.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy
_____

Читать полностью…

Software Philosophy

نگاهی دقیق به LLM‌ها

اجازه دهید با یک مثال شروع کنیم:
فرض کنید از هوش مصنوعی (AI) سوالی ریاضی پرسیده‌اید که می‌تواند به دو شکل زیر جواب دهد. به نظر شما کدام حالت بهتر و دقیق‌تر است؟ و چرا؟

❓ سوال کاربر:

Human: "Emily buys 3 apples and 2 oranges. Each orange costs $2. The total cost of all the fruit is $13. What is the cost of apples?"


💡 حالت اول (جواب مستقیم و سریع):

Assistant: "The answer is $3. This is because 2 oranges at $2 are $4 total. So the 3 apples cost $9, and therefore each apple is 9/3 = $3".


💡 حالت دوم (جواب مرحله‌به‌مرحله):

Assistant: "The total cost of the oranges is $4. 13 - 4 = 9, the cost of the 3 apples is $9. 9/3 = 3, so each apple costs $3. The answer is $3".


شاید در ظاهر هر دو به جوابی درست (۳ دلار) رسیده باشند، ولی از نظر نحوه کارکرد هوش مصنوعی، حالت دوم به مراتب بهتر است!

هدف از طرح این سوال اشاره به دو موضوع مهم بود:
اول این که: شما نباید در محاسبات به gpt اعتماد کامل داشته باشید. همانطور که می‌دانید gpt در واقع چیزی نیست جز یک ماشین که کلمه (توکن) بعدی هر جمله رو بر اساس آمار حدس میزند (Token Autocomplete).

در مدل جواب دادن اول، احتمال این که به جواب اشتباهی برسیم زیاد بود؛ چون مدل مجبور بود کل بار محاسباتی مسئله را فقط در همان یک کلمه (توکنِ بعد از علامت $) فشرده کند و صرفاً جواب را حدس بزند.

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

کارپاتی جمله‌ای معروف دارد: «مدل‌ها برای فکر کردن به توکن نیاز دارند!» (Models need tokens to think). یعنی هر چه توکن بیشتری تولید کنند، فرصت و فضای بیشتری برای محاسبه دارند.

مثل ما انسان‌ها که ناگهانی و چشم‌بسته نمی‌توانیم جواب مسائل منطقی را سریع بگوییم و ذهنم شروع به مرحله‌به‌مرحله حساب کردن می‌کند، مدل‌های زبانی هم دقیقاً همینطور هستند، مانند جواب دوم در مثال اول متن.

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

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

مورد دوم این که: در چنین حالت‌هایی (مخصوصاً وقتی اعداد بزرگتر یا محاسبات پیچیده‌تر می‌شوند)، حتی بهتر است مثلا در chat gpt در انتها بگویید: use code. در این حالت، مدل دیگر به «محاسبات ذهنی» خود (که در بسیاری از مواقع خطا دارد) تکیه نمی‌کند؛ بلکه خود برای این موضوع کدی ساده به زبان پایتون می‌نویسد، اجرا می‌کند و نتیجه دقیق را به شما می‌گوید و شما از جواب chat gpt مطمئن هستید و احتمال خطا به صفر می‌رسد.

🔗 این نکات جذاب از ویدیوی Andrej Karpathy در آمده است که ویدیویی ۳ ساعته است و برای درک عمیق و دقیق LLMها بسیار کمک می‌کند که باعث می‌شود ما خیلی بهتر و اصولی‌تر با ابزارهای AI کار کنیم.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#حامد_حاجیلو (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

ما اخیراً سیستم‌های AI خودمون رو به MAF منتقل کردیم و واقعاً فوق‌العاده بوده!



این جمله واسه من نیست. کامنت @CrystaCode تویOn .NET Live بود :) البته من ترجمش رو گذاشتم اینجا...

در این ویدیو Daniel Costea، در مورد ساختار Middleware ها در Microsoft Agentic Framework صحبت می‌کند.

او Middlewareها را به سه نوع تقسیم می‌کند و با مدل ذهنی prepare → handle → invoke توضیح می‌دهد؛ مدلی که برای هر کسی که قبلاً با Middleware در ASP.NET Core کار کرده، کاملاً آشناست:

اولین مورد Shared Function Middleware نزدیک‌ترین لایه به Request است. این Middleware از یک pipeline استفاده می‌کند و می‌تواند پیام‌های ورودی را بررسی و فیلتر کند، اما Response را نمی‌بیند.
به همین دلیل جای مناسبی برای Guardrailهای ورودی محسوب می‌شود؛ مثلاً حذف اطلاعات شخصی (PII) یا آدرس ایمیل قبل از اینکه اصلاً به مدل ارسال شوند.


دومین Response Middleware یک قدم فراتر می‌رود. در حالی که همچنان مثل یک pipeline عمل می‌کند، می‌تواند Response کامل را هم ببیند و حتی تغییرش دهد.
اینجا جایی است که می‌شود مشکلاتی مثل مصرف بیش‌ازحد Token را تشخیص داد و قبل از اینکه یک Call هزینه غیرضروری ایجاد کند، جلوی ادامه آن را گرفت. مثلا میشه Token Usage را هم بررسی و ذخیره کرد.

و در آخر Function Calling Middleware هم Tool Callها را با دسترسی کامل به Conversation History بررسی می‌کند.
در نتیجه، قبل از اجرای یک Tool می‌تواند یک Invocation پرریسک را Block کند، محدود کند یا حتی تغییر دهد. در Demo همین قابلیت باعث شد Agent مربوط به یک ماشین رباتیک، مستقیم با دنده عقب به دیوار برخورد نکند!

هرکدام از این Middlewareها می‌توانند در دو لایه مختلف اجرا شوند:
در ChatClient که Identity ندارد و می‌تواند بین چند Agent به اشتراک گذاشته شود و Agent که Session و Identity خود را دارد.

در مجموع یعنی ۶ نقطه مختلف برای Hook کردن Middleware.
ترتیب Middlewareها هم اهمیت زیادی دارد. اگر ترتیب درست نباشد، ممکن است یک Middleware بیشتر از چیزی که انتظار دارید اجرا شود.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#حامد_حاجیلو (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

🚀 @CrystaCode is officially open to everyone!
🔗 https://crystacode.ai

Читать полностью…

Software Philosophy

مدل Kimi K3 توسط Moonshot AI منتشر شد

این مدل با ۲.۸ تریلیون پارامتر، بزرگترین مدل متن‌باز جهان است.

ساختار فنی:
از معماری MoE استفاده می‌کند. برای هر توکن تنها ۱۶ اکسپرت از ۸۹۶ اکسپرت فعال می‌شوند. بر پایه Kimi Delta Attention ساخته شده و بازدهی مقیاس‌پذیری آن ۲.۵ برابر K2 است. پنجره زمینه ۱ میلیون توکنی دارد و درک تصویر به صورت بومی در آن ادغام شده است.

عملکرد و مقایسه:
در کدنویسی فرانت‌اند (Arena.ai) رتبه اول را کسب کرده و مدل‌های Claude Fable 5 و GPT-5.6 Sol را پشت سر گذاشته است.
در ارزیابی‌های SWE Marathon و Program Bench بالاترین عملکرد را دارد. در Terminal Bench 2.1 با اختلاف نیم امتیاز پس از GPT-5.6 Sol دوم است.
در رده‌بندی کلی Artificial Analysis در جایگاه سوم قرار دارد.

هزینه API
۳ دلار برای یک میلیون توکن ورودی و ۱۵ دلار برای یک میلیون توکن خروجی. در اجرای تسک‌های برنامه‌نویسی ۶۰ تا ۸۰ درصد ارزان‌تر از مدل‌های رقیب تموم می‌شود.

البته Open Source بودنش به این معنی نیست که می‌توانید روی کامپیوتر ران کنید! برای ران کردنش یک دیتاسنتر غول می‌خواهد. پس پول کم بدهید و اندازه Fable و Sol از این محصول استفاده کنید :)

🔗 توضیحات کامل را می‌توانید اینجا بخوانید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#حامد_حاجیلو (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

مفهوم Harness در دنیای AI

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

فکر کنید که GitHub Copilot یا Claude اگه فقط یک پرامپت بود که کل کد را به همراه پرامپت شما اجرا می‌کرد چقدر ناکارآمد بود.
مفهوم جالبی که این سیستم‌ها از آن استفاده می‌کنن تا مفاهیم non-determinstic دنیای AI را به مفاهیم deterministic دنیای واقعی نزدیک کنند مفهومی است به نام Harness.

جالب است بدانید که در GitHub Copilot برای هر مدل یک هارنس اختصاصی نوشته می‌شود و هر وقت یک مدل جدید از راه می‌رسد قبل اینکه آن مدل به VS Code اضافه شود اول هارنس اختصاصی‌ش نوشته می‌شود.

در این ویدئو مفهوم Harness خیلی خوب و قابل فهم توسط Tejas Kumar از IBM توضیح داده شده. اگر برنامه‌نویسی هستید که سیستم‌های مبتنی بر LLM می‌نویسید که کار واقعی انجام می‌دهد (نه صرفا یه چت ساده برای دمو) پیشنهاد می‌کنم حتما این ویدئو را ببینید.

این مفهوم همان مفهومی است که ما در CrystaCode برای ساخت «ادیتور ایجنت» از آن استفاده کردیم تا بتوان روی عملکرد سیستم حساب کرد و طبق سناریوهای skUnit تست‌ها پاس شود.

🔗 ویدئو کامل را می‌توانید اینجا ببینید.

#مهران_داودی (لینکدین - بلاگ)

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

هوش مصنوعی در دات‌نت بدون پیچیدگی

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

در اکوسیستم دات‌نت مجموعه‌ای از ابزارها و کتابخانه‌های آماده وجود دارد که دقیقاً برای پاسخ‌دادن به همین نیازها طراحی شده‌اند. از ابزارهای پایه برای اتصال به مدل‌های هوش مصنوعی گرفته تا اجزای RAG برای مدیریت داده، فریم‌ورک ایجنت‌ها برای تعریف نقش‌های مختلف، و استانداردهایی مثل MCP و A2A برای اینکه ایجنت‌ها بتوانند با سرویس‌ها و حتی با یکدیگر تعامل داشته باشند.

برای شروع کافی است Microsoft.Extensions.AI را به پروژه اضافه کنید و یک چت‌بات ساده بسازید. خیلی زود متوجه می‌شوید که برای مدیریت بهتر وظایف، Microsoft.Agents.AI را هم نصب کرده‌اید و چند MCP مختلف برای هندل‌کردن فعالیت‌ها اضافه شده‌اند.

ما در crystacode.ai از این امکانات به‌صورت حرفه‌ای استفاده کرده‌ایم، از ساخت چت‌بات‌ها تا طراحی ایجنت‌های تخصصی و اتصال آن‌ها به سرویس‌های مختلف.

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

🔗 https://www.youtube.com/watch?v=LB64QnwhLZM

_____

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy
______

Читать полностью…

Software Philosophy

تغییرات اخیر دات‌نت ۱۱، Runtime, libraries, SDK for the AI Era (بیلد ۲۰۲۴)

در این ویدئو که قسمتی از کنفرانس BUILD 2026 است تغییرات اخیر دات‌نت ۱۱ بررسی می‌شود.
یکی از قسمت‌های جالب این تغییرات، بخش‌هایی هستند که به خاطر LLM ها به وجود آمده است. که در ادامه به چند مورد اشاره می‌کنم.

به عنوان مثال دستوراتی مثل dotnet run و dotnet build در حال حاضر با توجه به اینکه در چه کانتکستی اجرا می‌شوند، می‌توانند لاگ‌های متفاوتی تولید کنند. به طور پیش‌فرض این دستورات لاگ‌هایی تولید می‌کنند که وضعیت درونی را بیشتر توضیح می‌دهند (Live Update)، ولی این نوع لاگ‌ها برای LLM ها هم مفید نیست و هم باعث مصرف توکن بیشتر می‌شود. تکنیک جدید باعث می‌شود وقتی این دستورات توسط ابزارهای LLM استفاده می‌شوند توکن خیلی کمتری مصرف کنند!

مورد جالب دیگر تغییراتی است که توی dotnet build انجام شده که بیلدهای موازی که به خاطر agent ها بیشتر و بیشتر شده، با پرفورمنس بهتری اجرا می‌شوند.

همچنین در این جلسه در مورد Runtime Async صحبت می‌شود که بسیار فیچر مهمی است و نحوه اجرای کدهای async را از سطح کامپایلر به سطح ران‌تایم می‌برد که تغییر خیلی زیرساختی و تاثیرگذاری محسوب می‌شود، هم از لحاظ پرفورمنسی، و هم از لحاظ tooling. با این تغییر دیگر در Call Stack خبری از آن همه اطلاعاتی که به خاطر State Machine‌ به وجود آمده بود نیست و همه چیز خیلی خواناتر شده است.

🔗 ویدئو کامل را می‌توانید اینجا ببینید.

#مهران_داودی (لینکدین - بلاگ)

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

استفاده از Graphify در پروژه‌ها

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

کار این ابزار، یعنی Graphify این است که از Code Base شما گرافی تمیز می‌سازد و به خاطر همین، از این به بعد وقتی با Claude یا GitHub Copilot پرامپتی را ران می‌کنید، توکن‌های شما به مراتب کمتر استفاده می‌شود و سرعت و دقت پیدا کردن فایل‌های مرتبط هم بالاتر می‌رود.

🔗 در همین Repo در مورد نحوه استفاده صحبت شده است.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#حامد_حاجیلو (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

رقابت نسل پنجم هوش مصنوعی: GPT-5، Claude، Gemini و Grok

در سال ۲۰۲۵، رقابت بین شرکت‌های پیشرو در حوزه هوش مصنوعی وارد مرحله‌ی تازه‌ای شده. چهار مدل قدرتمند، GPT-5 از OpenAI، Claude Opus 4.1 از Anthropic، Gemini 2.5 Pro از Google DeepMind و Grok 4 از xAI، هرکدام با ویژگی‌های منحصربه‌فرد، در تلاش‌اند تا جایگاه برتر در مسیر توسعه‌ی AGI را تصاحب کنند.
مدل GPT-5 با دقت بالا، توانایی استدلال پیچیده و نرخ خطای بسیار پایین، در آزمون‌های علمی و کدنویسی عملکردی بی‌نظیر داشته است. این مدل در حل مسائل ریاضی، تولید متن‌های دقیق و تعامل چندرسانه‌ای پیشتاز است.
مدل Claude Opus 4.1 تمرکز ویژه‌ای بر ایمنی، شفافیت و اخلاق دارد. در محیط‌های حساس، پاسخ‌های محتاطانه و قابل اعتماد ارائه می‌دهد و در تولید کد نیز بسیار توانمند ظاهر شده است.
مدل Gemini 2.5 Pro با پنجره متنی عظیم و یکپارچگی کامل با محصولات گوگل، برای پردازش اسناد طولانی و ورودی‌های تصویری و صوتی انتخابی عالی و سرعت و دقت آن در محیط‌های کاری چشم‌گیر است.
مدل Grok 4 بیشتر برای تحلیل داده‌های زنده و شبکه‌های اجتماعی طراحی شده. پاسخ‌های سریع، خلاقانه و گاهی غیررسمی‌اش آن را برای کاربران عمومی جذاب کرده.

🔍 مقایسه تخصصی مدل‌های هوش مصنوعی نسل جدید

🎯 ۱. دقت و استدلال منطقی
- مدل GPT-5 در آزمون‌های ریاضی مثل AIME 2025 نمره کامل (100٪) کسب کرده و در استدلال چندمرحله‌ای با استفاده از تکنیک chain-of-thought به دقت 99.6٪ رسیده. این یعنی در حل مسائل پیچیده، تقریباً بی‌رقیب عمل می‌کند.
- مدل Claude Opus 4.1 در استدلال اخلاقی و تحلیل‌های مفهومی قوی ظاهر شده، اما در آزمون‌های ریاضی و فنی نمره‌ی پایین‌تری نسبت به GPT-5 داشته است (حدود 78٪).
- مدل Gemini 2.5 Pro عملکرد خوبی در تحلیل داده‌ها و استدلال دارد، اما در آزمون‌های تخصصی مثل GPQA یا AIME کمی عقب‌تر از GPT-5 و Grok قرار گرفته است.
- مدل Grok 4 با نمره 93٪ در آزمون AIME و 98٪ در HumanEval برای کدنویسی، نشان داده که در استدلال فنی و برنامه‌نویسی بسیار قدرتمند است.

🧠 ۲. ظرفیت حافظه و پردازش ورودی
- مدل Gemini 2.5 Pro با پنجره متنی ۱ میلیون توکن، رکورددار پردازش اسناد طولانی و دیتاست‌های حجیم است.
- مدل GPT-5 با ظرفیت ۴۰۰ هزار توکن، توانایی پردازش اسناد بزرگ را دارد ولی در مقیاسی پایین‌تر از Gemini.
- مدل Grok 4 ظرفیت ۲۵۶ هزار توکن دارد و برای پروژه‌های متوسط بسیار مناسب و مقرون‌به‌صرفه‌ست.
- مدل Claude Opus 4.1 با ظرفیت ۲۰۰ هزار توکن، بیشتر برای تحلیل‌های متنی و پاسخ‌های دقیق طراحی شده است.

🖼 ۳. توانایی چندرسانه‌ای و تولید محتوا

- مدل GPT-5 در ورودی‌های تصویری و صوتی بسیار قوی عمل می‌کند، اما هنوز قابلیت تولید ویدیو ندارد.
- مدل Gemini 2.5 Pro در ورودی‌های چندرسانه‌ای (تصویر، صوت، ویدیو) کامل‌ترین تجربه را ارائه می‌دهد.
- مدل Grok 4 تنها مدلی است که خروجی ویدیویی هم تولید می‌کند و برای تولید محتوای پویا بسیار مناسب است.
- مدل Claude محدود به متن و فایل‌های ساده‌ست و در حوزه چندرسانه‌ای هنوز توسعه‌یافته نیست.

💰 ۴. هزینه و بهره‌وری
- مدل GPT-5 با قیمت حدود $1.25 برای ورودی و $10 برای خروجی به‌ازای هر میلیون توکن، گزینه‌ای اقتصادی برای شرکت‌هاست.
- مدل Claude و Grok هزینه‌ی بالاتری دارند (حدود $3 ورودی و $15 خروجی)، اما در پروژه‌های خاص مثل امنیت یا کدنویسی دقیق، ارزش افزوده دارند.
- مدل Gemini با هزینه‌ی بسیار پایین‌تر (تا ۲۰ برابر کمتر از Claude)، برای استارتاپ‌ها و پروژه‌های مقرون‌به‌صرفه انتخابی عالی است.

🧪 ۵. کاربرد تخصصی
- مدل GPT-5 برای پروژه‌های چندمنظوره، تحقیقاتی، پزشکی و امنیتی عالی است.
- مدل Claude برای محیط‌های حساس، اخلاق‌محور و تحلیل‌های دقیق توصیه می‌شود.
- مدل Gemini مناسب برای پردازش‌های حجیم، ادغام با ابزارهای گوگل و توسعه‌ی سریع است.
- مدل Grok برای تحلیل داده‌های زنده، شبکه‌های اجتماعی و تولید محتوای خلاقانه بسیار کاربردی است.

مطالعه بیشتر
___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

________

Читать полностью…

Software Philosophy

هوش مصنوعی، آماده‌ی آزمون؟ با skUnit بررسی‌اش کن!

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

🎬 داستان از کجا شروع شد؟
در دنیای دات‌نت، تست‌نویسی همیشه بخشی جدی و خشک بوده. اما وقتی پای هوش مصنوعی وسط می‌آیدد، دیگر نمی‌توانید فقط بگویید "این تابع درست کار کرد یا نه؟" باید بپرسید:
❓ آیا مدل واقعاً فهمید کاربر چه گفت؟
❓ آیا جوابش منطقی بود؟
❓ آیا توانست با ظرافت تابعی خاص را صدا بزند؟

حساسیت جایی بالاتر می‌رود که وقتی تغییری ایجاد می‌کنید و عمرا به سادگی بفهمدی تمام تغییرات قبلی درست کار می‌کند یا نه!

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


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

🔗 پیشنهاد می‌کنم سری به گیت‌هاب skUnit بزنین.
___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

________

Читать полностью…

Software Philosophy

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

بدون یک خط کد نویسی!

منتظرتونیم :)

Читать полностью…

Software Philosophy

بازنویسی کل GitHub Copilot Runtime با Rust

🔶 حدود ۱۲۰،۰۰۰ دلار هزینه توکن و سه هفته وقت یک برنامه‌نویس، هزینه این مایگرشن بوده است.

🔷 در این بلاگ، Stephen Toub توضیح داده که چطور کدهای GitHub Copilot Runtime (حدود ۸۰۰هزار خط کد) رو به #rust مایگریت کرده‌اند (از #typescript و #nodejs).

▫️ در بخش‌هایی از این بلاگ قشنگ معلومه استفن از دست node.js و محدودیت‌هاش عصبانی بوده!

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

#مهران_داودی (لینکدین - بلاگ)

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

کد مدریت شده (Managed Code) در دات‌نت یعنی چی؟

▫️به زبان ساده:
کد مدریت شده (Managed Code) یعنی کدی که اجرای آن توسط یک Runtime مدیریت می‌شود.

در دنیای دات‌نت، این Runtime همان CLR (Common Language Runtime) است.
مثلاً وقتی با سی‌شارپ کد می‌نویسیم، کدم مستقیماً به Machine Code تبدیل نمی‌شود.

مسیر کلی به این شکل است:

C# → Compiler → IL → CLR → JIT → Machine Code → CPU

🔹 زبان میانی (Intermediate Language یا IL) — ای‌ال
بعد از اینکه برنامه سی‌شارپ کامپایل می‌شود، خروجی مستقیماً Machine Code نیست؛ بلکه کدی به نام IL تولید می‌شود.

🔹 محیط اجرای .NET (Common Language Runtime یا CLR)
سی ال ار (CLR) همان Runtime دات‌نت است که اجرای Managed Code را مدیریت می‌کند و سرویس‌هایی مثل مدیریت حافظه و Type Safety را فراهم می‌کند.

🔹 کامپایلر در زمان اجرا (Just-In-Time یا JIT)
جیت (JIT) در زمان اجرای برنامه، IL رو به Machine Code تبدیل می‌کند تا CPU بتواند آن را اجرا کند.

🔹 مدیریت حافظه (Memory Management)
یکی از مزیت‌های مهم Managed Code این است که Runtime می‌تواند مدیریت حافظه را انجام دهد؛ مثلاً Garbage Collector حافظه‌ای را که دیگر استفاده نمی‌شود، برای آزادسازی مدیریت می‌کند.

🔵 کد مدیریت‌شده در مقابل کد مدیریت‌نشده
در برنامه‌های Native مثل C و ++C، کد معمولاً مستقیماً به Machine Code تبدیل می‌شود و مسئولیت‌های بیشتری مانند مدیریت حافظه بر عهده برنامه‌نویس است.
اما در دات‌نت مسیر به این شکل است:

C# → IL → CLR → Machine Code

به همین دلیل به کدی که اجرای آن تحت مدیریت CLR انجام می‌شود، Managed Code می‌گوییم.

🔗 جزئیات بیشتر را در این لینک بخوانید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#کامیار_شکیب (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

اگر در دات نت Agent، MCP Server یا ابزارهای مبتنی بر هوش مصنوعی توسعه میدهی، این پروژه میتواند تست نویسی را ساده تر کند.

ریپو skUnit یک فریمورک برای تست برنامه های مبتنی بر AI در .NET است که به جای کدنویسی پیچیده، تست ها را با Markdown مینویسد و از xUnit، NUnit و MSTest پشتیبانی میکند. همچنین میتواند Agentها، ‌IChatClient، MCP Serverها و سایر یکپارچه سازی های AI را تست کند.

https://github.com/mehrandvd/skunit⁠

@RepoFA

Читать полностью…

Software Philosophy

کنترل جریان (Flow Control) در سی‌شارپ

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

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

در سی‌شارپ، Flow Control به ما اجازه می‌دهد مسیر اجرای برنامه را مدیریت کنیم.

انواع اصلی Flow Control در C# شامل موارد زیر هستند:

۱. دستورات شرطی (Conditional Statements)

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

انواع دستورات شرطی در سی‌شارپ:
if
if-else
else if
switch
عملگر شرطی (Conditional Operator ?:)

مثال:

int number = 10;

if (number == 10)
{
Console.WriteLine("Number is 10");
}
else
{
Console.WriteLine("Number is not 10");
}


۲. دستورات حلقه (Looping Statements)

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

انواع حلقه‌ها در سی‌شارپ:

for
while
do-while
حلقه‌های تو در تو (Nested Loops)

مثال:
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}


خروجی:
0
1
2
3
4

۳. دستورات پرش (Jump Statements)

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

انواع دستورات پرش در سی‌شارپ:

break → پایان دادن به اجرای حلقه یا switch
continue → رد کردن اجرای فعلی حلقه و رفتن به مرحله بعد
return → خروج از متد و برگرداندن مقدار
goto → انتقال اجرای برنامه به یک بخش مشخص (که معمولاً استفاده از آن توصیه نمی‌شود)

for (int i = 0; i < 10; i++)
{
if (i == 5)
break;

Console.Write(i + " ");
}


خروجی:
0 1 2 3 4

🔗 جزئیات بیشتر را در این لینک بخوانید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#کامیار_شکیب (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

دستورها (Statementها) در زبان شی‌شارپ

یکی از مفاهیم پایه‌ای این زبان یعنی دستورها (Statement ها) است.
دستورها مشخص می‌کنند که برنامه چه کاری را انجام دهد. در واقع منطق و جریان اجرای برنامه‌های سی شارپ با استفاده از همین دستورها ساخته می‌شود.

چند نوع مهم از دستورها در سی‌شارپ:

تعریف متغیر (Declaration Statement)
برای ایجاد متغیر و مشخص کردن نوع آن استفاده می‌شود:

int age = 25;
string name = "Kamyar";


دستورهای عبارتی (Expression Statement)
برای انجام کارهایی مانند مقداردهی، تغییر مقدار متغیرها و اجرای متدها استفاده می‌شوند:

int number = 10;
number++;

Console.WriteLine(number);


دستورهای انتخابی (Selection Statement)
برای تصمیم‌گیری و اجرای کد بر اساس شرایط مختلف استفاده می‌شوند:
if (age >= 18)
{
Console.WriteLine("Adult");
}


دستورهای تکرار (Iteration Statement)
برای اجرای چندباره‌ی یک بخش از برنامه استفاده می‌شوند:
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}


دستورهای پرش (Jump Statement)
برای تغییر مسیر اجرای برنامه استفاده می‌شوند:
break;
continue;


دستورهای مدیریت خطا (Exception Handling Statement)
برای کنترل خطاهای احتمالی در برنامه استفاده می‌شوند:
try
{
// code
}
catch
{
// handle error
}


🔗 جزئیات بیشتر را در این لینک بخوانید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#کامیار_شکیب (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

دی‌کانستراکشن تاپل (Tuple Deconstruction) در سی‌شارپ

#csharp_for_beginners

قابلیت دی‌کانستراکشن تاپل (Tuple Deconstruction) از نسخه سی‌شارپ ۷.۰ به زبان سی‌شارپ اضافه شد. این قابلیت به شما اجازه می‌دهد اعضای یک Tuple را به‌طور هم‌زمان در چند متغیر مستقل قرار دهید. به این ترتیب دیگر نیازی نیست برای دسترسی به هر عضو از Item1، Item2 یا نام اعضای Tuple استفاده کنید و می‌توانید تمام مقادیر را تنها با یک دستور استخراج کنید.

به عنوان مثال، فرض کنید متد یک Tuple شامل اطلاعات یک حیوان خانگی را برمی‌گرداند:

(string Type, string Name, int Height, int Age, string Color) GetPet()
{
return ("Dog", "Max", 60, 4, "Brown");
}



می‌توان تمام مقادیر بازگشتی را به‌صورت هم‌زمان دریافت کرد:

(string type, string name, int height, int age, string color) = GetPet();



در این مثال، هر عضو Tuple مستقیماً در متغیر متناظر خود قرار می‌گیرد.

تعیین صریح نوع متغیرها
در این روش، نوع هر متغیر به‌صورت صریح داخل پرانتز نوشته می‌شود.

(string type, string name, int height, int age, string color) = GetPet();


مقدار اول در type
مقدار دوم در name
مقدار سوم در height
مقدار چهارم در age
مقدار پنجم در color

نادیده گرفتن اعضای غیرضروری با Discard

اگر به همه اعضای Tuple نیاز نداشته باشید، می‌توانید از Discard که با علامت _ نمایش داده می‌شود استفاده کنید.

(string type, _, int height, _, string color) = GetPet();



مقدار اول در type ذخیره می‌شود.
مقدار دوم نادیده گرفته می‌شود.
مقدار سوم در height قرار می‌گیرد.
مقدار چهارم نادیده گرفته می‌شود.
مقدار پنجم در color ذخیره می‌شود.

استفاده از _ باعث می‌شود مقدار مربوطه دریافت شود، اما در هیچ متغیری ذخیره نشود.

قوانین و محدودیت‌های دی‌کانستراکشن تاپل

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

- تعداد متغیرها باید با تعداد اعضای Tuple برابر باشد.

- اگر Tuple پنج عضو داشته باشد، باید در سمت چپ نیز پنج متغیر یا Discard (_) وجود داشته باشد.

نمونه صحیح:

(var type, var name, var height, var age, var color) = GetPet();


🔗 ویدئو را در این لینک می‌توانید می‌توانید مشاهده کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

آشنایی با Union Types در سی‌شارپ ۱۵

#csharp_for_beginners

یکی از قابلیت‌های جذابی که قرار است به سی‌شارپ ۱۵ اضافه شود، Union Types است. این ویژگی سال‌هاست در زبان‌هایی مانند TypeScript وجود دارد و به توسعه‌دهندگان اجازه می‌دهد نوعی تعریف کنند که بتواند یکی از چند نوع مشخص را در خود نگه دارد.

فرض کنید می‌خواهیم مجموعه‌ای از حیوانات خانگی را نگهداری کنیم:

List<object> pets =
[
new Dog("Fido"),
new Cat("tabby"),
new Bird { Species = "crow" }
];



در این مثال از List<object> استفاده کرده‌ایم چون اشیاء موجود در لیست از انواع مختلفی هستند.

اما این راهکار یک مشکل اساسی دارد؛ هر نوع شیء دیگری نیز می‌تواند وارد این لیست شود:

pets.Add(new Shark(300));



در حالی که کوسه (Shark) اصلاً جزو حیوانات خانگی موردنظر ما نیست.

برای پردازش این داده‌ها معمولاً از Pattern Matching استفاده می‌کنیم:

var description = pet switch
{
Dog dog => dog.Name,
Cat(var adjective) => $"A {adjective} cat",
Bird { Species: var species } => $"A {species}"
};


اما کامپایلر هیچ اطلاعی ندارد که چه نوع‌هایی مجاز هستند و چه نوع‌هایی نباید در این مجموعه قرار بگیرند.
راه‌حل: Union Types در سی‌شارپ ۱۵ می‌توان یک Union تعریف کرد:

union Pet(Dog, Cat, Bird);


این تعریف به کامپایلر اعلام می‌کند که نوع Pet فقط می‌تواند یکی از این سه نوع باشد:
اکنون می‌توان لیست را به شکل زیر تعریف کرد:
List<Pet> pets =
[
new Dog("Fido"),
new Cat("tabby"),
new Bird { Species = "crow" }
];


در این حالت اگر بخواهیم یک Shark به لیست اضافه کنیم، کامپایلر خطا خواهد داد؛ چون Shark جزو اعضای Union نیست.

یکی از مزیت های مهم Union Types این است که می‌توان مجموعه‌ای مشخص از انواع مرتبط را تحت یک نوع واحد تعریف کرد.

به همین دلیل هنگام استفاده از Switch Expression می‌تواند بررسی کند که آیا تمام حالت‌ها پوشش داده شده‌اند یا خیر.

برای مثال:

var description = pet switch
{
Dog dog => dog.Name,
Cat(var adjective) => $"A {adjective} cat",
Bird { Species: var species } => $"A {species}"
};

اگر یکی از انواع تعریف‌شده در Union را فراموش کنیم، کامپایلر هشدار نمایش خواهد داد.

این موضوع باعث می‌شود بسیاری از خطاها قبل از اجرای برنامه شناسایی شوند.

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

برای مثال:

union Pet(Dog, Cat, Bird)
{
public string Description => this switch
{
Dog dog => dog.Name,
Cat(var adjective) => $"A {adjective} cat",
Bird { Species: var species } => $"A {species}"
};
}



در این مثال ویژگی Description مستقیماً داخل Union تعریف شده است.

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

این ویژگی باعث می‌شود کدها تمیزتر و نگهداری آن‌ها ساده‌تر شود.

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

برای مثال:

[Union]
struct Result<T>
{
}


چرا Attribute-Based Union اهمیت دارد؟
این روش دو مزیت مهم دارد.

۱. بهبود کارایی (Performance)

بدون استفاده از union ها در برخی شرایط باعث Boxing می‌شود.

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

برای مثال اگر Union شما از چند Struct کوچک تشکیل شده باشد، جلوگیری از Boxing می‌تواند تأثیر قابل توجهی روی عملکرد برنامه داشته باشد.

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

این روش‌ها معمولاً پیچیده بودند و پشتیبانی مستقیمی از سوی کامپایلر نداشتند.
اما اکنون با استفاده از یک Attribute ساده می‌توان همان رفتار را به شکل رسمی و استاندارد پیاده‌سازی کرد.

🔗 ویدئو را در این لینک می‌توانید می‌توانید مشاهده کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

پیاده‌سازی Linked List در سی‌شارپ

#csharp_for_beginners

در این مقاله، ساختار دادهٔ LinkedList در زبان سی‌شارپ معرفی شده است. این ساختار یک لیست پیوندی دوطرفه (Doubly Linked List) است که امکان درج و حذف سریع عناصر را در هر نقطه از لیست فراهم می‌کند. برخلاف آرایه‌ها، عناصر در حافظه به‌صورت پشت‌سرهم ذخیره نمی‌شوند و هر عنصر در قالب یک گره (Node) نگهداری می‌شود.

ساختار LinkedList
هر گره در LinkedList<T> شامل سه بخش است:

مقدار داده (Value)
اشاره‌گر به گره قبلی (Previous)
اشاره‌گر به گره بعدی (Next)

به همین دلیل می‌توان در هر دو جهت لیست حرکت کرد.

ایجاد یک LinkedList

برای استفاده از این ساختار ابتدا باید فضای نام زیر را اضافه کنیم:


using System.Collections.Generic;



سپس لیست را ایجاد می‌کنیم:

LinkedList<int> list = new LinkedList<int>();


افزودن عناصر:


مهم‌ترین متدهای افزودن عنصر عبارت‌اند از:

افزودن در ابتدای لیست: ()AddFirst
افزودن در انتهای لیست: ()AddLast
افزودن قبل از یک گره مشخص: ()AddBefore
افزودن بعد از یک گره مشخص: ()AddAfter


نمونه کد:

LinkedList<int> list = new LinkedList<int>();

list.AddFirst(20);
list.AddLast(30);
list.AddLast(40);

foreach (int item in list)
{
Console.WriteLine(item);
}



خروجی:

20
30
40

برای حذف عناصر نیز متدهای مختلفی وجود دارد:

حذف اولین رخداد یک مقدار: Remove(T value)
حذف اولین گره: RemoveFirst()
حذف آخرین گره: RemoveLast()
حذف یک گره مشخص: Remove(LinkedListNode<T>)
حذف تمام عناصر لیست: Clear()

جستجوی عناصر
متد Contains() بررسی می‌کند که آیا یک مقدار در لیست وجود دارد یا خیر:

LinkedList<int> list = new LinkedList<int>();

list.AddLast(10);
list.AddLast(20);
list.AddLast(30);

Console.WriteLine(list.Contains(20));
Console.WriteLine(list.Contains(100));


خروجی:

True
False

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

کلاس Static در سی‌شارپ

#csharp_for_beginners

در زبان سی‌شارپ، کلاس Static کلاسی است که با کلیدواژه static تعریف می‌شود. این نوع کلاس فقط می‌تواند شامل اعضای استاتیک (مانند فیلدها، متدها، ویژگی‌ها و رویدادها) باشد و امکان ساختن شیء (Object) از آن وجود ندارد. اعضای آن مستقیماً از طریق نام کلاس فراخوانی می‌شوند.

تعریف کلاس Static:


static class Utility
{
public static void PrintMessage(string msg)
{
Console.WriteLine(msg);
}
}


استفاده:

Utility.PrintMessage("Hello World");


در این مثال، بدون ایجاد شیء از کلاس Utility، متد PrintMessage مستقیماً فراخوانی می‌شود.

ویژگی‌های مهم کلاس Static
▫️با کلمه کلیدی static تعریف می‌شود.
▫️تمام اعضای آن باید استاتیک باشند.
▫️نمی‌توان با new از آن نمونه‌سازی کرد.
▫️به صورت ضمنی sealed است؛ بنابراین قابل ارث‌بری نیست.
▫️نمی‌تواند از کلاس دیگری ارث ببرد.
▫️نمی‌تواند اعضای نمونه‌ای (Instance Members) داشته باشد.

فیلدها و ویژگی‌های Static
کلاس‌های استاتیک می‌توانند داده‌های مشترک در کل برنامه را نگهداری کنند:

static class Config
{
public static string AppName { get; set; } = "MyApp";
public static int Version { get; set; } = 1;
}


استفاده:

Console.WriteLine(Config.AppName);
Console.WriteLine(Config.Version);


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

محدودیت‌های کلاس Static
▫️امکان ایجاد شیء از آن وجود ندارد.
▫️نمی‌تواند اعضای غیراستاتیک داشته باشد.
▫️قابل ارث‌بری نیست.
▫️نمی‌تواند Interfaceها را پیاده‌سازی کند.


کاربردهای کلاس Static
▫️متدهای کمکی (Utility Methods) مانند توابع ریاضی.
▫️تنظیمات سراسری برنامه (Configuration).
▫️ثبت لاگ (Logging).
▫️توابعی که به وضعیت یک شیء وابسته نیستند.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

لینک (LINQ) در سی‌شارپ

#csharp_for_beginners

لینک (LINQ) یا Language Integrated Query قابلیتی در زبان سی‌شارپ است که امکان جستجو، فیلتر و پردازش داده‌ها را مستقیماً داخل خود زبان فراهم می‌کند.

در گذشته برای کار با منابع داده مختلف مثل SQL، XML یا سرویس‌های وب باید از زبان‌های جداگانه استفاده می‌شد، اما LINQ این مشکل را حل می‌کند و همهٔ عملیات کوئری‌نویسی را به شکلی یکپارچه داخل #C ارائه می‌دهد.

ویژگی‌های اصلی LINQ

▫️امکان نوشتن Query به صورت خوانا و کوتاه

▫️ پشتیبانی از Type Checking در زمان کامپایل

▫️استفاده یکسان برای انواع منابع داده

نمونه‌ای از LINQ :


int[] scores = [97, 92, 81, 60];

IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score;

foreach (var i in scoreQuery)
{
Console.Write(i + " ");
}


خروجی :

97 92 81

عملگر from منبع داده را مشخص می‌کند
عملگر where فیلتر را انجام می‌دهد
عملگر select دادهٔ نهایی را انتخاب می‌کند

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

آشنایی با Dictionary در سی‌شارپ

#csharp_for_beginners

در زبان برنامه‌نویسی سی‌شارپ، ساختار داده‌ی دیکشنری (Dictionary) برای ذخیره‌سازی اطلاعات به صورت «کلید و مقدار» استفاده می‌شود. هر کلید (Key) باید یکتا باشد و به یک مقدار (Value) اشاره کند. این ساختار در فضای نام System.Collections.Generic قرار دارد و به دلیل سرعت بالای جستجو، یکی از پرکاربردترین کالکشن‌ها در سی‌شارپ محسوب می‌شود.

مثال برای ساخت:

csharp

Dictionary<int, string> students = new Dictionary<int, string>();

در مثال بالا، نوع کلید int و نوع مقدار string است.

افزودن داده به Dictionary

برای اضافه کردن داده‌ها معمولاً از متد Add() استفاده می‌شود:
students.Add(1, "Ali");
students.Add(2, "Sara");
students.Add(3, "Reza");


نمایش اطلاعات Dictionary

برای نمایش عناصر از حلقه ها استفاده می‌شود:
foreach (var item in students)
{
Console.WriteLine($"Key: {item.Key}, Value: {item.Value}");
}


خروجی:

Key: 1, Value: Ali
Key: 2, Value: Sara
Key: 3, Value: Reza
Key: 4, Value: Mina


حذف عناصر

برای حذف یک عنصر:
students.Remove(1);


و برای حذف تمام داده‌ها:
students.Clear();


🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

آینده هوش مصنوعی و مهندسی کامپیوتر

هوش مصنوعی مهندسی را نابود نمی‌کند، اما در سکوت در حال از بین بردن چیزی بسیار مهم‌تر است: مسیر رشد نیروهای جونیور!

اخیرا که ویدئوی کنفرانس BUILD و صحبت‌های اسکات هنسلمن و مارک روسینوویچ را دیدم یکی از مهم‌ترین واقعیت‌ها درباره‌ی هوش مصنوعی در مهندسی را مطرح کردند؛ حقیقتی که باید بلندتر گفته شود، واقعیتی که بیشتر شرکت‌ها الان دیگر فهمیده‌اند:

هوش مصنوعی بهترین نتایجش را زمانی ارائه می‌دهد که مهندسان ارشد با آن کار می‌کنند.


اما در عین حال، هوش مصنوعی تقریبا تمام وظایف سطح جونیور را جایگزین کرده است: ایجاد ساختار اولیه، دیباگ، نوشتن کدهای تکراری (boilerplate)، تست کردن و غیره.
در نتیجه امروز بسیاری از تیم‌ها عملاً استخدام جونیورها را متوقف کرده‌اند. و این همان خطر واقعی است.

🔥 اگر امروز جونیورها حذف شوند، فردا سنیوری وجود نخواهد داشت.

بدون جونیور ⬅️ بدون نیروهای میانی ⬅️ بدون سنیور ⬅️ بدون آرشیتکت ⬅️ و در نهایت کسی نمی‌ماند که بتواند هوش مصنوعی را به ‌درستی هدایت کند.

ما هم این موضوع را از نزدیک دیده‌ایم. به همین دلیل در CrystaCode به‌طور جدی روز برنامه‌ی #cs_internship سرمایه‌گذاری می‌کنیم تا جریان پایداری از استعدادهای جونیور حفظ شود و مسیر واقعی رشد آن‌ها به نسل بعدی مهندسان ارشد فراهم گردد.

چون آینده‌ی مهندسی به کسانی بستگی دارد که هنوز سنیور نشده‌اند.

🔗 صحبت‌های اسکات هنسلمن و مارک روسینوویچ را در یوتیوب ببینید.

#مهران_داودی (لینکدین - بلاگ)

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

مفهوم Generics در سی‌شارپ

#csharp_for_beginners

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

در جنریک‌ها از پارامتر نوع (Type Parameter) استفاده می‌شود که معمولاً با حرف T نمایش داده می‌شود. این پارامتر هنگام ساخت شیء، با نوع واقعی داده جایگزین خواهد شد.

ساختار کلاس Generic
ساختار کلی یک کلاس جنریک به شکل زیر است:


class ClassName<T>
{
T data;

public ClassName(T value)
{
data = value;
}

public void Display()
{
Console.WriteLine(data);
}
}


در این مثال، T می‌تواند هر نوع داده‌ای مانند int، string یا حتی کلاس‌های سفارشی باشد.

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

جنریک (Generic) با چند پارامتر نوع
در سی‌شارپ می‌توان از چند پارامتر نوع نیز استفاده کرد:

class Pair<T1, T2>
{
public T1 First;
public T2 Second;

public Pair(T1 first, T2 second)
{
First = first;
Second = second;
}
}


نمونه استفاده:

Pair<int, string> pair = new Pair<int, string>(1, "One");


در این مثال، T1 برابر int و T2 برابر string خواهد بود.

کاربرد Generics در کتابخانه‌های سی‌شارپ

بسیاری از کلاس‌های آماده در فضای نام System.Collections.Generic بر پایه جنریک‌ها ساخته شده‌اند. برای مثال:

List<T>
Dictionary<TKey, TValue>
Queue<T>
Stack<T>

این کلاس‌ها امکان ذخیره و مدیریت داده‌ها را به صورت ایمن و بهینه فراهم می‌کنند.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______

Читать полностью…

Software Philosophy

گزارش از دیتابیس لازم داری؟ فقط حرف بزن!

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

مرحله اول: دریافت ساختار دیتابیس
برای اینکه GPT-4 بتواند کوئری دقیق تولید کند، ابتدا باید ساختار جدول‌ها و ستون‌ها را بشناسد. با استفاده از EF Core، می‌توان لیستی از جدول‌ها و فیلدها را استخراج کرد و به مدل ارسال کرد.

public async Task<string> GetAllTableSchemas()
{
// دریافت اطلاعات جدول‌ها از دیتابیس
}


مرحله دوم: تبدیل زبان طبیعی به SQL
در این مرحله، جمله‌ای مانند "نمایش مشتریانی که بیش از ۵ خرید داشته‌اند" به GPT-4 ارسال می‌شود. مدل با توجه به ساختار دیتابیس، کوئری SQL مناسب تولید می‌کند.
public async Task<string> GenerateSQLQuery(string userPrompt)
{
var prompt = $"Given the following database schema: {schema}, write a SELECT SQL query for: {userPrompt}";
var response = await openAiClient.GetCompletionAsync(prompt);
return response.Text;
}


مرحله سوم: اجرای کوئری و نمایش نتیجه
کوئری تولیدشده روی دیتابیس اجرا می‌شود و نتیجه به کاربر نمایش داده می‌شود. این بخش می‌تواند به‌صورت جدول، نمودار یا حتی فایل خروجی طراحی شود.
public async Task<DataTable> ExecuteQuery(string sql)
{
using var connection = new NpgsqlConnection(connectionString);
var command = new NpgsqlCommand(sql, connection);
var reader = await command.ExecuteReaderAsync();
// تبدیل نتیجه به DataTable
}



⚠️ نکته‌ای که باید در نظر بگیرید این است که فقط کوئری‌های SELECT مجاز هستند تا از تغییر یا حذف داده‌ها جلوگیری شود.

برای دیدن نمونه عملی این پروژه، مقاله اصلی در DZone را ببینید.

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

________

Читать полностью…
Subscribe to a channel