بررسی آمار ارائه شده توسط stackoverflow (قسمت دوم)

stackoverflowراستش زمانی که شروع با خواندن اصل مطلب کردم یک سری از پیش فرض هایی که در رابطه با تولید نرم افزار داشتم به چالش کشیده شد.به عنوان مثال در قسمت قبلی ذکر کردم که خیلی وقت ها شی گرایی نقض شده است و از کلاس های static استفاده شده .یا مثلا این که فکر می کردم زمانی که تعداد کاربر به میلیون رسید حتماً نیاز است ده ها سرور داشته باشیم.ولی متوجه شدم که خیلی جاهها توانسته اند با کد مشکل را حل کنند و خیلی از جاهها با سخت افزار.در واقع تعادل برقرار کرده اند.البته مطمئنا آن ها خیلی خوب می دانند هزینه توسعه خیلی گران تر از هزینه سخت افزار است.

موضوع بعدی که خیلی توجه من را به خودش جلب کرد در رابطه با تست بود.در stackoverflow تعداد تست های واحد بالا نیست.زیرا از کدهای static بسیار استفاده شده علاوه بر آن نیازی نمی دیدند این کار را انجام دهند زیرا یک انجمن بسیار قوی این کار را انجام می دهد.البته موضوع مهم این است که اگر همان تست های واحد محدود و همچنین تست های UI و سایر تست های اتوماتیک پاس نشوند محصولی وارد عملیات نمی شود.چیزهایی که باید تست شوند حتما تست می شوند و تست واحد هم خواهند داشت.مثل قسمت هایی که با پول سرو کار دارند.

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

اگر یکبار به stackoverflow  سر بزنید متوجه خواهید شد که از سرعت قابل توجهی برخوردار است.هدف آن ها این بوده که صفحه اصلی کمتر از ۵۰ms لود شود.آن ها به performance به چشم ux نگاه می کنند که البته این طور هم هست.در حال حاضر من در رابطه با سرعت یکی از پروژه هایم با مشکل روبرو هستم و کاری توانستم انجام دهم لاگ کردن زمان requestها است.نکته جالب این است که stackoverflow هم خیلی قبل تر از من این کار را کرده.از این کار برای پیدا کردن نقاطی که خیلی هزینه بر هستند استفاده می کند.

نکاتی که قابل تامل است:

  • در قسمت قبل درباره عدم اجبار به استفاده از لینوکس و ویندوز جمله ای گفتم:
    هر جایی که نیاز بوده از ویندوز و هر جایی که نیاز بوده از لینوکس استفاده کرده اند.با توجه به این موضوع آن ها متوجه شده اند که redis در لینوکس بهتر جواب خواهد داد،پس از لینوکس استفاده کرده اند.
  • موضوع بعدی که قابل توجه است،استفاده بسیار زیاد از SSD است.تمام دیتابیس ها از SSD استفاده می کنند و توانستند به وسیله SSD سرعت نوشتن را  بهبود ببخشند.
  • در اکثر اوقات نیاز به افزودن سخت افزار و سرور جدید نیست و  اگر به خوبی کد نوشته باشیم می توانیم نهایتا با افزودن رم به کارایی مد نظرمان برسیم.
  • آن ها تست ندارند ،چون به تست نیازی ندارند.بنابراین زمانی کاری را انجام می دهند که نیاز به آن داشته باشند.نه این که چون با کلاس است تست بنویسند.
  • از اختراع مجدد چرخ ترسی نداشته اند و هر جاییکه توانستند کد سبک تر و بهتر بنویسند چرخ را از اول اختراع کرده اند.
  • هر زمان که نیاز بوده به عمق رفته اند و با IL کد زده اند.
  • زمانی که تیم به ابزاری نیاز دارند بدون وجود هیچ روند کاری(نامه نکاری،دستور رئیس و…) برای آن ها تهیه می شود.
  • هزینه های Garbage collection به شدت پایین آورده اند.این کار باعث بالا رفتن کارایی برنامه های شده.
  • آن ها متوجه شده اند که هزینه کد ناکارآمد خیلی بیشتر از آن چیزی است که فکر می کنید.

من به شخصه خیلی درس گرفتم.در پایان:

The difference between “theory” and “practice” is that in theory there is no difference between theory and practice, but in practice, there is.

بررسی آمار ارائه شده توسطstackoverflow (قسمت اول)

stackoverflow

قطعا یکی از بزرگترین سایتهایی که با تکنولوژی دات نتی نوشته شده سایت stackoverflow است .که در تاریخ نگارش این مطلب حدود ۵۶۰ میلیون بازدید در ماه دارد.این ۵۶۰ میلیون بازدید را به وسیله ۲۵ سرور مدیریت می کند.واقعا برای من این رقم خیلی بزرگ است.من در ایران در پروژه ها مختلفی شرکت داشته ام و تا به حال به نصف این رقم را هم ندیده ام.بنابراین برایم این آمار خیلی جالب آمد.زیرا برنامه ای که هم اکنون روی آن کار می کنم تنها چهار هزار کاربر همزمان دارد و با کلی مشکل رویرو هستیم.

شبکه StackExchange در حال حاضر ۵۴مین سایت از نظر ترافیک در دنیا است.آن ها ۱۱۰ مجموعه سایت دارند.حدود ۴ میلیون کاربر،۴۰ میلیون جواب را در پایگاه داده های خود ذخیره می کنند.

کل این مجموعه سایت ها را ۲۵ سرور مدیریت می کند.این ۲۵ سرور به منظور مدیریت همه کار استفاده می شود.high availability، load balancing،caching،databases،searching.

همانطور که در بالا نیز اشاره داشتم آن ها از تکنولوژی های مایکروسافتی استفاده می کنند.ولی هیچ کجا محدودیتی ندارند و در جاهایی که نیاز باشد از لینوکس نیز استفاده می کنند.

حال به موقعیت کنونی آن نگاهی کنیم:

StackExchange network has 110 sites growing at a rate of 3 or 4 a month.

۴ million users

۸ million questions

۴۰ million answers

As a network #54 site for traffic in the world

۱۰۰% year over year growth

۵۶۰ million pageviews a month

Peak is more like 2600-3000 requests/sec on most weekdays. Programming, being a profession, means weekdays are significantly busier than weekends.

۲۵ servers

۲ TB of SQL data all stored on SSDs

Each web server has 2x 320GB SSDs in a RAID 1.

Each ElasticSearch box has 300 GB also using SSDs.

Stack Overflow has a 40:60 read-write ratio.

DB servers average 10% CPU utilization

۱۱ web servers, using IIS

۲ load balancers, 1 active, using HAProxy

۴ active database nodes, using MS SQL

۳ application servers implementing the tag engine, anything searching by tag hits

۳ machines doing search with ElasticSearch

۲ machines for distributed cache and messaging using Redis

۲ Networks (each a Nexus 5596 + Fabric Extenders)

۲ Cisco 5525-X ASAs (think Firewall)

۲ Cisco 3945 Routers

۲ read-only SQL Servers for used mainly for the Stack Exchange API

VMs also perform functions like deployments, domain controllers, monitoring, ops database for sysadmin goodies, etc.

حال نگاهی کنیم به پلتفورم های استفاده شده:

ElasticSearch

Redis

HAProxy

MS SQL

Opserver

TeamCity

Jil – Fast .NET JSON Serializer, built on Sigil

Dapper – a micro ORM.

WebSockets

دیتابیس:

Stack Exchange به ازای هر سایت یک دیتابیس دارد.یعنی یکی برای Stack Overflow،یکی برای Super User یکی برای  Server Fault .این رویکرد باعث ساده تر شدن horizontal scaling خواهد شد.اگر تغییری در یک دیتابیس داشته باشند به طور اتوماتیک در باقی دیتابیس ها در یک زمان اعمال می شود.علاوه بر آن مسئله مهم این است که این تغییرات باید سازگاری با نسخه های پیشین را حفظ کنند.برای مثال اگر یک ستون نامش بخواهد تغییر کند ابتدا یک ستون جدید اضافه می شود.سپس داده ها ستون قبلی به ستون جدید منتقل می شود.بعد از آن کد را تغییر می دهند تا با دو ستون بتواند کار کند.سپس دوباره کد را تغییر می دهند تا بتواند با ستون جدید کار کند و سپس ستون قبلی را حذف می کنند.

در این مجموعه سایت ها ،جدولی که برای امتیاز ها استفاده می شود denormalized است.همچنین آن ها از ORMی به نام dapper استفاده می کنند.

مهمترین قسمت موضوع:کد:

اکثر برنامه نویس ها به صورت ریموت کار می کنند.

کامپایلها خیلی سریع انجام می شوند.

با یک  کامپایل کد ها به سرور stage انتفال داده می شود.

امکانات جدید به وسیله Feature toggle مخفی می شوند.

بعد به Meta.stackoverflow برای تست انتقال داده می شوند.آن جا مکان مناسبی برای تست نرم افزار است زیرا هزار کاربر در روز با آن کار خواهند کرد.

دوباره به وسیله جامعه بزرکتر تست خواهند شد.

یکی از موضوعاتی که به شدت در کدهای آن ها به چشم می خورد استفاده شدید از static classes و methods برای بالا بردن کارایی برنامه است.

هر برنامه نویس دو یا سه مانیتور خواهند داشت.زیرا بهره وری را به شدت افزایش می دهد.

کش کردن:۵ لایه کش کردن در این مجموعه سایت ها وجود دارد:

۱st: is the network level cache: caching in the browser, CDN, and proxies.

۲nd: given for free by the .Net framework and is called the HttpRuntime.Cache. An in-memory, per server cache.

۳rd: Redis. Distributed in-memory key-value store. Share cache elements across different servers that serve the same site. If StackOverflow has 9 servers then all servers will be able to find the same cached items.

۴th: SQL Server Cache. The entire database is cached in-memory. The entire thing.

۵th: SSD. Usually only hit when the SQL server cache is warming up.

دیپلوی:می تواند روزی ۵ بار دیپلوی کنند.ولی به این معنی نیست که خیلی دیپلوهای بزرگی هستند زیرا آن ها نمی توانند سایت را به طور کلی از دسترس خارج کنند و ممکن است نیاز باشد دیپلوهای کوجک را انجام دهند.

تیم:

SRE (System Reliability Engineering): – 5 people

Core Dev (Q&A site) : ~6-7 people

Core Dev Mobile: 6 people

Careers team that does development solely for the SO Careers product: 7 people

نکاتی درباره HTTP نسخه ۲

احتمالا کم کم سروصدای نسخه جدید اصلی ترین پروتکل وب یعنی HTTP/2 را شنیده اید.در این پست قصد دارم یک بررسی سطحی از آن ارائه دهم.

HTTP/2 دارای APIهای یکسان با نسخه کنونی HTTP است:

به عبارت دیگر متد جدیدی را معرفی نمی کند.به عنوان مثال در Header یا در status code ها تغییری نمی دهد و شما قادر خواهید بود که فقط با بروزرسانی کتابخانه ای که هم اکنون برای HTTP/1 استفاده می کنید،HTTP/2 را نیز در برنامه خود پشتیبانی کنید و این موضوع بدون تغییر در برنامه شما امکان پذیر است.

درخواست های سبک تر:

در HTTP/1 برای کارایی بالاتر بهتر بود از Requests های اضافی پرهیز کرد زیرا Requests  بسیار سنگین بود.در نسخه جدید HTTP/2 دیگر به این تکنیک ها نیازی نیست زیرا در این پروتکل سعی شده است که سربار ایجاد یک درخواست جدید کاهش یابد.این کار به وسیله multiplexing انجام می شود.درواقع HTTP/2 از multiplexing برای انتقال چند پیام در یک connection در زمان یکسان استفاده می کند بنابراین ما یک پاسخ (response)نیز خواهیم داشت.

شبکه و سرور آسوده تر:

به علت connection کمتر سرور و شبکه بار کمتری را تحمل می کنند.برای مثال اگر یک موبایل از شش ارتباط TCP به منظور دانلود یک صفحه از چند سرور متفاوت استفاده کند به راحتی بافر شبکه موبایل با سربار مواجه خواهد شد و ممکن است بسیاری از پکت ها را از دست بدهد.HTTP/2 به شما اجازه برقراری یک ارتباط را به ازای هر هاست می دهد و سایت ها را نیز تشویق می کند که در صورت امکان محتوای خود را روی یک هاست قرار بدهند.

Cache Pushing:

موضوع زیبای دیگر برای کارایی بهتر این است که HTTP/2  به سرور اجازه می دهد که در صورت لزوم چیزهایی را برای استفاده در آینده توسط کلاینت به کش کلاینت پوش کنند.به عنوان مثال زمانی که شما یک صفحه Html را درخواست می دهید و آن صفحه به چند فایل stylesheets لینک داده است.در این صورت سرور بدون اینکه منتظر درخواست کلاینت برای آن فایل شود شروع به فرستادن آن فایل ها نیز می کند.علاوه بر آن امکان بروز رسانی کش های کلاینت که غیر معتبر شده اند را نیز وجود دارد.البته این امکان هم هست که کلاینت نیازی به دریافت این اطلاعات نداشته باشد که برای آن هم راه حلی اندیشیده شده است.

 

کلاینت می تواند درخواست خود را تغییر دهد:

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

رمزنگاری:

در HTTP/2  نیازی نیست که حتما از TLS استفاده کنید.البته Firefox و Chrome اعلام کرده اند که فقط از HTTP/2 به همراه TLS پشتیبانیخواهند کرد.

دیگر خبری از متن نیست:

همانطور که می دانید در نسخه قبلی ،HTTP یک پروتکل متنی بود و می توانستید به راحتی یک درخواست متنی را بسازید و بوسیله telnet به سمت سرور ارسال کنید و منتظر جواب بمانید ولی این پروتکل در نسخه جدید بسیار فرق کرده و دیگر خبری از متن نیست و متن به باینری تبدیل شده.این کار دلایلی مختلفی دارد.از جمله اینکه پردازش باینری ساده تر از پردازش متن است و همچنین نحوه چگونگی پردازش متن هم در این جا مشکل ساز بود که در HTTP/2 حل شده است.

همانطور که دید بیشتر تمرکز HTTP/2 برای بهبود کارایی است. ازطرفی بدون شک نقاط منفی نیز در آن دیده می شود.به عنوان مثال به علت اینکه مرورگر حق باز کردن یک connection را دارد ممکن است packet lost بیشتر خودش را نشان بدهد.

ارتباط در Signalr

اگر با signalr آشنایی ندارید از اینجا شروع کنید.

قبل هر موضوعی باید مفاهیم و انواع connection در SignalR را با هم بررسی کنیم.در SignalR ما با سه نوع connection در ارتباط هستیم.

SignalR connection: به ارتباط منطقی بین کلایت و سرور اشاره دارد که به وسیله یک آی دی منحصر بفرد نگهداری می شود.این داده به وسیله singalr برای برقراری یک Transport connection  استفاده می شود.زمانی که این ارتباط به هر دلیلی قطع شد singalr داده های مربوط به کلاینت را حذف خواهد کرد.این قطعی ارتباط می تواند به هر دلیل اتفاق بیافتد.مثل زمانی که کلاینت متد stop را صدا بزند و یا زمان timeoutدر هنگام transport connection بگذرد.

Transport connection:به ارتباط بین کلاینت و سرور اشاره دارد  که به وسیله یکی از چهار API پشتیبانی شده توسط singalr نگهداری می شود.WebSockets, server-sent events, forever frame, یا long polling.

Signalr از transport API برای ساختن Transport connection استفاده می کند. transport API با توجه به شبکه فیزیکی  یک transport connection را ایجاد می کند.زمانی که Signalr متوجه شود connection قطع شده است Transport connection نیز قطع می شود.

Physical connection:به لینک فیزیکی مثل سیم،سیگنال های بی سیم و .. اشاره دارد.این ارتباط به منظور برقراری Transport connection نیاز است علاوه بر آن Transport connection نیز به منظور برقراری SignalR connection نیاز است.زمانی که Physical connectionبه هر دلیلی قطع شود بلافاصله Transport connection و یا SignalR connection قطع نخواهند شد.در ادامه بیشتر توضیح خواهم داد.

 

در دیاگرام زیر Hubs و PersistentConnection مشخص کننده SignalR connection هستند. علاوه بر آن لایه transport نیز مشخص کننده transport connection است.خطوط بین کلاینت و سرور نیز مشخص کننده physical connection هستند.

معرفی SignalR و ارتباطات بلادرنگ

زمانی که شما متد Start را در کلاینت صدا می زنید،شما در حال فراهم کردن کلیه اطلاعات مورد نیاز برای برقراری یک ارتباط فیزیکی هستید.SignalR در کلاینت از این اطلاعات به منظور ساخت یک درخواست HTTP  و برقراری یک physical connection استفاده می کند. این درخواست از یکی از چهار متد transport  استفاده می کند.اگر به هر دلیلی این درخواست fail  شود SignalR connection بلافاصله از بین نخواهد رفت.به این دلیل که کلاینت هم اکنون نیز اطلاعات کافی برای برقراری مجدد ارتباط را به وسیله یک transport connection جدید دارد.در این سناریو هیچ مداخله ای توسط برنامه کاربر صورت نمی گیرد و درصوتی که یک transport connection جدید ایجاد شد یک SignalR connection جدید ایجاد نمی شود.این موضوع را می توان از عدم تغییر connection ID متوجه شد.

زمانیکه که در حال برقرار کردن یک transport connection جدید هستیم eventی به نام OnReconnected  اجرا می شود.OnDisconnected هم زمانی که SignalR connection از بین می رود اجرا می شود.

چه زمانی SignalR connection  از بین می رود:

زمانی که کلاینت متد Stop را صدا بزند.پیام stop به سمت سرور ارسال می شود.در این زمان هم کلاینت و هم سرور به سرعت connection را خواهند بست.

زمانی که کلاینت در مد  reconnect است سرور منتظر اتصال مجدد کلاینت می ماند.اگر به هر دلیلی این اتصال مجدد محقق نگردد و زمان timeout  نیز به اتمام برسد در این صورت دیگر کلاینت برای reconnect  تلاش نخواهد کرد و همچنین سرور نیز SignalR connection را disposes خواهد کرد.

اگر به هر دلیلی کلاینت نتواند متد Stop را صدا بزند سرور مدتی برای اتصال مجدد صبر خواهد کرد.و پس از timeout سرور SignalR connection را disposes خواهد کرد.

اگر سرور نیز به هر دلیلی متوقف شود در این حالت کلاینت برای ارتباط مجدد تلاش می کند و در صورتیکه از مدت timeout بگذرد کلاینت دیگر برای ارتباط مجدد تلاش نخواهد کرد.

در حالت معمول نیز اگر کلاینت متد Stop را صدا بزندSignalR connection و transport connection به طور همزمان بسته خواهند شد.

موضوع بعدی که مطرح می شود بسته شدن Transport connection است:

در واقع این امکان وجود دارد که Physical connections به هر دلیلی کند باشد و یا وقفه هایی همراه باشد.با توجه به اینکه میزان و طول این وقفه ها به چه میزان است ممکن است transport connectionمتوقف شود.در این حالت signalr برای ارتباط مجدد تلاش خواهد کرد.ممکن است در حالاتی signalr متوجه قطع شدن transport connection بشود ولی در سناریوهایی ممکن است که نه API های مورد استفاده برای transport connection  و نه SignalR متوجه از بین رفتن ارتباط بشوند.در این حالت به جز زمانی که ما از long polling استفاده می کنیم،signalr از keepalive برای چک کردن اینکه آیا ارتباط برقرار است یا خیر استفاده می کند.زمانی که یک connectionغیر فعال است سرور به صورت دوره ای یک پکت برای کلاینت ارسال می کند که در حال حاضر هر ده ثانیه این اتفاق رخ می دهد..به وسیله گوش دادن به این پکت ها کلاینت می تواند تشخیص دهد که آیا مشکلی برای ارتباط پیش آمده است یا خیر.

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

اگر کلاینت در مد reconnecting  باشد ولی به هر دلیلی نتواند transport connection را برقرار کند در این حالت سرور بعد از مدت زمان timeout ارتباط را متوقف خواهد کرد در این صورت command مربوط به قطع ارتباط را در جایی صف خواهد کرد و در صورتیکه کلاینت بعدها توانست به سرور وصل شود command را به کلاینت ارسال خواهد کرد.

بعد از قطع ارتباط رویداد OnDisconnected در هاب اجرا خواهد شد.

سناریو هایی که در آن ارتباط کلاینت قطع خواهد شد:

ارتباط با سرور اگر توسط مرورگر کاربر باشد در این حالت در صورتی که کاربر به هر دلیلی از صفحه ای به صفحه دیگر برود کدهای سمت کلاینت در SignalR متد Stop  را صدا خواهند زد.

سناریو هایی که در آن ارتباط سرور قطع خواهد شد:

زمانی که به هر دلیلی سرور خاموش شود یا app domain را recycles کنیم یا حالت هایی مثل این موضوع،ارتباط بلافاصلاه قطع خواهد شد.در این حالت signalr می بایست بدون اجرا ConnectionSlow  شروع به تلاش برای ارتباط مجدد کند.اگر تا قبل ازمدت زمان timeout سرور به حالت طبیعی برگردد SignalR connection از بین نخواهد رفت.

تفاوت Abstract class با Interface

Feature Interface Abstract class
Multiple inheritance یک کلاس می تواند چند Interface را پیاده سازی کند. یک کلاس فقط می تواند از یک کلاس ارث بری کند چه Abstract باشد و چه Abstract نباشد.
Default implementation در Interface نمی توانیم پیاده سازی داشته باشیم و فقط امضای متد وخواص را می توانیم در آن تعریف کرد. می توان در کلاس Abstract متدهایی را به صورت معمولی  و همچنین به صورت Abstract تعریف کرد.
Access Modifiers در Interface هر چیزی که تعریف شود به صورت پیش فرض public خواهد بود. در کلاس Abstract می توان از انواع Access Modifiers استفاده کرد.
Core VS Peripheral مشخص کننده امکانات ثانوی کلاس هایی است که از interface پیاده سازی می کنند.به عنوان مثال هم انسان و هم ماشین می توانند IMovable را پیاده سازی کنند. مشخص کننده امکانات اصلی یک کلاس  و شی است که از کلاس Abstract ارث برده است.
Speed کند تر از Abstract class است. سریعتر از Interface است.
Adding functionality (Versioning) اگر متدی یا خواصی را به یک Interface اضافه کنید می بایست در تمامی کلاس ها که این Interface را پیاده سازی کرده اند آن متد و یا خاصیت را اضافه کنید. در صورتی که متد یا خاصیتی را در Abstract class اضافه کنیم می توانیم پیاده سازی پیش فرضی برای آن در نظر بگیریم در این صورت نیاز نیست در کلاس های زیر فرزند این متد یا خاصیت پیاده سازی شوند.
Fields and Constants interfaces نمی تواند فیلد یا ثابتی داشته باشد. می توانند فیلد و ثابت داشته باشد.

 

Metaprogramming به چه معنی است؟

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

با توجه به این موضوع دو سطح برنامه نویسی را می توان نام برد:

  • سطح پایه که به آن application گفته می شود و در آن کد،ورودی ها را پردازش می کند.
  • سطح متا که سطح پایه را پردازش می کند.

به زبان دیگر سطح متا قابلیت این را دارد که سایر برنامه ها را پردازش کند.

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

    let str = 'Hello' + '!'.repeat(3);
    console.log('System.out.println("'+str+'")');

همچنین در کد زیر هم سطح پایه و سطح متا با جاواسکریپت نوشته شده است:


  > eval('5 + 2')
    ۷

سه نوع کلی را برای meta programming می توان متصور شد:

  • Introspection:می توان به صورت فقط خواندنی به ساختار یک برنامه دسترسی پیدا کرد.
  • Self-modification:می توان ساختار یک برنامه را تغییر داد.
  • Intercession:می توان یک سری عملگرهای زبان را از نوع تعریف کرد.

هم اکنون metaprogramming در دات نت نیز  به وسیله Roslyn میسر شده است.

Joel Test برای برنامه نویسان

به احتمال زیاد با Joel Test تست آشنا هستید.این تست توسط Joel Spolsky مدیر مجموعه Stack Exchange Network برای ارزیابی یک تیم نرم افزاری ابداع شده است.این تست شایستگی یک تیم نرم افزاری را اندازه گیری می کند.

حال با توجه به Joel Test  تست جدیدی با یک رویکرد جدید مطرح شده است که یک برنامه نویس را ارزیابی می کند.با هم نگاهی به دوازده مورد آن خواهیم انداخت.

the-joel-test-for-programmers-758x818

  1. آیا می توانیداز سورس کنترل به طور موثر استفاده کنید؟
  2. آیا می توانید مشکلات الگوریتمی خود را حل کنید؟
  3. آیا می توانید با بیشتر از یک زبان یا تکنولوژی برنامه بنویسید؟
  4. آیا برنامه ای برای اینکه هر روز دانش و مهارت خود را افزایش دهید دارید؟
  5. آیا از اسامی مناسب استفاده می کنید؟
  6. آیا  می توانید با ایده های خود ارتباط موثر برقرار کنید؟
  7. آیا مفاهیم پایه ای الگوهای برنامه نویسی را درک کرده اید؟
  8. آیا می توانید به طور موثر دیباگ کنید؟
  9. آیا کدتان را تست می کنید؟
  10. آیا دانش خود را به اشتراک می گذارید؟
  11. آیا از بهترین ابزار برای کارهای خود استفاده می کنید؟
  12. آیا می توانید یک برنامه واقعی بسازید؟

 

مزایای Refactoring قسمت دوم

در قسمت قبل با دو مزیت اصلی Refactoring آشنا شدید در این قسمت درباره دو مزیت دیگر Refactoring خواهم گفت.

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

Refactoring  باعث بالا رفتن سرعت در توسعه نرم افزار می شود:شما به وسیله Refactoring باعث بهبود طراحی سیستم می شوید علاوه بر آن درک شما از کد و سیستم نیز بالا می رود.باگ های سیستم نیز راحت تر پیدا خواهند شد.همه اینها باعث خواهد شد که سرعت توسعه بالا برود.موضوعی که باید به آن توجه کرد این است که طراحی خوب ذاتا باعث افزایش سرعت خواهد شد بنابراین با Refactoring  می توانیم طراحی خوب را همیشه بهبود ببخشیم.

جمع بندی کل دوره تا به اینجا:

Refactoring به معنای تغییر یک سیستم نرم افزاری به منظور ارتقا و بهبود ساختار داخلی آن به صورتی که رفتار بیرونی آن تحت تاثیر قرار نگیرد.اگر بخواهم دقیق تر بگویم ،Refactoring را می توان راهی برای منظم و تمیز کردن ساختار کد دانست.این کار برای جلوگیری از ایجاد باگهای نرم افزاری انجام می شود.

اصول Refactoring  را می توان تا حدودی مجزا از زبان دانست.به عنوان مثال این اصول هم در جاوا و هم در سی شارپ قابل پیاده سازی هستند.

ما می توانیم از رفکتورینگ به عنوان یکی از نیازمندهای Non-functional  سیستم نام ببریم.از مزایای دیگری که این کار دارد می توان به نگهداری ساده تر نرم افزار و همچنین توسعه پذیری راحت تر آن اشاره کرد.

از مزایای Refactoring  می توان به دلایل زیر اشاره کرد:

  • باعث بهبود کارایی سیستم می شود.
  • باعث فهم آسانتر کد می شود.
  • به پیدا کردن باگها کمک می کند.
  • باعث سریعتر شدن کد می شود.

مزایای Refactoring قسمت اول

Refactoring چند مزیت اصلی دارد که در این پست با دو مزیت آن آشنا خواهیم شد.

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