مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 3 - Middleware چیست؟
پیشنیازها
- «با HttpHandler بیشتر آشنا شوید»
یکی از بزرگترین تغییرات ASP.NET Core نسبت به نگارش‌های قبلی آن، مدیریت HTTP pipeline آن است. به عنوان یک توسعه دهنده‌ی ASP.NET به طور قطع با مفاهیمی مانند HttpHandler و HttpModules آشنایی دارید و ... هر دوی این‌ها با نگارش جدید ASP.NET حذف و با مفهوم جدیدی به نام Middleware جایگزین شده‌اند.
 - HttpHandlerها عموما مبتنی بر پسوندهای فایل‌ها عمل می‌کنند. برای نمونه، رایج‌ترین آن‌ها ASP.NET page handler است که هرگاه درخواستی، ختم شده‌ی به پسوند aspx، به موتور ASP.NET Web forms وارد شد، به این page handler، جهت پردازش نهایی هدایت می‌شود. محل تنظیم آن‌ها نیز در فایل web.config است.
 - HttpModuleها مبتنی بر رخدادها عمل می‌کنند. HttpModuleها به عنوان جزئی از request pipeline عمل کرده و دسترسی کاملی دارند به رخدادهای طول عمر درخواست رسیده. آن‌ها را می‌توان توسط فایل‌های global.asax و یا web.config تنظیم کرد.
 - MiddleWareها را که جزئی از طراحی OWIN نیز هستند، می‌توان به عنوان کامپوننت‌های کوچکی از برنامه که قابلیت یکپارچه شدن با HTTP request pipeline را دارند، درنظر گرفت. عملکرد آن‌ها ترکیبی است از هر دوی HttpHandler و HttpModule‌ها که در نگارش‌های قبلی ASP.NET مورد استفاده بودند. از MiddleWareها می‌توان برای پیاده سازی اعمال مختلفی جهت پردازش درخواست‌های رسیده مانند اعتبارسنجی، کار با سشن‌ها، ثبت وقایع سیستم، مسیریابی و غیره استفاده کرد. OWIN یا Open Web Interface for .NET به توسعه دهنده‌ها امکان غیروابسته کردن برنامه‌ی ASP.NET خود را از وب سرور مورد استفاده می‌دهد. به علاوه OWIN امکان پلاگین نویسی اجزای مختلف برنامه را بدون وابسته کردن آن‌ها به یکدیگر فراهم می‌کند. برای مثال می‌توان یک پلاگین logger را تهیه کرد تا اطلاعات مختلفی را از درخواست‌های رسیده ثبت کند.



مواردی که با ارائه‌ی ASP.NET Core 1.0 حذف شده‌اند

- System.Web: یکی از اهداف اصلی OWIN، مستقل کردن برنامه‌ی وب، از هاست آن است تا بتوان از وب سرورهای بیشتری استفاده کرد. System.Web انحصارا برای IIS طراحی شده بود و در این نگارش دیگر وجود خارجی ندارد.
- HttpModules: با Middlewareها جایگزین شده‌اند.
- HttpHandlers: البته HttpHandlers از زمان ارائه‌ی اولین نگارش ASP.NET MVC، در چندین سال قبل منسوخ شدند. زیرا پردازش صفحات وب در ASP.NET MVC برخلاف وب فرم‌ها، از فایل‌هایی با پسوندهای خاص شروع نمی‌شوند و نقطه‌ی آغازین آن‌ها، اکشن متدهای کنترلرها است.
- فایل global.asax: با حذف شدن HttpModules، دیگر ضرورتی به وجود این فایل نیست.


شباهت‌های بینMiddleware و HttpModuleها

همانند HttpModuleها، Middlewareها نیز به ازای هر درخواست رسیده اجرا می‌شوند و از هر دو می‌توان جهت تولید response ایی خاص استفاده کرد.


تفاوت‌های بینMiddleware و HttpModuleها

- عموما HttpModule از طریق web.config و یا فایل global.asax تنظیم می‌شوند. اما Middlewareها تنها از طریق کد و در فایل Startup.cs برنامه‌های ASP.NET Core 1.0 قابل معرفی هستند.
- به عنوان یک توسعه دهنده، کنترلی را بر روی ترتیب اجرای انواع و اقسام HttpModuleها نداریم. این مشکل در Middlewareها برطرف شده و اکنون ترتیب اجرای آن‌ها، دقیقا مطابق ترتیب افزوده شدن و تعریف آن‌ها در فایل Startup.cs است.
- ترتیب اجرای HttpModuleها هرچه که باشد، برای حالت‌های request و response یکی است. اما ترتیب اجرای Middlewareهای مخصوص response، عکس ترتیب اجرای Middlewareهای مخصوص request هستند (تصویر ذیل).
- HttpModuleها را صرفا جهت اتصال کدهایی به رخدادهای طول عمر برنامه می‌توان طراحی کرد؛ اما Middleware مستقل هستند از این رخدادها.
- HttpModuleها به System.Web وابسته‌اند؛ برخلاف Middlewareها که وابستگی به هاست خود ندارند.



Middleware‌های توکار ASP.NET Core 1.0

ASP.NET Core 1.0 به همراه تعدادی Middleware توکار است؛ مانند:
- Authentication: جهت پشتیبانی از اعتبارسنجی
- CORS: برای فعال سازی Cross-Origin Resource Sharing
- Routing: جهت تعریف و محدود سازی مسیریابی‌های برنامه
- Session: برای پشتیبانی و مدیریت سشن‌های کاربران
- Diagnostics: پشتیبانی از صفحات خطا و اطلاعات زمان اجرای برنامه
و مواردی دیگر که برای توزیع فایل‌های استاتیک و یا مرور محتویات پوشه‌ها و امثال آن‌ها طراحی شده‌اند که در طی این مطلب و همچنین مطالب آتی، آن‌ها را بررسی خواهیم کرد.

یک مثال: اگر یک پروژه‌ی خالی ASP.NET Core 1.0 را در ویژوال استودیو ایجاد کنید، این پروژه قادر نیست حتی فایل‌های استاتیک مانند تصاویر، فایل‌های پیش فرض مانند index.html و یا قابلیت مرور ساده‌ی فایل‌های موجود در یک پوشه را ارائه دهد (حتی اگر به آن‌ها نیازی نداشته باشید).
طراحی این نگارش از ASP.NET، مبتنی است بر سبک وزن بودن و ماژولار بودن. هر قابلیتی را که نیاز دارید، باید middleware آن‌را نیز خودتان به صورت صریح اضافه کنید و یا در غیر اینصورت فعال نیست. برخلاف نگارش‌های قبلی ASP.NET که HTTP Module‌های از سشن گرفته تا اعتبارسنجی و غیره، همگی به صورت پیش فرض در فایل Web.Config فعال بودند؛ مگر اینکه آن‌ها را به صورت دستی حذف می‌کردید.



ثبت و فعال سازی اولین Middleware

در ادامه‌ی تکمیل و معرفی برنامه‌ی خالی ASP.NET Core 1.0، قصد داریم یک Middleware توکار را به نام Welcome Page، بجای نمایش سطر Hello world پیش فرض این برنامه، ثبت و فعال سازی کنیم. این Middleware ویژه، در اسمبلی به نام Microsoft.AspNetCore.Diagnostics قرار دارد. اگر فایل project.json پیش فرض این پروژه را باز کنید، این اسمبلی به صورت پیش فرض در آن ثبت و معرفی شده‌است:
{
    "dependencies": {
        "Microsoft.NETCore.App": {
            "version": "1.0.0",
            "type": "platform"
        },
        "Microsoft.AspNetCore.Diagnostics": "1.0.0",
        "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
        "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
        "Microsoft.Extensions.Logging.Console": "1.0.0"
    },
بنابراین هم اکنون بسته‌ی نیوگت آن نیز به پروژه‌ی جاری اضافه شده و قابل استفاده است. در غیراینصورت همانطور که در قسمت قبل در مطلب «نقش فایل project.json» عنوان شد، می‌توان بر روی گره references کلیک راست کرده و سپس از منوی ظاهر شده،‌گزینه‌ی manage nuget packages را انتخاب کرد. سپس، ابتدا برگه‌ی browse را انتخاب کنید و در اینجا نام Microsoft.AspNetCore.Diagnostics را جستجو کرده و در آخر آن‌را نصب کنید.
پس از اطمینان حاصل کردن از نصب بسته‌ی نیوگت Microsoft.AspNetCore.Diagnostics، اکنون جهت معرفی Middleware توکار Welcome Page ، فایل Startup.cs را گشوده و کدهای آن‌را به نحو ذیل تغییر  دهید:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
 
namespace Core1RtmEmptyTest
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }
 
        public void Configure(IApplicationBuilder app)
        {
            app.UseWelcomePage();
 
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello DNT!");
            });
        }
    }
}
در اینجا نحوه‌ی ثبت این middleware را با افزودن آن به IApplicationBuilder تزریق شده‌ی توسط OWIN، به کمک متد الحاقی UseWelcomePage مشاهده می‌کنید.
به علاوه middleware دومی را نیز با متد الحاقی Run مشاهده می‌کنید. به این نوع middlewareهای خاص، اصطلاحا terminal middleware می‌گویند. از این جهت که درخواستی را دریافت و یک response را تولید می‌کنند و کار همینجا خاتمه می‌یابد و زنجیره‌ی پردازشی middlewareها ادامه نخواهد یافت. در اینجا پارامتر context آن از نوع HttpContext است و باید دقت داشت، زمانیکه کار نوشتن در Response، در اینجا انجام شد، اگر پس از متد Run یک Middleware دیگر را ثبت کنید، هیچگاه اجرا نخواهد شد.

در این حالت اگر برنامه را اجرا کنید، خروجی ذیل را مشاهده خواهید کرد:


welcome page نیز یک terminal middleware است. به همین جهت middleware بعدی ثبت شده‌ی در اینجا یا همان متد Run، دیگر اجرا نخواهد شد.

در قسمت‌های بعدی، تعداد بیشتری از Middlewareهای توکار ASP.NET Core 1.0 را بررسی خواهیم کرد.
مطالب
CoffeeScript #2

Syntax

برای کار با CoffeeScript، ابتدا باید با ساختار Syntax آن آشنا شد. CoffeeScript در بسیاری از موارد با جاوااسکریپت یکسان است در حالیکه در قسمت قبل گفته شد که CoffeeScript زیر مجموعه‌ای جاوااسکریپت نیست؛ بنابراین برخی از کلمات کلیدی مانند function و var در آن مجاز نیست و سبب بروز خطا در زمان کامپایل می‌شوند. وقتی شما شروع به نوشتن فایل CoffeeScript می‌کنید، باید تمام کدهایی را که می‌نویسید، با Syntax کامل CoffeeScript بنویسید و نمی‌توانید قسمتی را با جاوااسکریپت و قسمتی را با CoffeeScript بنویسید.

برای نوشتن توضیحات در فایل CoffeeScript باید از علامت # استفاده کنید که این قسمت را از زبان Ruby گرفته است.

# A comment
در صورتیکه نیاز به نوشتن توضیحات را در چندین خط داشته باشید نیز این امکان دیده شده است:
###
  A multiline comment
###
نکته: تفاوتی که در توضیح یک خطی و چند خطی وجود دارد این است که توضیحات چند خطی پس از کامپایل، در فایل جاوااسکریپت خروجی نوشته می‌شوند، ولی توضیحات یک خطی در فایل خروجی تولید می‌شود.

در زبان CoffeeScript فاصله (space) بسیار مهم است؛ چرا که زبان Python براساس میزان تو رفتگی کدها، بدنه‌ی شرط‌ها و حلقه‌ها را تشخیص می‌دهد و CoffeeScript نیز از این ویژگی استفاده می‌کند. هرگاه بخواهید از {} استفاده کنید فقط کافی است از کلید Tab استفاده کنید تا پس از کامپایل به صورت {} تبدیل شود.

Variables & Scope

CoffeeScript یکی از باگهایی را که در نوشتن جاوااسکریپت وجود دارد (متغیرهای سراسری) حل کرده است. در جاوااسکریپت درصورتیکه هنگام تعریف متغیری از کلمه‌ی کلیدی var در پشت اسم متغیر استفاده نشود، به صورت سراسری تعریف می‌شود. CoffeeScript به سادگی متغیرهای سراسری را حذف می‌کند. در پشت صحنه‌ی این حذف، اسکریپت نوشته شده را درون یک تابع بدون نام قرار می‌دهد و با این کار تمامی متغیرها در ناحیه‌ی محلی قرار می‌گیرند و سپس قبل از نام هر متغیری، کلمه‌ی کلیدی var را قرار می‌دهد. برای مثال:

myVariable = "vahid"
که نتیجه کامپایل آن می‌شود:
var myVariable;
myVariable = "vahid";
همان طور که مشاهده می‌کنید، متغیر تعریف شده به صورت محلی تعریف شده و با این روش تعریف متغیر سراسری را به صورت اشتباهی، غیرممکن می‌کند. این روش استفاده شده در CoffeeScript جلوی بسیاری از اشتباهات معمول توسعه دهندگان وب را می‌گیرد.
با این حال گاهی اوقات نیاز است که متغیر سراسری تعریف کنید. برای اینکار باید از شیء سراسری موجود در مرورگر (window) یا از روش زیر استفاده کنید:
exports = this
exports.MyVariable = "vahid"


Functions

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

func = -> "vahid"
نتیجه‌ی کامپایل آن می‌شود:
var func;
func = function() {
  return "vahid";
};
همان طور که در بالا گفته شده، در صورتیکه بخواهید تابعی با چندین خط دستور داشته باشید، باید ساختار تو رفتگی را حفظ کرد. برای مثال:
func = ->
  # An extra line
  "vahid"
نتیجه کامپایل کد بالا نیز همانند کد قبلی می‌باشد.

Function arguments

برای تعریف آرگومان در توابع باید قبل از <- از () استفاده کرد و آرگومان هایی را که نیاز است، در داخل آن تعریف کرد. برای مثال:

func = (a, b) -> a * b
نتیجه‌ی کامپایل آن می‌شود:
var func;
func = function(a, b) {
  return a * b;
};
CoffeeScript از مقدار پیش فرض برای آرگومان‌های توابع نیز پشتیبانی می‌کند:
func = (a = 1, b = 2) -> a * b
همچنین در صورتیکه تعداد آرگومان‌های یک تابع برای شما مشخص نبود، می‌توانید از " ... "  استفاده کنید. مثلا وقتی می‌خواهید جمع n عدد را بدست آورید که n عدد به صورت آرگومان به تابع ارسال می‌شوند:
sum = (nums...) -> 
  result = 0
  nums.forEach (n) -> result += n
  result
در مثال فوق آرگومان nums آرایه‌ای از تمام آرگومان‌های ارسال شده به تابع است و نتیجه‌ی کامپایل آن می‌شود:
var sum,
  slice = [].slice;

sum = function() {
  var nums, result;
  nums = 1 <= arguments.length ? slice.call(arguments, 0) : [];
  result = 0;
  nums.forEach(function(n) {
    return result += n;
  });
  return result;
};
 

فراخوانی توابع

برای فراخوانی توابع می‌توانید به مانند جاوااسکریپت از با پرانتز () یا ()apply و یا ()call صدا زده شوند. اگرچه مانند Ruby، کامپایلر CoffeeScript می‌توانند به صورت اتوماتیک توابعی با حداقل یک آرگومان را فراخوانی کند.

a = "Vahid!"

alert a
# برابر است با
alert(a)

alert inspect a
# برابر است با
alert(inspect(a))
اگرچه استفاده از پرانتز اختیاری است اما توصیه می‌شود در مواقعی که آرگومان‌های ارسالی بیش از یک مورد باشد توصیه می‌شود از پرانتز استفاده کنید.
در صورتی که تابعی بدون آرگومان باشد، برای فراخوانی آن بدون نوشتن پرانتز بعد از نام تابع، CoffeeScript نمی‌تواند تشخیص دهند که این یک تابع است و مانند یک متغیر با آن برخورد می‌کند. دراین رابطه، رفتار CoffeeScript بسیار شبیه به Python می‌باشد.
 

مطالب
کار با Docker بر روی ویندوز - قسمت دوم - نصب Docker
پس از آشنایی با مفهوم Containers، در این قسمت قصد داریم برنامه‌ی تقریبا 500 مگابایتی Docker for Windows Installer.exe را نصب کنیم.
 
پیش‌نیازهای نصب Docker بر روی ویندوز

مطابق مستندات آن، برای نصب داکر بر روی ویندوز به حداقل‌های زیر نیاز است:
- استفاده از ویندوز 10 نگارش enterprise، که شماره نگارش آن حداقل 1607 باشد (حداقل Anniversary Update باشد).
- مجازی سازی در BIOS فعال شده باشد.
البته مجازی سازی عموما به صورت پیش‌فرض فعال است. برای بررسی آن، taskmanager ویندوز را اجرا کرده و در برگه‌ی Performance آن، جائیکه مشخصات CPU را نمایش می‌دهد، یک سطر به Virtualization اختصاص دارد که مقدار آن باید enabled باشد (تصویر زیر) و اگر نیست، برای فعال کردن آن باید به تنظیمات BIOS سیستم خود مراجعه کنید:


روش دیگر دریافت این اطلاعات، اجرای دستور systeminfo در خط فرمان، با دسترسی مدیریتی است. در خروجی آن، عبارت «Virtualization Enabled In Firmware» را جستجو کنید که باید مقدار آن yes باشد.

- داشتن CPU با قابلیت SLAT یا Second Level Address Translation.
برای یافتن این موضوع، برنامه‌ی coreinfo را دریافت کرده و آن‌را به صورت coreinfo -v اجرا کنید. خروجی آن سه سطر مرتبط با مجازی سازی را به همراه دارد. اگر قابلیتی موجود نباشد، جلوی آن یک خط تیره و اگر قابلیتی موجود باشد، روبروی آن یک ستاره را مشاهده خواهید کرد.

روش دیگر بررسی آن، اجرای دستور msinfo32 در قسمت run ویندوز و سپس enter است. در قسمت system summary، اطلاعات Second Level Address Translation قابل مشاهده هستند (اگر No باشد، امکان اجرای containerهای لینوکسی را بر روی ویندوز نخواهید داشت):


- داشتن حداقل 4 گیگابایت RAM.
- فعال بودن Hyper-V نیز برای اجرای Linux Containers بر روی ویندوز، ضروری است (نصاب Docker، این‌کار را به صورت خودکار انجام می‌دهد).


دریافت نصاب Docker for Windows

برای دریافت نصاب داکر مخصوص ویندوز، به آدرس زیر مراجعه کنید:
https://store.docker.com/editions/community/docker-ce-desktop-windows
که بلافاصله با تصویر کریه زیر مواجه خواهید شد:


برای رفع این مشکل، می‌توان از روش مطرح شده‌ی در مطلب «یک روش ساده برای دور زدن تحریم‌ها!» استفاده کرد؛ یعنی تنظیم DNS به 178.22.122.100 به صورت زیر:


پس از این تغییر، چون IP قابل مشاهده‌ی سیستم شما توسط سایت داکر تغییر می‌کند، اینبار صفحه‌ی دریافت Docker Community Edition for Windows به صورت زیر ظاهر می‌شود:


همانطور که مشاهده می‌کنید، عنوان کرده‌است که لطفا لاگین کنید تا بتوانید این برنامه را دریافت کنید. به همین جهت بر روی لینک آن کلیک کرده، یک اکانت جدید را در سایت docker ایجاد کنید (با یک ایمیل واقعی که تائیدیه آن‌را دریافت خواهید کرد). پس از آن، با این اکانت جدید به سایت داکر وارد شوید تا لینک دریافت فایل exe نصاب آن‌را دریافت کنید.
در این حالت مرورگر و یا حتی دانلودمنیجر شما بدون مشکل می‌توانند این فایل را دریافت کنند و همان تنظیم DNS فوق، مشکل عدم دسترسی را برطرف می‌کند.


نصب Docker for Windows

پس از اجرای نصاب آن و پایان عملیات نصب (که تنها کافی است در صفحه‌ی ابتدایی آن تیک مربوط به Windows Containers را نیز قرار دهید)، نیاز دارد تا شما را یکبار از سیستم Logout و login کند. پس از ورود به سیستم، تنظیمات ابتدایی آن به صورت خودکار صورت گرفته و در صورت فعال نبودن Hyper-V، پیام زیر را مشاهده خواهید کرد:


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

یک نکته: کاری که در قسمت فعالسازی Hyper-V به صورت خودکار انجام می‌شود، شامل اجرای سه دستور زیر، در کنسول پاور شل، با دسترسی مدیریتی و سپس ری استارت سیستم است:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All -Verbose
Enable-WindowsOptionalFeature -Online -FeatureName Containers -All -Verbose
bcdedit /set hypervisorlaunchtype Auto
پس از آن، خط فرمان را باز کرده و با ستفاده از docker CLI نصب شده، دستور docker info را صادر کنید، تا بتوانید مشخصات نگارش نصب شده را مشاهده نمائید.
C:\Users\Vahid>docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 18.06.1-ce
OSType: windows
OSType را در صورتیکه سیستم شما توانمندی‌های سخت افزاری لازم را داشته باشد، می‌توان به Linux نیز تغییر داد.


بررسی تنظیمات سوئیچ کردن بین Linux Containers و Windows Containers

پس از اتمام ری‌استارت‌ها، برای آزمایش فعال بودن Hyper-V، در قسمت Run ویندوز، عبارت Virtmgmt.msc را نوشته و enter کنید. اگر تصویر زیر را مشاهده نمی‌کنید:


یکبار بر روی آیکن Docker در قسمت Tray Icons ویندوز کلیک راست کرده و گزینه‌ی switch to Linux containers را انتخاب کنید تا پس از مدتی، آیکن MobyLinuxVM در قسمت virtual machines (تصویر فوق) ظاهر شود.


اگر پس از انتخاب این گزینه، پیام زیر را دریافت کردید:


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


قسمت «پیش‌نیازهای نصب Docker بر روی ویندوز» را با دقت بررسی کنید (خصوصا قسمت BIOS و SLAT). نبود یکی از موارد ذکر شده، سبب بروز این مشکل می‌شود.
برای مثال اجرای دستور coreinfo -v بر روی سیستم من چنین خروجی را به همراه دارد:
E:\>coreinfo -v

AuthenticAMD
Microcode signature: 00000000
HYPERVISOR      -       Hypervisor is present
SVM             *       Supports AMD hardware-assisted virtualization
NP              -       Supports AMD nested page tables (SLAT)
روبروی HYPERVISOR و همچنین SLAT یک - را قرار داده‌است. یعنی این موارد یا پشتیبانی نمی‌شوند و یا در BIOS فعال نشده‌اند.
همانطور که مشاهده می‌کنید، قابلیت SLAT در CPU این سیستم وجود ندارد. به همین جهت نمی‌توان به Linux containers سوئیچ کرد. هرچند windows containers آن کار می‌کند.

روش دیگر مشاهده‌ی این خطا، مراجعه‌ی به event viewer ویندوز است. در قسمت خطاهای سیستم، ممکن است خطای زیر را مشاهده کنید:
Hypervisor launch failed; Second Level Address Translation is required to launch the hypervisor.


آزمایش Docker نصب شده

پس از نصب docker، خط فرمان ویندوز را گشوده و دستور زیر را صادر کنید:
docker run hello-world
اگر از قسمت قبل به‌خاطر داشته باشید، hello-world در اینجا نام یک image است. البته چون این image بر روی سیستم ما موجود نیست، این دستور، ابتدا آن‌را از docker hub دریافت کرده و سپس اجرا می‌کند. بنابراین می‌شد ابتدا دستور pull را صادر کرد و سپس run. اما دستور run قادر است هر دو عمل را با هم انجام دهد.

یک نکته: این image، یک image لینوکسی است. به همین جهت پیش از اجرای این دستور، همانطور که پیشتر نیز عنوان شد، یکبار بر روی آیکن Docker در قسمت Tray Icons ویندوز کلیک راست کرده و گزینه‌ی switch to Linux containers را انتخاب کنید. سپس دستور docker run hello-world را اجرا نمائید.

و یا در همین حال دستور docker run -p 80:80 nginx را صادر کنید تا وب سرور لینوکسی nginx را بتوانید تحت ویندوز اجرا کنید. پس از خاتمه‌ی عملیات دریافت و اجرای وب سرور، با توجه به تنظیم  p 80:80-، پورت 80 میزبان (اولین عدد)، به پورت 80 کانتینر نگاشت شده‌است. به همین جهت تنها با اجرای دستور http://localhost، خروجی این وب سرور را می‌توانید در مرورگر سیستم خود مشاهده کنید.
همانطور که مشاهده می‌کنید، با استفاده از داکر، پیش از آنکه بدانیم چگونه باید یک نرم افزار را نصب کرد، می‌توان از آن استفاده کرد!


روش متوقف کردن Containers در حال اجرا

اگر دستور docker ps را در خط فرمان ویندوز اجرا کنید، لیست پروسه‌های اجرا شده‌ی توسط آن قابل مشاهده هستند. در این لیست container id در حال اجرا نیز مشخص است. برای خاتمه‌ی کار آن، تنها کافی است دستور docker stop id را اجرا کنید.
یک نکته: ضرورتی به ذکر کامل id نیست. برای مثال ذکر سه حرف اول آن نیز کفایت می‌کند.


روش اجرای مجدد یک Container

فرض کنید می‌خواهیم سرور nginx را مجددا اجرا کنیم. یک روش آن، اجرای مجدد دستور docker run -p 80:80 nginx است که پیشتر آن‌را انجام دادیم. در این حالت این image تبدیل به container شده و همانند روش‌های متداول نصب نرم افزار، اکنون به عنوان یک نرم افزار نصب شده در دسترس است. برای مشاهده‌ی لیست آن‌ها، دستور docker ps -a را اجرا کنید. این لیست تا این لحظه باید شامل containerهای nginx و hello-world باشد. متوقف کردن یک container، سبب تخریب یا حذف آن نمی‌شود. در این حالت در لیستی که توسط دستور docker ps -a نمایش داده شده‌است، باز هم container idها قابل مشاهده هستند. فقط کافی است برای اجرای یکی از آن‌ها، دستور docker start id را اجرا کرد. به این صورت دیگر نیازی به ذکر دستور کامل docker run با تمام پارامترهای آن نیست. این id نیز همانطور که ذکر شد، می‌تواند سه حرف ابتدایی این id باشد تا حدی که نسبت به سایر idهای موجود، منحصربفرد شناخته شود. یا بجای container id می‌توان container name نمایش داده شده‌ی در این لیست را استفاده کرد.
پس از اجرای nginx توسط دستور docker start id، دو روش برای بررسی در حال اجرا بودن آن وجود دارد:
الف) مرورگر را باز کنیم و آدرس http://localhost را بررسی کنیم.
ب) دستور docker ps را در خط فرمان اجرا کنیم، تا مشخص شود که آیا پروسه‌ی nginx در حال اجرا است یا خیر؟

بنابراین دستور docker ps -a لیست تمام containers در حال اجرا و همچنین متوقف شده را نمایش می‌دهد. اما دستور docker ps تنها لیست containers در حال اجرا را نمایش خواهد داد.


روش حذف Containers از Docker

همانطور که در قسمت قبل نیز بحث شد، معادل نصب نرم افزار در اینجا، ایجاد یک container از یک image دریافتی از docker hub است. روش عکس آن، یعنی تخریب یک container، دقیقا معادل عزل نرم افزار از سیستم، در حالت‌های متداول است. برای اینکار مجددا دستور docker ps -a را اجرا می‌کنیم تا لیست تمام containerهای در حال اجرا و همچنین متوقف شده نمایش داده شوند. لیستی که در اینجا نمایش داده می‌شود، شبیه به لیستی است که در قسمت add/remove programs ویندوز مشاهده می‌کنید. این لیست معادل لیست نرم افزارهای نصب شده‌ی بر روی سیستم است و یا برای مشاهده‌ی لیست imageهای دریافتی از docker hub می‌توان دستور docker images را صادر کرد.
قبل از حذف یک container نیاز است آن‌را متوقف کنیم. برای این منظور از دستور docker stop id استفاده می‌شود. سپس اجرای دستور docker rm id، سبب حذف کامل این container خواهد شد. برای آزمایش آن، مجددا دستور docker ps -a را اجرا کنید.
دستور docker rm چندین id را نیز می‌پذیرد. می‌توان این idها و یا حتی سه حرف ابتدایی آن‌ها را با فاصله در اینجا ذکر کرد. علاوه بر id، ذکر نام containers نیز مجاز است.


روش حذف Imageهای دریافتی از Docker Hub

دستور docker rm، فقط containers را از سیستم حذف می‌کند (نرم افزارهای نصب شده). اما خود imageهای اصلی دریافت شده‌ی از docker hub را حذف نمی‌کند (معادل همان فایل‌های zip دریافت نرم افزار یا برنامه‌های نصاب، در حالت متداول و سنتی نصب نرم افزار). برای آزمایش آن دستور docker images را اجرا کنید. هنوز هم در لیست آن، تمام موارد دریافتی موجود هستند.
برای حذف یک image می‌توان از دستور docker rmi id استفاده کرد (rmi بجای rm). این id نیز در لیست docker images ظاهر می‌شود و ذکر قسمتی از آن، تا حدی که نسبت به سایر idهای لیست شده منحصربفرد باشد، کافی است. در اینجا بجای id، از نام image نیز می‌توان استفاده کرد. همچنین ذکر چندین id و یا نام نیز پس از دستور docker rmi، میسر است.


روش جستجوی imageها در Docker Hub توسط Docker CLI

فرض کنید می‌خواهیم image مربوط به راهنمای Docker را از Docker Hub دریافت کنیم. یک روش آن مراجعه‌ی مستقیم به سایت آن است و استفاده از امکانات جستجوی فراهم شده‌ی در آن سایت. روش دیگر، استفاده از Docker CLI است. اگر دستور docker search docs را در خط فرمان اجرا کنیم، لیست تمام مخازن کدی که در آن‌ها واژه‌ی docs قرار دارد، نمایش داده می‌شود. البته پیش از نصب image آن بهتر است به برگه‌ی tags مخزن کد آن نیز مراجعه کنید تا بتوانید حجم آن‌را نیز مشاهده نمائید که حدود یک گیگابایت است. مخازن docker hub، حاوی imageهای نصاب containerهای متناظر هستند. برای دریافت و اجرای آن می‌توان دستور docker run -p 4000:4000 docs/docker.github.io را اجرا کرد.
پس از دریافت یک گیگابایت مستندات، container آن بر روی پورت 4000 در سیستم ما (http://localhost:4000)، به صورت یک وب سایت استاتیک، قابل دسترسی خواهد بود. به این صورت می‌توان به مستندات کامل داکر به صورت آفلاین دسترسی داشت.


مفهوم Interactive Terminal در Docker

زمانیکه دستور اجرای مستندات آفلاین را صادر می‌کنید، در انتهای آن عنوان می‌کند که وب سایت محلی آن بر روی پورت 4000 قابل دسترسی است. سپس در ذیل آن ذکر شده‌است که اگر ctrl+c را فشار دهید، اجرای آن به پایان می‌رسد. اما عملا اینطور نیست و اگر دستور docker ps را صادر کنید، هنوز container در حال اجرای آن را می‌توان مشاهده کرد.
اما اگر اینبار دستور اجرای docker run را به همراه یک interactive terminal با سوئیچ it و نام docs صادر کنیم:
 docker run -p 4000:4000 -it --name docs docs/docker.github.io
اکنون اگر ctrl+c را فشار دهیم و پس از آن دستور docker ps را صادر کنیم، دیگر در لیست آن، container در حال اجرای docs مشاهده نمی‌شود.
سوئیچ it یا interactive terminal سبب می‌شود تا یک container در foreground، بجای background اجرا شود. به این ترتیب دستور ctrl+c، سبب خاتمه‌ی واقعی پروسه‌ی درحال اجرای در container می‌شود.
روش دیگر خاتمه‌ی این container، استفاده از نام ذکر شده‌است؛ یعنی اجرای دستور docker stop docs.

یک نکته: اگر می‌خواهید از terminal باز شده قطع شوید (مجددا به command prompt باز گردید) اما سبب خاتمه‌ی container آن نشوید، از ترکیب ctrl+p+q استفاده کنید.


اجرای containerهای ویندوزی

در مورد نحوه‌ی سوئیچ بین نوع‌های مختلف containerهای ویندوزی و لینوکسی پیشتر توضیح دادیم. برای این منظور می‌توان بر روی آیکن Docker در قسمت Tray Icons ویندوز کلیک راست کرده و گزینه‌ی switch to Windows/Linux containers را انتخاب کرد. باید دقت داشت که پشتیبانی از containerهای ویندوزی، از ویندوز 10، نگارش  1607، یا همان Anniversary Update آن به بعد، به ویژگی‌های ویندوز اضافه شده‌اند که به صورت خودکار توسط docker فعالسازی می‌شوند:



اجرای IIS به عنوان یک Windows Container

تا اینجا imageهای دریافتی، لینوکسی بودند. اگر گزینه‌ی Windows Containers را به روشی که گفته شد، فعال کنید، اینبار با اجرای دستورات docker ps و یا docker images، هیچ خروجی را دریافت نخواهید کرد. از این جهت که کانتینرهای ویندوزی و لینوکسی، به صورت کاملا ایزوله‌ای از هم اجرا و مدیریت می‌شوند. علت آن‌را هم در MobyLinuxVM که پیشتر با اجرای دستور Virtmgmt.msc بررسی کردیم، می‌توان یافت. Containerهای لینوکسی، در داخل MobyLinuxVM اجرا می‌شوند.
در اینجا به عنوان مثال می‌توان image رسمی مربوط به IIS را از docker hub دریافت و به صورت یک کانتینر ویندوزی اجرا کرد. البته پیش از اجرای دستورات آن بهتر است به برگه‌ی tags آن مراجعه کرده و حجم‌های نگارش‌های مختلف آن‌را بررسی کرد. اجرای دستور docker pull microsoft/iis به معنای دریافت tag ای به نام latest است (به حجم 6 گیگابایت!)؛ یعنی با دستور docker pull microsoft/iis:latest یکی است. بنابراین در اینجا بر اساس tagهای مختلف، می‌توان دستور pull متفاوتی را صادر کرد. برای مثال اگر دستور docker pull microsoft/iis:nanoserver را صادر کردید، نگارش مخصوص nano server آن‌را که فقط 449 مگابایت است، دریافت می‌کند. بنابراین از این پس به tagهای هر مخزن docker hub خوب دقت کنید و نگارش مختص به سیستم عامل خود را دریافت نمائید. عدم ذکر tag ای، همواره tag ویژه‌ای را به نام latest، دریافت می‌کند.
با اجرای دستور زیر
 docker run -p 81:80 -d --name iis microsoft/iis:nanoserver
داکر، ابتدا image مخصوص nanoserver آن‌را دریافت و سپس اجرا می‌کند. چون وب سرور است، نیاز به تنظیمات پورت آن‌را داریم. p 81:80- به این معنا است که پورت 80 کانتینر را (پورتی که IIS درون آن بر روی آن اجرا می‌شود)، به پورت 81 بر روی سیستم میزبان (یا همین ویندوز فعلی که داکر را اجرا می‌کند)، نگاشت کن. پارامتر d در اینجا به معنای detach است. یعنی به محض اجرای این دستور، کار اجرای این کانتینر در background انجام شده و سپس به خط فرمان، بازگشت داده می‌شویم. همچنین نامی نیز به این container انتساب داده شده‌است تا ساده‌تر بتوان با آن کار کرد.

یک نکته: مشکلی با اجرای IIS مخصوص نانوسرور بر روی ویندوز 10 به این صورت و توسط داکر نیست. بنابراین پس از اجرای دستور فوق، کار دریافت image و ساخت container و سپس اجرای آن به صورت خودکار انجام شده و بلافاصله به command prompt بازگشت داده می‌شویم (به علت استفاده‌ی از پارامتر d). اکنون اگر دستور docker ps را صادر کنیم، مشاهده می‌کنیم که کانتینر IIS مخصوص نانوسرور، هم اکنون بر روی ویندوز 10 در حال اجرا است و در آدرس http://localhost:81 قابل دسترسی است.

جهت تکمیل این بحث، بهتر است image مخصوص nanoserver را نیز از docker hub دریافت و اجرا کنیم:
 docker run microsoft/windowsservercore
حجم image آن 6GB است.


تنظیمات کارت شبکه‌ی Containers

هنگامیکه پروسه‌ای درون یک container اجرا می‌شود، ایزوله سازی‌های بسیاری نیز در مورد آن اعمال خواهد شد؛ به همین جهت گاهی از اوقات عده‌ای containerها را با ماشین‌های مجازی نیز مقایسه می‌کنند. برای مثال کانتینرها به همراه network adapter خاص خود نیز هستند؛ درست مانند اینکه یک کامپیوتر مجزای از سیستم جاری می‌باشند و اگر این network adapter را ping کنیم، می‌توان به این صورت نیز به آن کانتینر، دسترسی داشته باشیم.
برای یافتن آن، دستور docker inspect iis را صادر می‌کنیم. خروجی آن به همراه یک قسمت network نیز هست که داخل آن یک IP Address قابل مشاهده است. این IP است که مختص و منحصربفرد این container است. در ابتدا برای آزمایش آن، می‌توان آن‌را ping کرد؛ مانند ping 172.27.49.47. همچنین به تمام برنامه‌های داخل این container توسط این IP نیز می‌توان دسترسی یافت. برای مثال فراخوانی http://172.27.49.47:81 در مرورگر، سبب نمایش صفحه‌ی اول IIS می‌شود. البته اگر اینکار را انجام دهیم، کار نمی‌کند. علت اینجا است، نگاشت پورتی را که تعریف کرده‌ایم (پورت 81)، به پورتی در کامپیوتر میزبان است و نه این IP ویژه. برنامه‌ی اصلی IIS در داخل container، به پورت 80 بر روی این آدرس IP گوش فرا می‌دهد. اکنون اگر آدرس http://172.27.49.47:80 را در کامپیوتر میزبان فراخوانی کنیم، کار می‌کند.
بنابراین هرچند containerها به معنای نرم افزارهای از پیش نصب شده‌ی در حال اجرا هستند، اما ... به همراه ایزوله سازی‌های قابل توجهی بر روی کامپیوتر میزبان اجرا می‌شوند؛ درست مانند یک کامپیوتر مجزای از آن.
اشتراک‌ها
دریافت کتاب Node.js in Action
جاوا اسکریپت سمت سرور؟ Node.js جاوا اسکریپت سمت سرور است که توانایی پشتیبانی از برنامه‌های تحت وب مقیاس پذیر و عملکرد بالا را دارد. با استفاده از I/O ناهمگام، سرور توانایی انجام بیش از یک کار در یک لحظه را دارد که این یک احتیاج کلیدی برای برنامه‌های بلادرنگ تحت وب به مانند چت، بازی‌ها و آمار‌های لحظه به لحظه است. همچنین چون زبان برنامه نویسی جاوا اسکریپت است، شما تا انتها هم از همین زبان برای برنامه نویسی استفاده می‌کنید. 
دریافت کتاب Node.js in Action
نظرات مطالب
نحوه استفاده از ViewModel در ASP.NET MVC
سلام؛ وقتی رو صفحه اصلی سایت کاربر روی ادامه مطلب کلیک میکنه و وارد صفحه مربوط به اون مطلب میشه، صفحه جدید از یک پارشال ویوو تشکیل شده که دارای یک تگ فرم هست برای ارسال نظرات کاربران و هم چنین یک پارشال ویوو دیگر برای نمایش مطلب کامل اون لینک میباشد. برای استفاده هردو مدل یک view model تعریف شده که شامل هر دو موجودیت‌ها است. وقتی توی ویوو اصلی دکمه ادامه مطلب زده میشه این ارور داده میشه:

The model item passed into the dictionary is of type 'Class.Domain.Enities.Product', but this dictionary requires a model item of type 'WebAli.ViewModel.ProductCommentListViewModel'. 

مطالب
OutputCache در ASP.NET MVC
مقدمه

OutputCaching باعث می‌شود خروجیِ یک اکشن متد در حافظه نگهداری شود. با اعمال این نوع کشینگ، ASP.NET در خواست‌های بعدی به این اکشن را تنها با بازگرداندن همان مقدار قبلی ِ نگهداری شده در کش، پاسخ می‌دهد. در حقیقت با OutputCaching از تکرار چند باره کد درون یک اکشن در فراخوانی‌های مختلف جلوگیری کرده‌ایم. کش کردن باعث می‌شود که کارایی و سرعت سایت افزایش یابد؛ اما باید دقت کنیم که چه موقع و چرا از کَش کردن استفاده میکنیم و چه موقع باید از این کار امتناع کرد. 


فواید کَش کردن

- انجام عملیات هزینه دار فقط یکبار صورت میگیرد. (هزینه از لحاظ فشار روی حافظه سرور و کاهش سرعت بالا آمدن سایت)

- بار روی سرور در زمان‌های پیک کاهش می‌یابد.

- سرعت بالا آمدن سایت بیشتر میشود. 


چه زمانی باید کَش کرد؟ 

- وقتی محتوای نمایشی برای همه کاربران یکسان است.

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

- وقتی محتوای نمایشی به شکل مکرر در طول روز باید نمایش داده شود.

- وقتی محتوای نمایشی به طور مکرر آپدیت نمی‌شود. (در مورد تعریف کیفیت "مکرر"، برنامه نویس بهترین تصمیم گیرنده است) 


طرح مساله 

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

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

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

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

فشار ترافیکی(ریکوئست‌های زیاد) و آپدیت‌های روزانه‌ی دیتابیس را، در دو کفه ترازو قرار دهید؛ چه کار باید کرد؟ این تصمیمی است که شما باید بگیرید. نگرانی خود را در زمینه آپدیت‌های روزانه و ساعتی کمتر کنید؛ در ادامه راهی را معرفی میکنیم که آپدیت‌های هر از گاهِ شما، در پاسخِ ریکوئست‌ها دیده شوند. کمی کفه‌ی کش کردن را سنگین کنید.

به هر حال، فعال کردن قابلیت کش کردن برای یک اکشن، بسیار ساده است، کافیست ویژگی ( attribute ) آن را بالای اکشن بنویسید :

[OutputCache(Duration = "60", Location = OutputCacheLocation.Server)]
        public ActionResult Index()
        {
            //کوئری یا کوئری‌های لازم برای استفاده در صفحه اصلی و تبدیل آن به یک ویو مدل جامع
        }
[OutputCache(CacheProfile = "FirstPageIndex",Location=OutputCacheLocation.Server)]
        public ActionResult Index()
        {
            //کوئری یا کوئری‌های لازم برای استفاده در صفحه اصلی و تبدیل آن به یک ویو مدل جامع
        }

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

    <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="FirstPageIndex" duration="60"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

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

برای تست عملیات کشینگ، کافیست یک BreakPoint  درون Index قرار دهید و برنامه را اجرا کنید. پس از اجرا، برنامه روی Break Point می‌ایستد و اگر F5 را بزنیم، سایت بالا می‌آید. بار دیگر صفحه را رفرش کنیم، اگر این "بار دیگر" در کمتر از 60 ثانیه پس از رفرش قبلی اتفاق افتاده باشد برنامه روی Break Point متوقف نخواهد شد، چون خروجی اکشن، در کش بر روی سرور ذخیره شده است و این یعنی ما فشار کمتری به سرور تحمیل کرده ایم، صفحه با سرعت بالاتری در دسترس خواهد بود.

ما از تکرار اجرای کد جلوگیری کرده ایم و عدم اجرای کد بهترین نوع بهینه سازی برای یک سایت است. [اسکات الن، پلورال سایت]


چطور زمان مناسب برای کش کردن یک اکشن را انتخاب کنیم؟

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

- کشینگ با زمان طولانی؛ ما در حقیقت با اینکار منابع سرور را حفاظت میکنیم، چون عملیاتِ هزینه دار(مثل کوئری‌های حجیم) تنها یکبار در طول زمان کشینگ اجرا خواهند شد. مثلا اگر تنظیم زمان روی عدد 86400 تنظیم شود(یک روز کامل)، پس از اولین ریکوئست به اکشن مورد نظر، تا 24 ساعت بعد، این اکشن اجرا نخواهد شد و فقط خروجی آن نمایش داده خواهد شد. آیا دلیلی دارد که یک کوئری هزینه دار را که قرار نیست خروجی اش در طول روز تغییر کند به ازای هر ریکوئست یک بار اجرا کنیم؟   

اگر اطلاعات موجود در دیتابیس را تغییر دهیم چه کار کنیم که کشینگ رفرش شود؟ 

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

کافیست در بخش ادمین، وقتی که یک پست ایجاد میکنید یا پستی را ویرایش میکند در اکشن‌های مرتبط با Create یا Edit یا Delete چنین کدی را پس از فرمان ذخیره تغییرات در دیتابیس، بنویسید: 

Response.RemoveOutputCacheItem(Url.Action("index", "home"));

واضح است که ما داریم کشینگ مرتبط با یک اکشن متد مشخص را پاک میکنیم. با اینکار در اولین ریکوئست پس از تغییرات اعمال شده در دیتابیس، ASP.NET MVC چون میبیند کَشی برای این اکشن وجود ندارد، متد را اجرا میکند و کوئری‌های درونش را خواهد دید و اولین ریکوئست پیش از کَش شدن را انجام خواهد داد. با اینکار کشینگ ریست شده است و پس از این ریکوئست و استخراج اطلاعات جدید، زمان کشینگ صفر شده و آغاز میشود.

میتوانید یک دکمه در بخش ادمین سایت طراحی کنید که هر موقع دلتان خواست کلیه کش‌ها را به روش فوق پاک کنید! تا اپلیکیشن منتظر ریکوئست‌های جدید بماند و کش‌ها دوباره ایجاد شوند. 


جمع بندی

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

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

<caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="Long" duration="86400"/>
          <add name="Average" duration="43600"/>
          <add name="Short" duration="600"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

برای مطالعه جزئیات بیشتر در مورد OutputCaching مقالات زیر منابع مناسبی هستند.

[اینجا ] و [اینجا ]

مطالب
بررسی چند کتابخانه آپلود با پشتیبانی از DragDrop
برای یکی از پروژه‌ها نیاز به یک آپلودر داشتم که قابلیت  Drag&Drop را نیز داشته باشد و در ضمن پیاده سازی آسانی هم داشته باشد. در این بین به تعدادی از کتابخانه‌های جی کوئری می‌پردازیم.
FileDrop
اولین کتابخانه‌ای که با آن آشنا شدم و از آن استفاده کردم، کتابخانه‌ی FileDrop است که بسیار ساده و در عین حال قابلیت‌های خوبی را می‌دهد و از فناوری Filereader  (+) در Html5 برای اینکار استفاده می‌کند. مرورگرهای کروم، فایرفاکس 3.6 به بعد، IE10 به بعد و Opera 12 به بعد از آن پشتیبانی می‌کنند.
فایل‌های مورد نیاز را از اینجا دانلود کنید . فایل اسکریت آن را ابتدا صدا بزنید:
 <script src="~/scripts/jquery.filedrop.js" type="text/javascript"></script>
سپس المان‌های زیر را به کد HTML خود اضافه کنید:
 <div id="dropZone">فایل برنامه را به داخل این کادر بکشانید</div>
        <br>
        فایل یا فایل‌های آپلود شده:
        <ul id="uploadResult"></ul>
تگ اول، محلی است که فایل‌ها به سمت آن درگ و روی آن دراپ می‌شوند که از این به بعد به آن محل آپلود می‌گوییم. المان بعدی جهت گزارش فایل‌هایی است که آپلود شده‌اند. با آپلود شدن هر تعداد فایل، اسم آن به لیست اضافه می‌گردد.
کدهای css زیر را هم به صفحه اضافه کنید تا محل آپلود زیباتر شود:
        .files {
            min-height: 42px;
            background: #CCC none repeat scroll 0% 0%;
            border-top: 1px solid #FFF;
            margin: 11px 0px;
            padding: 11px 13px;
            border-radius: 6px;
        }

        #dropZone.mouse-over {
            background-color: #1d4257;
        }

کد جی کوئری زیر را به صفحه اضافه کنید:
      $('#dropZone').filedrop({
                url: uploadAddress,
                paramname: 'files',
                maxFiles: 1,
                dragOver: function() {
                    $('#dropZone').addClass('mouse-over');
                },
                dragLeave: function() {
                    $('#dropZone').removeClass('mouse-over');
                },
                drop: function() {
                    $('#dropZone').removeClass('mouse-over');
                },
                afterAll: function() {
                    $('#dropZone').html('آپلود با موفقیت انجام شد');
                },
                uploadFinished: function(i, file, response, time) {
                    $('#uploadResult').append('<li>' + file.name + '</li>');
                }
            });
ابتدا پلاگین جی کوئری را روی تگ مربوطه اعمال می‌کنیم و سپس پارامترها را با مشخصات زیر اعمال می‌کنیم:
Url  آدرسی که قرار است فایل‌ها به آن سمت ارسال شوند. 
 Paramname  در سمت سرور باید فایل‌ها را با استفاده از این نام پارامتر دریافت  کنید.
 maxFiles  تعداد فایلهایی که میتوان با درگ و دراپ کردن روی آن به دست آورد. در بالا به یک فایل محدود شده است.
 dragOver  این رویداد زمانی اجرا خواهد شد که اشاره گر با حالت درگ کرده فایل‌ها را به محل آپلود آورده است.
 dragLeave  موقعی که ماوس از محل آپلود خارج می‌شود
 drop  موقعی که شما فایل‌ها را روی محل  آپلود رها می‌کنید.
 afterAll  بعد از اینکه همه کارها تمام شد اجرا می‌شود.(آخرین رویداد)
 uploadFinished  کار آپلود به پایان رسیده است. در مثال بالا پس از پایان آپلود، نام فایل آپلود شده را به کاربر نشان داده‌ایم.

نحوه‌ی دریافت آن در سمت سرور, در یک اکشن متد به صورت زیر است:

[HttpPost]
        public virtual ActionResult UpdateApp(IEnumerable<HttpPostedFileBase>files)
        {
            foreach (HttpPostedFileBase file in files)
            {
                string filePath = Path.Combine(TempPath, file.FileName);
                file.SaveAs(filePath);
            }

            return Json(new {state = "success", message = "با موفقیت عملیات ارسال فایل انجام شد"}, JsonRequestBehavior.AllowGet);
        }

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

این موارد از اصلی‌ترین‌ها هستند که به کار می‌آیند. به غیر این‌ها یک سری خصوصیات اضافه‌تری هم برای آن وجود دارد.


fallback_id 
 اگر دوست دارید این آپلودر را نیر به یک آپلودر معمولی اتصال دهید از این شناسه استفاده کنید.
 withCredentials   با استفاده از کوکی‌ها یک درخواست cross-origin ایجاد می‌کند.
 data  اگر دوست دارید به همراه فایل‌ها اطلاعات دیگری هم به همراه آن ارسال و پست شوند از این طریق اقدام نمایید. می‌تواند در قالب یک متغیر باشد یا خروجی یک تابع.
data: {
        param1: 'value1',           
        param2: function(){
            return calculated_data; 
        }
 headers برای ارسال مقدار اضافه‌تر در هدر درخواست به کار میرود و صدا زدن آن همانند کد data می‌باشد. 
 error   در صورتیکه در فرایند آپلود خطایی رخ دهد، اجرا می‌گردد. نحوه‌ی کدنویسی آن و بررسی خطاهای آن به شرح زیر است:
error: function(err, file) {
        switch(err) {
            case 'BrowserNotSupported':
                alert('مرورگر از این فناوری پشتیبانی نمی‌کند')
                break;
            case 'TooManyFiles':
                // قصد آپلود همزمان فایل‌های بیشتری از حد مجاز تعیین شده دارید
                break;
            case 'FileTooLarge':
                //حداقل حجم یکی از فایل‌ها از حجم مجاز تعیین شده بیشتر است
                //برای دسترسی به نام آن فایل از کد زیر استفاده کنید
              //file.name
                break;
            case 'FileTypeNotAllowed':
                // نوع حداقل یکی از فایل‌ها با نوع‌ها مشخص شده ما یکی نیست
                break;
            case 'FileExtensionNotAllowed':
                // پسوند حداقل یکی از فایل‌ها مورد تایید نیست
                break;
            default:
                break;
        }
    }
 allowedfiletypes   نوع فایل‌های مجاز را تعیین می‌کند:
allowedfiletypes: 
['image/jpeg','image/png','image/gif']
 allowedfileextensions   پسوند فایل هایی که برای آپلود مجاز هستند را معرفی می‌کند.
allowedfileextensions:
 ['.apk','.jar']
 maxfilesize   حداکثر حجم مجاز برای هر فایل که به مگابایت بیان می‌شود.
 docOver   این رویداد زمانی اجرا می‌شود که فایل‌های درگ شده شما وارد محیط یا پنجره مرورگر می‌شود.
 uploadStarted 
 این رویداد زمانی اجرا میگردد که فرایند آپلود هر فایل به طور جداگانه در حال آغاز شدن است:
متغیر i در کد زیر شامل اندیس فایلی است که آپلودش آغاز شده است و این اندیس از صفر آغاز می‌شود.
متغیر file دسترسی شما را به اطلاعات یک فایل باز میکند مانند نام فایل.
متغیر len تعداد فایل هایی را که کاربر در محل آپلود رها کرده است، باز میگرداند.
function(i, file, len){

    },
uploadFinished 
با اتمام آپلود هر فایل، این رویداد فراخوانی می‌گردد. دو پارامتر اول آن، همانند سابق هستند. پارامتر response خروجی json ایی را که در سمت سرور برگرداندیم، به ما باز می‌گرداند. پارامتر بعدی، زمانی را که برای آپلود طول کشیده است، بر می‌گرداند.
 function(i, file, response, time) {
    }
progressUpdated 
این رویداد برای نمایش پیشرفت یک آپلود مناسب است که آخرین پارامتر آن یک عدد صحیح از پیشرفت فایل را بر می‌گرداند.
function(i, file, progress) {
    },
globalProgressUpdated 
این رویداد میزان پیشرفت کلیه فایل‌ها را به درصد باز می‌گرداند:
function(progress) {
        $('#progress div')
.width(progress+"%"); }
speedUpdated 
سرعت آپلود هر فایل را با کیلوبیت بر ثانیه مشخص می‌کند.
function(i, file, speed) {
    }
rename
در صورتی که قصد تغییر نام فایل ارسالی را دارید می‌توانید از این رویداد استفاده کنید. پارامتر name، نام اصلی فایل را بر می‌گرداند که می‌توانید آن را دستکاری کنید و نام جدیدی را به عنوان خروجی برگردانید. نمونه کاربردی از این رویداد
 rename: function(name) {
    }

beforeEach 
این رویداد قبل از آپلود هر فایل آغاز می‌گردد و برگرداندن مقدار false در آن باعث جلوگیری و کنسل شدن آپلود آن فایل می‌گردد.
function(file) {
    }

beforeSend 
پارامترهای اولی تکراری هستند ولی آخرین پارامتر یک تابع done را می‌توان به آن پاس کرد که قبل از اجرای کل عملیات آپلود صدا زده می‌شود.
 function(file, i, done) {
    }
رویدادی به اسم queuefiles هم هست تعداد فایل‌هایی را که میتوانند به طور موازی و همزمان آپلود گردند، مشخص می‌کند. ولی دراین حالت maxfiles مورد استفاده قرار نمی‌گیرد. جهت بررسی یک مثال عملی و همچنین کدهای سمت سرور در PHP میتوانید از این آموزش استفاده کنید.
با تستی که به صورت لوکال رو آن انجام دادم به نظر نمی‌رسد برای فایل‌های با حجم متوسط به بالا مناسب باشد و برای فایل‌های با حجم کم مناسب می‌باشد. یک فایل 8 مگابایتی در حالت لوکال 9 ثانیه آپلود آن زمان برد و برای فایل‌های بزرگتر، فایرفاکس دیالوگ Stop Script را نشان داد.

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

Bootstrap FileStyle
اگر از قالب بوت استراپ استفاده می‌کنید و دوست دارید روی المان input file  قدیمی، ولی به شکلی مدرن کار کنید این کتابخانه هم فراموش نشود.

DropZoneJS
این کتابخانه به نسبت DropFile امکانات بیشتری را دارد و در سایت اختصاصی آن مثال‌ها و مستندات خوبی قرار گرفته است. در ساده‌ترین حالت آن ابتدا فایل کتابخانه  را صدا زده و سپس تگ فرم را به آن نسبت دهید:
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>

<form action="/upload-target" class="dropzone"></form>
ولی اگر بخواهید آن را به سمت سرور ارسال کنید و  از آنجا آن را کنترل کنید، کد فرم را به شکل زیر تغییر دهید:
ابتدا بسته‌ی نیوگت آن را صدا بزنید:
Install-Package dropzone

با نصب این کتابخانه یک سری فایل CSS هم به سیستم اضافه می‌شود که می‌توانید برای استایل دهی هر چه بیشتر از آن بهره ببرید. کد فرم را به شکل زیر تغییر دهید:
    <form action="~/Home/SaveUploadedFile" method="post" enctype="multipart/form-data" class="dropzone" id="dropzoneForm" style="width: 50px; background: none; border: none;">
        <div class="fallback">
            <input name="file" type="file" multiple />
            <input type="submit" value="Upload" />
        </div>
    </form>
تگی که با کلاس fallback مزین شده است موقعی به کار می‌آید که مرورگر از این کتابخانه پشتیبانی نکرده و مجبور به نمایش یک آپلود معمولی می‌شویم.
با استفاده از کدنویسی هم می‌توان یک المان را به یک آپلودر تبدیل کرد:
var myDropzone = new Dropzone("div#myId", { url: "/file/post"});

//============ OR ====================
$("div#myId").dropzone({ url: "/file/post" });
همانطور که می‌بینید الزامی برای اینکه از یک تگ فرم استفاده کنید ندارد.
برای کانفیگ آپلودرهایی که از طریف المانهای Html ایجاد می‌شوند، می‌توان از کد زیر استفاده کرد و یک تنظیم عمومی برای تمامی آپلودرهای html آن صفحه ایجاد کرد.
Dropzone.options.myId= {
  paramName: "file", //نام پارامتری که فایل از طریق آن انتقال می‌بابد
  maxFilesize: 2, // MB
  accept: function(file, done) {
    if (file.name == "justinbieber.jpg") {
      done("Naha, you don't.");
    }
    else { done(); }
  }
};
تابع بالا یک آرگومان از نوع file را برگردانده و اگر این تابع، تابع done را با پارامتری رشته‌ای صدا بزند، عملیات آپلود آن فایل کنسل شده و پیام خطایی را نمایش می‌دهد و در صورتیکه بدون پارامتر صدا زده شود، عمل آپلود بدون مشکل انجام می‌شود.
ازآنجا که این کتابخانه از تنظیمات وسیعی استفاده می‌کند و از حوصله‌ی این مقاله خارج است، بهتر هست که صفحه‌ی مستندات آن را که کامل هم هست، مطالعه بفرمایید. از سری قابلیت‌هایی که پشتیبانی می‌کند: موارد پوشش داده شده در FileDrop، ساخت layout، ایجاد صف، متد حذف و اضافه و از این قبیل، ایجاد تصویر تمبر مانند و ...

یک نکته تکمیلی در مورد آپلود: در ASP.net به طور پیش فرض نهایت حجم فایل آپلودی 4 مگابایتی تعیین شده است که میتوانید آن را از طریق web.config تغییر دهید:
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="1048576" />
    </system.web>
</configuration>
برای IIS 7 به بعد هم از تکه کد زیر استفاده کنید:
<system.webServer>
   <security>
      <requestFiltering>
         <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
   </security>
 </system.webServer>
در هر دو کد بالا نهایت حجم بر روی یک گیگابایت تعیین شده است که maxRequestLength به صورت کیلوبایت و maxAllowContentLength به صورت بایت تعیین شده است. توصیه می‌شود هر دو شکل آن را وارد کنید. به خصوص که IIS Express از کد ابتدایی استفاده می‌کند و بخواهید نتیجه‌ی آن را در تست‌ها ببینید.

مطالب
الگوریتم‌های داده کاوی در SQL Server Data Tools یا SSDT - قسمت سوم - الگوریتم‌های Decision trees و Linear Regression

در قسمت قبل با الگوریتم Naive Bayes به عنوان الگوریتمی جهت شروع امر داده کاوی آشنا شدیم. در این قسمت به الگوریتم‌های Decision trees و Linear Regression می‌پردازیم.


مقدمه 

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


چرا الگوریتم درخت تصمیم؟

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


تفسیر الگوریتم

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


شرح نوار ابزار


  • کمبوی مربوط به ،Tree شامل درخت‌های تصمیم مربوط به خروجی‌ها (ویژگی‌هایی که می‌خواهیم پیش بینی کنیم) می‌باشد.
  • Default Expansion اندازه درخت را مشخص می‌کند. به عبارتی مشخص می‌کند که درخت چند سطحی باشد.
  • هیستوگرام تعداد حالات ویژگی قابل پیش بینی را مشخص می‌کند که از طریق آن می‌توان در یک نگاه با توجه به رنگ حالت مورد نظر در هر نود، یک مسیر مشخص را در درخت طی کرد. برای مثال فرض کنید که یک ویژگی دارای 10 حالت باشد که برای شما 5 حالت از این 10 حالت مهمتر است. بنابراین تعداد را روی 5 تنظیم می‌کنیم. مابقی حالات در یک گروه قرار گرفته به رنگ خاکستری نشان داده می‌شوند.
  • کمبوی Background جهت کنترل رنگ پیش زمینه نود‌ها می‌باشد. در حالت پیش فرض، این کمبو تمامی حالات ویژگی مورد پیش بینی را در نظر می‌گیرد. در این حالت رنگ تیره‌تر نود نشان دهنده تعداد موردها در آن نود می‌باشد. هرچه این رنگ تیره‌تر باشد، یعنی موارد بیشتری در آن دسته قرار می‌گیرند. شما همچنین می‌توانید یک حالت خاص از ویژگی مورد پیش بینی را انتخاب کنید. در این حالت رنگ پس زمینه هر نود احتمال پیش بینی با توجه به حالت انتخاب شده را نشان می‌دهد. نود با پس زمینه پر رنگ‌تر احتمال بالاتری با توجه به حالت انتخاب شده دارد. 


آموزش بیش از اندازه

این الگوریتم، درخت را به صورت بازگشتی رشد می‌دهد. درنتیجه گاهی اوقات ممکن است که با یک درخت بزرگ مواجه شوید. این درخت می‌تواند شامل سطح‌ها و شاخه‌های زیادی باشد. بنابراین شامل قوانین زیادی هم خواهد بود. اما در نظر داشته باشید که ارتباط مستقیمی بین کیفیت پیش بینی و اندازه درخت وجود ندارد. حقیقت امر این است، هرگاه که درخت بیش از اندازه عمیق شود، بجای اینکه تعمیم قوانین صورت گیرد، آموزش حالات مختلف نشان داده می‌شود و این خوب نیست. الگوریتم درخت تصمیم مایکروسافت ویژگی دارد به نام forward pruning که رشد درخت را با استفاده از امتیاز بایزین کنترل می‌کند. به عبارتی زمانیکه اطلاعات کافی برای بخش کردن یک نود وجود نداشته باشد، از این امر جلوگیری می‌کند. این کار توسط پارامتر Complexity_Penalty انجام می‌گردد که مقداری اعشاری بین 0 و 1 را می‌گیرد. هرچه مقدار بالاتری به این پارامتر اختصاص داده شود، محدودیت بیشتری برای تقسیم درخت درنظر گرفته می‌شود و بنابراین سایز درخت کوچکتر می‌گردد.


پارامترهای الگوریتم درخت تصمیم

دسترسی به این پارامترها از طریق تب mining models  امکان پذیر می‌باشد. با کلیک بر روی الگوریتم پنجره، properties  آن نمایش داده خواهد شد حال می‌توان به بخش Algorithm Parameters  رفت و پارامترها را مقداردهی کرد. 

Complexity_Penalty : که توضیح آن در بخش "آموزش بیش از اندازه" آورده شد.

Minimum_Support : جهت تعیین مینیمم اندازه هر نود به کار می‌رود. برای مثال اگر مقدار 20 را به آن بدهیم، آنگاه هر تقسیم بندی که منجر به تولید نودهای فرزندی با اندازه کمتر از 20 شود، انجام نمی‌گردد. اغلب در مواردی که مجموعه داده دارای حالات گوناگون زیادی است، می‌توان مقدار این متغیر را بالا برد تا از آموزش بیش از اندازه جلوگیری کرد. پیش فرض این پارامتر 10 می‌باشد.

Score_Method : این پارامتر مشخص می‌کند که از کدام روش برای محاسبه امتیاز جهت بخش بندی درخت استفاده کنیم. سه مقدار 1، 3 و 4 را می‌گیرد. 1 از امتیاز انتروپی استفاده می‌کند، 3 از بایزین k2 و 4 از بایزین Dirichlet equivalent .

Split_Method : سه مقدار 1 تا 3 را می‌گیرد. فرض کنید که وضعیت تحصیل در یک مجموعه داده سه حالت را دارد: دیپلم، لیسانس، فوق لیسانس. اگر مقدار 1 را برای این پارامتر تعیین نماییم آنگاه حالت دودویی برای تقسیم نودها درخت درنظر گرفته می‌شود. یعنی دو حالت دیپلم و غیر دیپلم. حال اگر مقدار 2 را نظر بگیریم آنگاه تقسیم نودها براساس تمامی حالات درنظر گرفته می‌شود؛ در اینجا سه تا. مقدار 3 که مقدار پیش فرض نیز می‌باشد، انتخاب حالت 1 یا 2 را به عهده الگوریتم می‌گذارد.

Maximum_Input_Attributes : ماکزیمم ورودی را می‌توان از این طریق تعیین کرد. اگر تعداد ورودی‌ها بیشتر از این مقدار باشد، آنگاه فقط ورودی‌های مهم درنظر گرفته شده و مابقی نادیده گرفته می‌شوند.


Linear Regression:

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

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

قبل از شروع، یک خبر!
VsDoc for jQuery 1.3.1 (جهت فعال سازی intellisense آخرین نگارش جی کوئری در VS.Net)


اگر سعی کنید jQuery را به همراه سایر کتابخانه‌های جاوا اسکریپتی دیگر به صورت همزمان استفاده کنید (مثلا mootools یا ASP.Net Ajax و امثال آن)، احتمالا قسمتی و یا تمامی کدهای جاوا اسکریپتی شما کار نخواهند کرد. برای مثال update panel شما در ASP.Net Ajax از کار می‌افتد، یا کدهای mootools شما دیگر کار نمی‌کنند. علت اینجا است که تمامی این کتابخانه‌ها از نشانه $ به عنوان متغیری عمومی که بیانگر نام مستعار کتابخانه مربوطه است استفاده می‌کنند و در نهایت تمام این‌ها با هم تداخل خواهند کرد.

خوشبختانه jQuery امکان رفع این تداخل را پیش بینی کرده است که به صورت زیر می‌باشد:

<script type="text/javascript" language="javascript" src="jquery.min.js"></script>
<script type="text/javascript">
jQuery.noConflict();
jQuery(document).ready(function($) {
//tip-1
$("select > option").each(function() {
var obj = $(this);
obj.attr("title", obj.attr("value"));
});
//tip-1
});
</script>

کد مثال فوق، به تمامی آیتم‌های drop down list‌ های شما در یک صفحه، بر اساس value هر آیتم موجود در آن‌ها، یک tooltip اضافه می‌کند. (با IE7 به بعد و فایرفاکس سازگار است)
در اینجا ابتدا jQuery.noConflict فراخوانی شده و سپس document ready متداول هم باید اندکی مطابق کد فوق تغییر کند. مابقی کدهای شما از این پس نیازی به تغییر نخواهند داشت. (روش‌های دیگری هم برای تغییر نام $ وجود دارند که در مستندات مربوطه قابل مشاهده است)