موجودی عجیب! به نام Bloom Filter در برنامه نویسی

بلوم فیلتر و کاربرد آن در برنامه نویسی

خُب این بلوم فیلتر چیه و به چه دردی میخوره را من هم نمی‌دونستم تا اینکه توی مقاله‌ای برای کاهش مصرف حافظه و کاهش افزونگی داده‌های تبادل شده بین نودهای شبکه‌های تحمیل پذیر تاخیر یا DTN بهش برخوردم که البته الان DTN موضوع مورد بحثم نیست و بعدا در یک نوشته جدا بهش می‌پردازم.

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

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

احتمالا شما هم مثل من گیچ شدید 🙂

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

حالا بیاید دنبال Y بگردیم و خب نتیجه جست و جو به ما میگه که Y در لیست نیست. در این حالت ما قطعا می‌تونیم بگیم که Y وجود نداره چرا؟ چون اصلا وارد نشده هنوز تا اسمش توی کاغذ ما ثبت بشه.

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

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


تعریف Bloom filter

احتمالا می‌دونید که جدول درهم سازی(hash table) چطور کار می کنه؟ اگر نمی‌دونید پیشنهاد می‌کنم یک سری به ویکی بزنید.

در علوم رایانه، جدول درهم‌سازی یا جدول هش نوعی ساختمان داده است که مقدارهایی[۱] که باید ذخیره شوند را به وسیله تابع هش (درهم سازی) با کلیدهای ویژه‌ای مرتبط می‌سازد. عملیات اولیه‌ای که این جدول تسهیل می‌کند عمل مراجعه است. به این معنی که کاربر می‌تواند با سرعتی کارآمد داده مورد نظرش را در آن بیابد. در جدول‌های هش همچنین افزودن داده‌های جدید در زمان کم امکان‌پذیر است. زمان لازم برای جستجو و افزودن وابسته به نوع جدول و میزان داده‌ها هستند. این زمان می‌تواند با انتخاب جدول مناسب به مرتبه زمانی O(1) برسد.

وقتی شما یک داده جدید در یک آرایه یا لیست ساده وارد می کنید، index همون مکانی که داده در آن قرار داده می شه از روی داده ای که داره تشخیص داده نمی‌شه. این به این معنی هست که ارتباط مستقیمی بین index و مقدار ذخیره شده در اون خونه از آرایه وجود ندارد.به همین دلیل اگر شما نیاز داشته باشید که یک مقدار را در آرایه جست و جو کنید، مجبور خواهید شد که همه Index ها را جست و جو کنید تا داده مورد نظرتون را پیدا کنید. اما در جدول درهم‌ساز شما key یا index را توسط هش کردن مقدار یا value تشخیص می دید. بعد این مقدار را در این index از لیست قرار می دید. به این معنی که key از روی مقدار value تشخیص داده می‌شه و هر زمانی شما نیاز به بررسی اینکه آیا value موجود هست یا نه داشته باشید شما فقط مقدار value را hash‌ می‌کنید و بعد بر اساس key جست وجو می‌کنید که توی تصویر زیر نشون داده شده. این خیلی سریعتر هست و مرتبه الگوریتم نیز O(1) است که خب خیلی سریع‌تر از O(n) است.

نحوه عملکرد جدول درهم سازی یا hash table

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

فراموش نکنید که شما این کار را برای هر پسوردی که توسط کاربر وارد میشه باید انجام بدید. چطور میشه هزینه این کار را کاهش داد؟

بلوم فیلتر میتونه به ما کمک کنه. اما چطوری؟ بریم ببینیم بلوم فیلتر چطور کار می‌کنه.

طبق تعریف بلوم فیلتر می‌تونه یک مقدار را در حالت‌های “احتمال وجود آن در مجموعه است” یا “قطعا در آن مجموعه نیست” بررسی کند. تفاوت ظریف بین احتمالا و قطعا نه در اینجا بسیار مهم است.

به خاطر این جمله “احتمالا در مجموعه است“ می‌باشد که چرا این ساختار داده‌ها احتمالاتی نامیده می‌شوند. و با تعریف هایی که شده بدین معنی است که مثبت کاذب امکان پذیر هست اما منفی کاذب غیر ممکن است. عجله نکنید، در ادامه با مثال عملی می‌بینیم که دقیقا اینا یعنی چی. بلوم فیلتر اساسا شامل یک بردار بیتی یا لیست بیتی(یک لیست شامل مقدار بیت فقط ۰ یا ۱) به طول m، با مقدار اولیه ۰ مانند شکل زیر است:

مقداردهی لیست بیتی بلوم فیلتر

برای اضافه کردن یک آیتم به بلوم فیلتر، ما اول آیتم مون را به k تابع هش مختلف می دهیم هر تابع هش یک عدد به ما می‌دهد که ما متناظر با هر عدد توی آرایه‌مون مقدار اون خونه را برابر ۱ قرار می‌دهیم. همونطور که می‌تونید ببینید در جدول هش ما از یک تابع هش تکی استفاده کردیم و به عنوان نتیجه فقط یک index تکی به عنوان خروجی داشتیم.

اما در این مثال از بلوم فیلتر ما از تابع هش چندگانه (k تعداد توابع هش) استفاده می‌کنیم که خروجی چندگانه نیز خواهیم داشت.

خروجی تابع هش چندگانه برای کلمه geeks

همونطور که در تصویر بالا مشخص هست برای ورودی آیتم geeks ما سه تابع هش داریم که هر تابع یک مقدار به ما بر می‌گردونه که در این مثال مقدار ۱ ,۴,۷ هست یعنی خونه شماره ۱ , ۴ و ۷ را از صفر به ۱ تغییر میدهیم که ما آن ها را مشخص کردیم.

خروجی تابع هش چندگانه برای کلمه nerd

به همین ترتیب برای ورودی دیگری به نام nerd توابع هش به ما ۳ خروجی ۳,۴,۵ را می‌دهد.

شاید متوجه شده باشید که index شماره ۴ یا همون خونه شماره ۴ قبلا با کلمه geeks علامت گذاری شده(از صفر به ۱ تغییر داده شده). خب تا اینجا با بردار بیتی خودمان را با دو وردی پر کرده ایم. و حالا می تونیم بررسی کنیم که آیا مقدار مورد نظر ما داخل آن وجود دارد یا نه. اما چطوری؟ خیلی ساده هست. ما یک جدول هش ایجاد کردیم. ورودی مورد نظرمون که می‌خواهیم جست و جو کنیم را با سه تا تابع هش می‌کنیم و نتیجه سه تا تابع که سه تا عدد است را بررسی می کنیم که کدام index‌ها یا ساده‌تر کدوم مکان‌های آرایه میشه. مثلا اگر بخواهیم ببینیم کلمه nerd وجود دارد یا نه کافیه ابتدا این کلمه را بدیم به سه تابع هش و خروجی که سه تا عدد است را داخل آرایه تک بعدی بررسی کنیم. که خب هر سه تا خونه مقدارش برابر ۱ است یعنی این عنصر احتمالا وجود دارد.

جستجوی کلمه cat در بلوم فیلتر

در ادامه بزارید جست و جو برای کلمه cat را انجام دهیم که خروجی سه تابع هش این کلمه برابر ۱ ,۳,۷ هست که می‌تونیم ببینیم که مقدار هر سه تا خونه ۱,۳,۷ برابر ۱ هست که این به این معنی است که ما می‌توانیم بگوییم “احتمالا کمله cat در لیست وارد شده است”. اما وارد نشده است!!

پس این خطا از کجا است؟ در واقع هیچ خطایی رخ نداده. به این اتفاق میگن خطای مثبت کاذب که در ادامه نحوه جلوگیری از این اتفاق را هم توضیح می‌دهم. بلوم فیلتر به ما می گوید که این نشان می دهد که شاید کلمه cat قبلا وارد شده بوده است زیرا همه خانه‌های index مربوط به خروجی سه تابع هش برای کلمه cat برابر ۱ است(حتی با داده های مختلف دیگه). خب این کجاش مفیده و بدرد می‌خوره؟

بیاید در نظر بگیریم اگر خروجی توابع هش برای کلمه cat به جای ۱,۳,۷برابر ۱,۶,۷ می‌بود، در این صورت چی می‌شد؟ ما می تونستیم ببینیم که Index مربوط به ۶ برابر ۰ است. که به این معنی هست که با هیچ ورودی، قبلا این خونه علامت‌گذاری(تغییر از صفر به ۱) نشده. که به این معنی است که کلمه cat هیچ وقت وارد نشده است. این نحوه کار بلوم فیلتر است که می تواند به ما بگوید “دقیقا”داده در لیست وجود ندارد. خب به طور خلاصه:

  • اگر ما برای یک مقدار جست و جو کردیم و نتیجه هر هش‌ای را پیدا کردیم که مقدار آن برابر ۰ بود ما می‌توانیم با اطمینان بگوییم که در لیست وجود ندارد.
  • اگر همه indexهای خروجی توابع هش برابر ۱ باشد آنگاه ممکن است مقدار جست و جو شده وجود داشته باشد.

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

خب بزارید برگردیم به مثال پسورد که ابتدا در موردش صحبت کردیم. اگر ما بررسی پسوردهای ضعیف را با این نوع از بلوم فیلتر پیاده سازی کنیم، ابتدا، ما بلوم فیلترمان را با یک لیست از پسوردهای ضعیف که به ما یک بردار بیتی می‌دهد که برخی از indexهای آن با ۱مقدار دهی شده و مابقی با ۰ مقدار دهی شده است، ایجاد می‌کنیم. از آنجایی که اندازه بلوم فیلتر نمی تواند خیلی بزرگ باشد و یک اندازه ثابت دارد، این می تواند به راحتی در حافظه ذخیره شود حتی در صورت نیاز می‌تواند در سمت client ذخیره شود.

به همین دلیل است که بلوم فیلتر بسیار space-efficient است. در حالی که یک جدول هش نیاز به داشتن اندازه دلخواه بر اساس داده‌های ورودی دارد، بلوم فیلترها می توانند با اندازه ثابت به خوبی کار کنند و این یعنی عملیات جستجو خیلی سریع‌تر و ساده‌تر خواهد بود.

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

همچنین در نظر بگیرید که اگر نرخ خطای مثبت بلوم فیلتر شما ۱% باشد به این معنی است که در میان هزینه های مراجعه به سرور یا دیسک، تنها ۱% از کوئری‌های ما با خطا مواجه خواهد شد و ۹۹درصد دیگر سمت سرور نخواهند رفت. بد نیست نه؟

عملیات‌های بلوم فیلتر

یک بلوم فیلتر ساده از دو عملیات test (یا بررسی) و add (یا اضافه کردن) پشتیبانی می‌کند. Test برای چک کردن اینکه آیا یک عنصر در مجموعه وجود دارد یا نه و عملیات add هم برای اضافه کردن یک عنصر به مجموعه.

به نظرتون امکان حذف کردن یک ایتم از بلوم فیلتر وجود دارد؟ قبل از ادامه دادن یکم روی جواب تون فکر کنید.

قبل از جواب دادن به سوال بالا بیاید یک مثال بصورت عملی بررسی کنیم. فرض کنید در بردار بیتی دو کلمه geeks و nerd را اضافه کردیم:

حالا ما میخواهیم عنصر geeks را از بلوم فیلتر حذف کنیم. بنابراین اگر ما ۱,۴,۷ را از بردار بیتی حذف کنیم که قبلا توسط geeks علامت گذاری شده بودند، و ما مقدارشونا به ۰ تغییر بدیم چه اتفاقی می افتد؟

به سادگی می‌تونید ببینید که اگر ما در ادامه کلمه nerd را جست و جو کنیم همانطور که می‌بینید Index شماره ۴ برابر ۰ هست و این به ما می‌گوید که دقیقا nerd در لیست وجود ندارد در حالی که اشتباه است. این بدین معنی است که امکان حذف در بلوم فیلتر وجود ندارد.

پس راه حل چیه؟ در واقع توی بلوم فیلتر ساده چنین امکان وجود نداره. اما اگر واقعا به چنین چیزی نیاز دارید می تونید از یک نسخه تغییر یافته بلوم فیلتر به نام Counting bloom filter استفاده کنید. ایده ساده است. به جای مرتب سازی یک بیت تکی از مقدارها، ما یک مقدار integer را ذخیره می کنیم و بردار بیتی ما بردار integer خواهد بود. قابلیت حذف کردن باعث افزایش اندازه و هزینه ما خواهد شد. در این حالت به جای علامت گذاری یک مقدار بیت با ۱ هنگام ورود داده، ما مقدار integer را به مقدار ۱ افزایش می دهیم و اگر داده جدیدی وارد بلوم فیلتر کردیم یک واحد دیگه افزایش می‌دهیم مثلا مقدار خانه اگر ۱ بود با افزایش مجدد به ۲ تغییر داده می‌شود و در هنگام حذف کلمه یک واحد از خانه‌هایی خروجی توابع هش کم می‌کنیم. برای بررسی اینکه یک عنصر موجود هست یا نه کافی هست که عنصر را هش کنیم و خانه هایی را که بررسی میکنیم مقدارشون بیشتر از ۰ باشه. که قابلیت حذف را ما فعلا نیاز نداریم و بیشتر از این هم بهش نمی‌پردازیم.


اندازه Bloom filter و تعداد توابع Hash

شاید به این فکر کرده باشید که اگر اندازه بلوم فیلتر کوچک در نظر گرفته بشه ممکنه سریع همه خونه های آن برابر ۱ بشه و بعد از این هر کلمه‌ای چه در لیست باشه چه نباشه را بررسی کنیم جواب مثبت برگردانده بشه. بنابراین اندازه بلوم فیلتر خیلی مهم است. در اینجا اگر اندازه بلوم فیلتر بزرگ انتخاب شود ما جواب های مثبت کاذب کمتری داریم و اگر اندازه کوچک باشد ما جواب های مثبت کاذب بیشتری خواهیم داشت. اینجا یک موضوع جدید خواهیم داشت با عنوان نرخ خطای مثبت کاذب. پارامتر مهم دیگر این است که چه تعداد تابع هش نیاز داریم؟

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

طبق مقاله ارائه شده که نتیجه آن در شکل زیر نشان داده شده می‌توانید ببینید که اندازه بلوم فیلتر و تعداد توابع هش به صورت مناسب چقدر هست:

در نمودار بالا با افزایش تعداد تابع هش یعنی k، نرخ خطا که با p نشان داده شده کاهش پیدا می‌کند. در واقع ما می‌توانیم نرخ خطای کاذب مثبت P را بر اساس اندازه بلوم فیلتر که با m و تعداد تابع هش که با k نشان می‌دهیم، اگر تعداد عنصر ورودی ما(مثلا تعداد پسوردها) برابر n باشد، می‌توانیم بصورت زیر محاسبه کنیم:

محاسبه احتمال خطای کاذب برای بلوم فیلتر

اگر به ریاضیات علاقه ای ندارید نگران نباشید 🙂 در واقع ما فقط نیاز داریم که مقدار m و k را مشخص کنیم. اگر نرخ خطای مثبت کاذب ما برابر p باشد و تعداد داده‌های ورودی برابر n باشد ما می تونیم از فرمول های زیر برای محاسبه پارامترهامون استفاده کنیم:

محاسبه اندازه بلوم فیلتر m و تعداد توابع هش مورد نیاز k

نکته دیگه که باید توجه کنید این هست که هدف استفاده از بلوم فیلتر جست و جوی سریعتر هست، ما نمی توانیم از توابع هش با سرعت پایین استفاده کنیم. بنابراین توابع هش رمزنگاری Sha-1 و MD5 انتخاب خوبی برای بلوم فیلترها نیستند. توابع هش سریعتری پیاده سازی شدن که می‌توانید ازشون استفاده کنید. مثلا murmur fnv HashMix انتخاب های بهتری هستند.

کاربردها

بلوم فیلتر برای بررسی عضو داخل یک مجموعه است. مثال ساده بلوم فیلتر برای کاهش هزینه مراجعه به دیسک یا شبکه برای کلیدهای ناموجود است. همونطور که ما می‌توانیم ببینیم بلوم فیلترها می توانند یک کلید را در O(k) جست و جو کنند که k تعداد تابع هش است. این بسیار سریعتر هست که کلید ناموجود را جست و جو کنیم. اگر عنصر در بلوم فیلتر نباشد پس ما نیازی به جست و جوی پر هزینه نداریم. از طرف دیگه اگر عنصر در بلوم فیلتر موجود باشد ما جست و جو را انجام می‌دهیم و می‌توانیم انتظار داشته باشیم که در برخی موارد ما نرخ خطای مثبت کاذب(false positive rate) داشته باشیم. و عنصر موجود نباشد. در ادامه برخی مثال‌های استفاده از بلوم فیلتر را معرفی می‌کنیم.

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

خیلی خلاصه شبکه های تحمل پذیر تاخیر یا DTN شبکه هایی هستند که بر خلاف شبکه های سنتی که ارتباط end-to-end اگر با تاخیر مواجه بشه ارتباط را خاتمه میده می تونن تاخیر را تا حدود زیادی تحمل کنند. در صورت نیاز به مطالعه بیشتر اینجا را می‌توانید مطالعه کنید. در این شبکه ها دو تا گره(node) که همون دستگاه‌ها هستند حالا می‌تواند یک ماشین مجهز به wifi توی بزرگراه هوشمند باشه یا اینکه یک ماهواره در مدار زمین باشه وقتی با همدیگه مواجه می‌شوند باید بسته‌هایی که در بافر خودشون دارند را با یکدیگر مبادله کنند. یک راه ساده انتقال کل بافر هر نود برای نود دیگه است که خب سربار خیلی زیادی داره و از طرف دیگه ممکنه یک نود برخی از پکت‌ها را قبلا توسط بقیه نودها دریافت کرده باشه مجددا دریافت کنه و باعث سربار اضافی بشه. برای کاهش سربار و جلوگیری از ارسال تکراری پکت ها استفاده از بلوم فیلتر یک راهکار خوبی است. به این صورت که ابتدا هر نود یک بردار بیتی(بلوم فیلتر) از بسته هایی که دارد ایجاد می‌کند که حجم بسیار پایینی دارد و آن را برای نود دیگه ارسال می‌کند. و نود قبل از ارسال بسته‌ها چک ‌می‌کند که آیا داخل بلوم فیلتر دریافتی وجود دارند یا نه. اگر بلوم فیلتر جواب منفی داد یعنی بسته‌ها در نود دیگر وجود ندارند و باید ارسال بشوند و اما اگر بلوم فیلتر اعلام کنه که بسته موجود است از ارسال آن جلوگیری میشه. که این می‌تواند باعث کاهش سربار تبادلات شود.

مثال های استفاده از بلوم فیلتر:

  • برای هشدار به کاربران در مورد ضعیف بودن پسورد که در بالا توضیح داده شد.
  • برای جلوگیری از دسترسی کاربران به سایت های مخرب
  • برای بررسی اینکه چه کاربرانی قبلا از سایت شما بازدید کردند بر اساس IP هاشون.
  • برای بررسی اینکه چه تعداد از کاربران محتوای سایت شما را خوانده اند

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

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

در پست های آینده سعی می‌کنم یک مثال کاربردی را بصورت کدنویسی پیاده سازی کنم و شرح بدم.

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

منابع

https://en.wikipedia.org/wiki/Bloom_filter

https://hackernoon.com/probabilistic-data-structures-bloom-filter-5374112a7832

https://www.geeksforgeeks.org/bloom-filters-introduction-and-python-implementation/

https://www.semantics3.com/blog/use-the-bloom-filter-luke-b59fd0839fc4/

https://medium.com/better-programming/probabilistic-data-structures-bloom-filter-5374112a7832

نوشته موجودی عجیب! به نام Bloom Filter در برنامه نویسی اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

آشنایی با Clean Architecture : نگاهی به معماری سنتی سه لایه

قسمت اول : مقدمات
قسمت دوم : مبانی معماری
قسمت سوم : نگاهی به معماری سنتی سه لایه (شما در حال خواندن این مقاله هستید)
قسمت چهارم : اجزای معماری Clean Architecture
قسمت پنجم : پیاده سازی بر اساس سرویس ها
قسمت ششم : پیاده سازی بر اساس UseCase ها قسمت هفتم : آشنایی با CQRS


اگر مدت کوتاهی از کار حرفه ای شما گذشته باشد حتما با معماری سه لایه سنتی آشنا هستید.
در این معماری لایه سطح پایین، دسترسی به دیتابیس شماست.
در این لایه صرفا ذخیره سازی یا خواندن اطلاعات از یک نگهدارنده مثل فایل یا دیتابیس انجام میشود. به این لایه data یا persistence هم میگویند.
لایه بعدی بیزنس لاجیک یا application layer است.
بیزنس لاجیک چگونگی رفتار با داده ها را تعیین میکند. اینکه داده های دریافتی از کاربر چگونه تغییر کنند یا داده های دریافتی از دیتابیس چطور تغییر کند.
لایه بیرونی هم پرزنتیشن است که مسئول نمایش داده های متناسب و یا دریافت اطلاعات از سمت کاربر است.
نکته مهم در تعیین لایه مرکزی هست.
در حالت سه لایه معمولا کل ساختار وابسته به لایه data است و این میتواند نقص محسوب شود.
برای اینکه مکانیزم کاری این سه لایه را درک کنید یک مثال روزمره را با هم بررسی میکنیم.

فرض کنید که ساختار سه لایه نرم افزار را در خانه خود بخواهید پیاده کنید.

شما در بخش پذیرایی (presentation layer) نشسته اید ، سفارش غذای خود را به آشپزخانه که در اینجا میز آماده سازی نام دارد، میگویید و غذا را از همانجا دریافت میکنید.(سفارش شما یک درخواست«request» است و دریافت سفارش یک پاسخ«response» نام دارد.)

مسئول میزآماده سازی (application layer) وظیفه دارد بر اساس خواسته شما غذا را آماده سازی کند و از منبع یخچال(data layer) استفاده کند، همچنین میتواند یخچال را بر اساس مواد غذایی جدید پر کند. مثلا لوازم کیک را از یخچال خارج کند کیک را بسازد و دوباره در یخچال قرار دهد.

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

لایه های معماری سه لایه

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

لایه اپلیکیشن در حقیقت لایه عملیات منطقی ما (یا همان logic یا business) است.

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

نحوه تعاملِ این سه لایه بر اساس توضیحات خانه ای که توضیح دادیم ساده و تقریبا «تقسیم وظایف شده» است.

در معماری clean لایه مرکزی انتیتی ها هستند یعنی جایی که قلب نرم افزار است و روی طراحی آن فکر شده است. همچنین پرزنتیشن و دیتا (persistence) با اینکه در ساختار لایه ای وجود دارند ولی جزئیات محسوب میشوند. این موضوع را در مقالات بعدی توضیح خواهم داد.

فقط به یاد داشته باشید که در Clean Architecture تمرکز اصلی روی مدل های دامین (انتیتی ها یا همان کلاس های مدل) و لایه اپلیکیشن(منطق رفتارهای مختلف در برنامه) است.

معمولا این سه لایه را با همین نام ها یا نام های مشابه نامگذاری میکنند یعنی اگر دردیاگرامی اسم متفاوت دیدید فکر نکنید سه لایه جدید هستند!

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

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

یک پروژه ساده را با معماری سه لایه سنتی پیاده میکنیم.

این پیاده سازی روش های مختلفی دارد. فعلا در مورد مقدمات این پروژه کمی صحبت میکنیم.

فرض کنید به کمک دات نت میخواهیم api هایی را به عنوان مثال پیاده سازی کنیم.

طرح مسئله میکنیم.

عنوان : apiهای مربوط به ثبت و خواندن خبر

توضیح : میخواهیم یک جدول در دیتابیس sql داشته باشیم به نام post و سه api داشته باشیم. که دو تای آن مربوط به خواندن خبر (یکی تک خبر و یکی همه خبرها) و یکی آن مربوط به ثبت خبر باشد.از EntityFramework به عنوان ORM استفاده خواهیم کرد و از این به بعد به آن EF میگوییم.

دامین مدل (انتیتیها) : Post

فرمت api ها :

GET : api/posts
Input:-
Output:list of PostVm
GET : api/posts/:id
Input:id
Output:PostVm
POST: api/posts
Input: AddPostVm
Output:-

ممکن است تمایل داشته باشید از ریپازیتوری پترن هم استفاده کنیم اما آیا وقتی EF داریم لازم است unitofwork و repository پیاده سازی شود؟

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

  • بطور کلی EF ذاتا کد شما را نسبت به تغییرات دیتابیس ایزوله میکند.
    این موضوع را میتوان از پشتیبانی EF از چندین نوع دیتابیس فهمید.
    شما هر وقت بخواهید با کمترین تغییر میتوانید کانکشن خود را از SQL Server به دیتابیس دیگر مثل MySql تعویض کنید.. فقط کافیست provider خود را تغییر دهید.
  • آبجکت DbContext در EF نقش unit of work را بازی میکند.
  • آبجکت DbSet در EF نقش Repository را بازی میکند.
  • در EF Core ما provider برای ذخیره سازی in-memory داریم که یعنی امکان unit test هم فراهم است.

در مورد این موضوع افراد مختلفی نظر داده اند.

  • جیمی بوگارت خالق MediatR و Automapper میگوید وقتی از ORM استفاده میکنید ایجاد یک لایه ابسترکشن دیگر چندان مزیتی نخواهد داشت. البته استفاده مستقیم از ORM در لایه UI را توصیه نمی کند.
  • استیو اسمیت نویسنده داکیومنت ماکروسافت در مورد معماری وب اپلیکیشن های مدرن و همچنین مدرس بهترین دوره های pluralsight عقیده داره که شما به ریپازیتوری نیازی ندارید اما نمیشه از مزایایی که پیاده سازی ریپازیتوری داره چشم پوشی کرد.
نویسنده این کتاب اعتقاد دارد که پیاده سازی پترن ریپازیتوری با حضور EF لازم نیست.
  • جان اسمیت نویسنده کتاب EF Core in action هم عقیده دارد استفاده از Repository/UnitOfWork زمانی که از EF Core استفاده میکنید لزومی ندارد.

وقتی سه متخصص در یک موضوع نظر یکسان داشته باشند شما چه کار میکنید؟
نکته اینجاست که باید فکر کرد که کلا فلسفه پترن ها حل کردن یک مساله است.

آیا در پروژه ای که در حال انجام آن هستید Repository/unitofwork مشکلی را حل میکند؟
در ادامه پروژه خود را بدون این پترن ها و فقط با کمک EF و معماری سه لایه پیاده میکنیم.

در انجام مراحل با اینکه جزئیات توضیح داده شده است اما فرض این است که به EF و web api و Sql serve آشنایی دارید.

به کمک ویژوال استودیو ابتدا لایه data را میسازیم تا مدل یا مدل های خود رابسازیم.

انتخاب نوع پروژه
تعیین نام پروژه و نام سولوشن
ایجاد شدن پروژه با یک کلاس به نام class1

فایل class1 را به Post تغییر میدهیم.

به کمک دستور زیر EF را نصب میکنیم،

dotnet add  package Microsoft.EntityFrameworkCore

پنجره Console package manager را در ویژوال استودیو باز میکنیم.

خطایی که میبینید به این دلیل است که درون فولدر پروژه مربوطه نیستیم و باید محل فایل csproj را پیدا کنیم.

با دستورات کنسول داخل فولدر پروژه قرار میگیریم.

دستور زیر را دوباره تکرار میکنیم

dotnet add  package Microsoft.EntityFrameworkCore

اینبار چون در فولدر پروژه مربوطه هستیم نصب انجام میشود و میتوان از طریق فایل Post.Data.csproj و یا بخش Nuget در پنجره سولوشن به وجود این لایبرری مطمئن شد.

چون قرار است از قSql serve استفاده کنیم باید دو کتابخانه زیر را نصب کنیم. مطمئن باشید که نسخه ای از sql server (مثلا express) روی سیستم شما نصب باشد که بتوانیم از طریق EF به آن متصل شویم.

dotnet add package  Microsoft.EntityFrameworkCore.SqlServer
dotnet add package  Microsoft.EntityFrameworkCore.Tools.DotNet

بعد از نصب در پنجره سولوشن و فایل csproj کتابخانه ها را خواهید دید

اگر علامت زرد رنگ مثل تصویر فوق دیده شد کافیست پروژه را یکبار unload و سپس reload کنید (با رایت کلیک روی Post.Data آیتم های گفته شده را خواهید دید)

کلاسی به نام PostContext میسازیم که از DbContext ارث بری کند. رفرنس Microsoft.EntityFrameworkCore را اضافه میکنیم.

وظیفه این کلاس برقراری ارتباط با دیتابیس است.
فعلا این کلاس را رها میکنیم و مدل Post در دیتابیس را تکمیل میکنیم.

حالا باید کلاس post خود را برای دیتابیس قابل فهم کنیم. یعنی بگویم فلان پراپرتی کلید اصلی آن است یا فلان پراپرتی required است و تعداد کاراکتر آن فلان قدر است.

از روش Data Annotation یا Fluent Api میتوانیم استفاده کنیم.

ترجیح، استفاده از Fluent Api است چون Entity را با منطق دیتابیس درگیر نمیکند.

در فایل Post.cs کلاس زیر را اضافه میکنیم

و در context به این کلاس اشاره میکنیم.

حالا با تعریف DbSet متناظر با entity تعریف شده و اضافه کردن کانکشن استرینگ مراحل مقدماتی آماده سازی دیتابیس را تکمیل میکنیم:

میتوانید کانکشن استرینگ را در appsetting تعریف کنید.

تا اینجای کار لایه دیتا را ایجاد کردیم که حاوی entity ها (که در اینجا یکی است) است.

دقت کنید استفاده از Fluent api این امکان را میدهد که بتوانیم این لایه را هم دو قسمت کنیم. یکی domain models یا همان entity ها که فقط شامل کلاس post.cs است (و کلاس های دیگر که مرتبط با بخش domain model هستند و بعدا اضافه میشوند) و دیگری لایه data که کانتکست در آن وجود دارد.
با اینکار انتظار دارم ذهن شما با معماری clean architecture که در مقالات بعدی توضیح خواهم داد آشنا شود.

یک پروژه دیگر به نام Entities درست میکنیم.

به اسم و مسیر ها دقت کنید که در کنار پروژه قبلی ساخته شود.

آدرس لوکیشن در داخل فولدر Post.Data میخواهد پروژه ما را بسازد. به فولدرها نگاه میکنیم.

موقع ساختن پروژه در ابتدای کار، به دلیل بی دقتی، اسم سولوشن Post.Data شده و داخل این فولدر دو پروژه ما سقرار خواهد گرفت.

نام فولدر اصلی ما یا همان سولوشن ما، Post.Data است. همچنین فایل اجرای سولوشن اشتباها Post.Data.Sln است که آنرا هم اصلاح میکنیم.

ویژوال استودیو را می‌بندیم و فولدر حاوی این دو پروژه را به PostThreeLayer تغییر میدهیم. الان باید دو فولدر PostThreeLayer تو در تو داشته باشید.

حالا فایل های داخل فولدر دوم را به همین فولدر منتقل کنید و فولدر را پاک کنید.

حالا اسم سولوشن را از Post.Data.sln به PostThreeLayer.sln تغییر دهید و سپس روی فایل sln کلیک کنید تا پروژه اجرا شود.

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

کلاس Post.cs را از لایه قبل به اینجا منتقل کنید.

در لایه قبل کلاس PostMap.cs به شکل فایل تبدیل کنید ، چون عملیات مربوط به دیتابیس است نباید به لایه Entities منتقل شود.

چون ما معماری سه لایه را پیاده میکنیم و در این معماری چیزی به نام Enitites نداریم بهتر است یک فولدر درست کنیم و این دو پروژه را با هم لایه Data بنامیم.

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

کلاس PostMap در پروژه Post.Data نمیتواند کلاس Post در پروژه Post.Entities را ببیند.

قبل از اصلاحِ این موضوع، نحوه نامگذاری پروژه ها را اصلاح میکنیم. حضور Post هم در namespace و هم در نام کلاس ممکن است مشکل ساز شود.روی پروژه کلیک کرده و F2 را فشار میدهیم تا rename کنیم. همچنین در تمامی کلاس ها namespace را به اسم جدید تغییر میدهیم.

همچنین بهتر است کلاس PostContext به Context تغییر نام دهد.( چون کانتکست مربوط به یک تیبل Post نیست و مربوط به همه تیبل های آینده هم هست)

حتما فولدرهای پروژه در explorer ویندوز را چک کنید و تغییر نام دهید، در انتها فایل sln را توسط یک ادیتور باز کنید و بررسی کنید مسیرها روی نام های جدید تنظیم شده باشد.

اسم فولدر Data در سولوشن هم اصلاح کنیم و به Persistence تغییر دهیم. بهتر است نام فولدر و پروژه ها شبیه به هم نباشد.

نام ها اصلاح شد. برای اینکه پروژه Data بتواند کلاس های پروژه Entities را ببیند باید رفرنس بدهیم.

روی Post رایت کلیک کنید

اگر گزینه آخر را می‌بینید که روی آن کلیک کنید، اگر نمیبینید در پروژه Data روی Dependencies رایت کلیک کنید و Add references را انتخاب کرده و از بخش Solution تیک مربوط به پروژه Entities را بزنید.

با اضافه شدن رفرنس Entities به بالای کلاس، دسترسی به Post برای کلاس PostMap ممکن خواهد شد.

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

قدم اول نصب Microsoft.EntityFrameworkCore.Design روی پروژه Data است.

Install-Package  Microsoft.EntityFrameworkCore.Design

مطمئن شوید که در پروژه Data هستید و سپس دستور فوق را اجرا کنید

حالا دستور زیر را بنویسید

احتمالا به مشکل برخورد خواهید کرد و فولدر مایگریشن ایجاد نخواهد شد، مگر آنکه یک پروژه با startup داشته باشد.
دستورات EF Core با پروژه های Startup بدون مشکل کار میکنند و با class library مشکل دارد. چون بطور معمول روی تمپلیت اصلی دات نت برای web api یا MVC کانتکستی که ایجاد میشود توسط دپندنسی اینجکشن است که در زمان runtime اتفاق می افتد.
اما میتوانید با ارث بری از IDesignTimeDbContextFactory در لایبرری خود اینکار را انجام دهید. در این حالت زمانی که دستورات کامندی EF مثل مایگریشن را مینویسید پیاده سازی شما دیده میشود و کانتکست شما ساخته میشود.

دقت کنید که متغیر connectionString که در Context پیش از این تعریف شده بود را استاتیک کردیم که این کلاس به آن دسترسی داشته باشد.

حالا دستور مایگریشن را با اشاره به پروژه ای که قرار است برای آن مایگریشن اجرا شود مینویسیم:

فولدر مایگریشن در پروژه Data ساخته شد که حاوی دستوراتی است که باعث اعمال مدل تعریف شده بر روی دیتابیس میشود.

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

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

حالا لایه پرزنتیشن را ایجاد میکنیم. چون پروژه ما قرار است web api باشد یک پروژه به سولوشن اضافه میکنیم.

اسم پروژه را Presentation میگذاریم.

پروژه جدید به شکل زیر است و یک کنترلر تستی دارد.

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

دو ویو مدل PostVm و AddPostVm هم بر اساس api خواسته شده ایجاد میکنیم.

حالا فقط لایه بیزنس لاجیک یا لایه اپلیکیشن باقی مانده. یک کلاس لایبرری جدید درست میکنیم به نام Application :

چون قرار نیست repository/unit of work درست کنیم کارمان راحت است. اگر قرار بود ریپازیتوری و uow داشته باشیم باید اینترفیس های آن را در لایه اپلیکیشن طراحی میکردیم و لایه data باید این اینترفیس ها را پیاده میکرد. با اینکار اگر در آینده لایه دیتا تغییر میکرد اتفاقی برای لایه های دیگر نمی افتاد و لایه دیتای جدید باز هم باید اینترفیس های موجود در لایه اپلیکیشن را پیاده سازی میکرد.

فقط یک سرویس مرتبط با api ها را میسازیم. با یک سرویس به نام PostService میتوانیم سه api را پیاده سازی کنیم.

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

به سراغ api میرویم. لایه پرزنتیشن باید لایه اپلیکیشن را ببیند تا بتواند با اینجکت کردن اینترفیس ها به متدهای این لایه دسترسی پیدا کند.

پس در لایه پرزنتیشن add reference میکنیم و Application را اضافه میکنیم.

به کانستراکتور اینترفیسی که میخواهیم را اینجکت میکنیم

در فایل startup این اینجکشن را تعریف میکنیم

حالا api مربوط به لیست پست ها را پیاده سازی میکنیم

هنوز متد GetPosts که نوشتیم در اینترفیس IPostService و سرویس PostService وجود ندارد.

همچنین هنوز متد PostDto که خروجی سرویس است را پیاده نکردیم. PostDto میتواند همان Entity اصلی یعنی Post باشد. این بستگی به شما و متد شما دارد که چه سرویسی ارائه میدهد. معمولا در متدهای ساده میتوان از همان Entity استفاده کرد

متد Wrap خروجی Dto را به ویومدل مناسب این api تبدیل میکند.

ممکن است این سرویس در api های دیگر هم استفاده شود و هر api ویومدل خودش را داشته باشد، پس نیاز داریم که خروجی سرویس را به آنچه api میخواهد تبدیل کنیم. البته کتابخانه هایی برای اینکار وجود دارد که در این مقاله فرصت بررسی آنها یست.

با کلیک روی علامت حباب زرد رنگ میگوییم که برایمان متد GetPosts را در اینترفیس generate کند.

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

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

برای پیاده سازی این متد نیاز به context داریم. لایه application باید به لایه data دسترسی داشته باشد.

کانتکست را اینجکت کردیم ولی یک resolver نیاز داریم که در لایه اپلیکیشن بتواند دپندنسی اینجکشن را هندل کند. از کتابخانه autofac استفاده میکنیم ولی کتابخانه های مشابه هم قابل استفاده هستند.(از اکستنشن دپندنسی اینجکشن مایکروسافت هم میتوانید استفاده کنید)

به کمک nuget در پروژه اپلکیشن کتابخانه autofac را نصب میکنیم و فایل ماژولی برای این لایه درست میکنیم.

باید به کمک RegisterType سرویس PostService و Context را برای constructor ها قابل فهم کنیم.

در پروژه Presentation هم باید در کلاس startup از ماژول applicationModule استفاده کنیم.

باید کتابخانه autofac.Extension.DependencyInjection را در پروژه presentation نصب کنیم.

خطوط زیر را به startup اضافه میکنیم)بر اساس راهنمای autofac)

حالا در api اصلاحات زیر را انجام میدهیم.

رپر(wrapper) را در ویومدل پیاده سازی کردیم که کپسوله باشد.

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

میتوانیم یک BaseController به عنوان والد کنترلر ها بسازیم و از آن ارث بری کنیم و متدی برای تولید فرمت خروجی در آن قرار دهیم و به جای اینکه هر دفعه اینجا بنویسیم Ok ، یکبار در یک متد والد اینکار را کنیم و در اکشن ها هر بار آن متد را صدا بزنیم.

فایل PostVm.cs به شکل زیر است

متدهای دیگر هم به همین شکل پیاده میکنیم.

در این مثال exception ها هندل نشده، فرمت خروجی api ها و pagination نداریم، همچنین ریسورسی برای پیام های خروجی نداریم و به منظور وضوح در انتقال مفاهیم برخی ریفکتورها چشم پوشی شده است.
بطور کلی برخی مدل ها و ویومدل ها و تکرار برخی موضوعات صرفا به جهت جنبه آموزشی دارند.

پروژه انجام شده را میتوانید در این گیت ببینید.

در مقاله بعدی به Clean Architecture میپردازیم.

نوشته آشنایی با Clean Architecture : نگاهی به معماری سنتی سه لایه اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

داستان تولد یک پیام رسان

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

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

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

۱٫بهبود های مداوم.
تعداد کاربرانتان قدم به قدم رشد میکند در نتیجه اگر در مراحل ابتدایی خطاها و مشکلات زیادی دارید پر واضح است که تعداد ریزش شما هم کمتر خواهد بود. به علاوه اینکه اون بخش از کاربرانی که در این شرایط با شما میمانند معمولا کاربر جَلد شما میشوند و احتمالا با بهبود شرایط دیگر اپ شما را ترک نخواهند کرد.

۲٫ ایجاد تغییرات بنیادی.
تعداد کاربر کمتر به شما این فرصت را میدهد که گاهی تغییرات زیرساختی بدهید. مثلا بعد از اینکه تعداد کاربران شما از پنج هزار نفر فراتر رفت متوجه میشوید که ساختار کش کردن و نگهداری عکس های کاربران اشتباه است و مجبور هستید یک جدول جدید با ساختار جدید ایجاد کنید. طبیعی است که تغییرات زیرساختی گاهی با حجم بالای دیتا یا بسیار سخت است یا عملا غیر قابل انجام است.

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

۴٫ فیچر بر اساس نیاز واقعی کاربرانتان
رشد طبیعی این امکان را به شما میدهد که به مرور به نیازهای واقعی کاربرانتان پی ببرید. این نیازها معمولا از قبل به طور کامل قابل پیش بینی نیست. مثلا هر فیچری که تلگرام دارد الزاما بدرد کاربران شما هم نمیخورد. خیلی وقتها کاربران هم با تلگرام کار میکنند هم با پیام رسان شما. اما معمولا زمان، شرایط و نوع استفاده از پیام رسان داخلی ممکن است متفاوت باشد. بطور مثال عده ای فقط وقتی قرار است موزیک یا ویدئو دانلود کنند از پیام رسات داخلی استفاده کنند چون سرعت بالاتر و هزینه کمتری دارد یا مثلا عده ای فقط در محیط کار از پیام رسان شما استفاده میکنند یا مثلا برخی پدر و مادرها فرزندانشان را از نصب تلگرام نهی میکنند اما با نصب پیام رسان داخلی مشکلی ندارند در نتیجه باید پیام رسانتان برای افراد زیر ۲۰ سال جذاب باشد و یکسری فیچر مختص آنها داشته باشید که حتی بتوانند پیش بقیه پز بدهند که شاید ما تلگرام نداریم اما این اپ فلان امکانات را دارد که مال شما ندارد!!

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

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

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

گردآوری توسط ایده طلایی

نقشه راه فرانتند دولوپر‌ها

در ادامه پست قبلی، که «میخوام برنامه‌نویس بشم» بود، نقشه‌های راه را جدا کردم و در دو پست جداگانه مینویسم تا خواندن آن برای خواننده و ویرایش آن‌ها برای خودم راحت‌تر باشد.

در این پست مسیر فرانتندی‌ها را مرور میکنیم.

خب بریم سراغ فراتند. HTML رو که گفتیم پایه و اساسه و بکندی‌ها هم بلد باشن. برای شروع فرانتند حتما باید CSS رو بلد باشین و جاواسکریپت هم باید بدونین. جاواسکریپت در ادامه مسیر بسیار مهمه پس باید پایه‌ای یاد بگیرید. DOM و ایجاد تغییرات در اون رو باید یاد بگیرید و گرفتن API یا AJAX رو هم بدونید. ES6 برای ادامه مسیر مهم است و بهتره که همین اول یاد بگیرید.

استفاده از یک PackageManager مانند npm یا yarn را باید بدانید و یکی از پیش پردازنده‌های CSS یا همون CSS Pre-processors رو باید یادبگیرید، مانند SASS یا LESS. از بین فریم ورک‌های CSS هم یکی را یاد بگیرید مانند Bootstrap یا Semantic UI البته بوتسترپ پر طرفدارتر است

از ابزارها، کار کردن با یکی از task runner ها مانند gulp و یک Module Bundler مانند Webpack را یاد بگیرید، و همچنین از Linters and Formatters استفاده کنید.

بعد از این‌ها باید یکی از فریم‌ورک‌ها را انتخاب کنید. ReactJs, AngularJs, VueJs. در حال حاضر همه این‌ها پرطرفدار هستند و بهتره از تو سایت‌های کاریابی ببینید که کدوم بیشتر مورد استقبال شرکت‌ها هست. در ادامه برای اینکه حرفه‌ای باشید، باید بتونید برای کدتون تست بنویسید. Unit Test, Functional Test, Integration Test تست‌هایی است که باید یاد بگیرید بنویسید.

در این مرحله شما یک فرانتند دولوپر هستید. البته که میتونید تو حوزه‌های موبایل اپلیکیشن وارد بشید و مثلا react Native کار کنید یا server side rendering انجام بدید.

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

پ.ن۱. من سعی میکنم در روز‌های آینده لینک‌های آموزشی در هر بخش را هم به پست اضافه کنم.

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

نوشته نقشه راه فرانتند دولوپر‌ها اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

نقشه راه بکند دولوپر‌ها

در ادامه پست قبلی که «میخوام برنامه‌نویس بشم» بود، نقشه‌های راه را جدا کردم و در دو پست جداگانه مینویسم تا خواندن آن برای خواننده و ویرایش آن‌ها برای خودم راحت‌تر باشد.

در این پست مسیر بکندی‌ها را مرور میکنیم.

اول یک زبان انتخاب کنید. چه زبانی انتخاب کنیم؟ میتونید یه زبان اسکریپتی انتخاب کنید مثل: PHP, Ruby, Python یا یک زبان فانکشنال مثل Scala یا انتخاب‌های دیگه‌ای مثل Go, Java, .Net, Rust. آیا برای همه این زبان‌ها کار هست؟ بله حتما هست. میتونید یه سرچ تو سایت جابینجا یا کارلیب بزنید و ببینید کدوما تو ایران بیشتر رو بورسن یا اگه قصد مهاجرت دارید تو سایت‌هایی مثل لینکدین یا indeed سرچ کنید. اگر رنج حقوق هم براتون مهمه برای شرکتای خارجی میتونید تو سایت glassdoor میانگین حقوق‌ها رو هم ببینید. البته پیشنهادی که میکنن بزرگان امر، این هست که اول از زبان‌های اسکریپتی شروع کنید و بعد سراغ بقیه زبان‌ها برید.

روی زبانی که انتخاب کردید وقت بزارید و سعی کنید تمرین کنید باهاش. در کنار یادگیری زبان باید یک packageManager هم بتونید استفاده کنید. مثلا برای PHP از Composer، برای روبی از Gem استفاده میشود. زمانی که تمرین میکنید سعی کنید استاندارد‌های اون زبان رو هم یادبگیرید، مانند PSRs برای PHP. اینجوری عادت به نوشتن کد‌های خوب میکنید. همچنین برای حل هر مشکلی و نوشتن هر کدی best practice اون رو سرچ کنید. شما یه خط کد رو به شکل‌هایی مختلف ممکنه بتونید بنویسید ولی باید ببینید که افراد حرفه‌ای اون رو چجوری مینویسن و در اصلاح best practice اون چیه.

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

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

بعد از اینکه یک اپلیکیشن ایجاد کردین و دیتابیس و زبان رو خوب یاد گرفتین وقت انتخاب یک فریم‌ورک برای کار کردنه. مثلا برای PHP فریم‌ورک‌هایی مثل laravel یا symfony بسیار پرطرفدار هستند. تا اینجا شما یک بکند کار هستین که بهتره یه چیز‌هایی مثل caching, REST APIs, Web Servers رو هم بشناسه.

البته به این موضوع دقت داشته باشید که مثال‌ها برای Package Manager یا فریم ورک، برای PHP مثال آورده‌شده، اما شما بسته به زبانی که انتخاب میکنید فریم‌ورک‌های متفاوتی وجود دارد که میتوانید انتخاب کنید و این‌ها صرفا مثال‌های برای آشنایی هستند.

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

نوشته نقشه راه بکند دولوپر‌ها اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

میخوام برنامه نویس بشم

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

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

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

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

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

سوال دوم کار برا برنامه نویسی هست؟

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

خب برگردیم به سوال اول، یک نفر میخواد برنامه نویس وب بشه و میخواد بدونه از کجا شروع کنه. اول از همه باید بدونین که تو سال ۲۰۱۹ وب دولوپرها تو سه شاخه فعالیت میکنن، frontend, backend, devOps. بکندی‌ها برنامه مینویسن با دیتابیس و سرور سر و کار دارند و در واقعا برنامه ای که اطلاعات رو میگیره و پردازش میکنه و به کاربر تحویل میده رو انجام میدن. فرانتندی‌ها رو ظاهر سایت می‌کنن در واقع چیزی که کاربر نهایی میبینه و باهاش کار میکنه. DevOps ها برنامه‌های تولید شده رو به دست مشتری تو کوتاهترین زمان میرسونن. البته دوآپس یک اصطلاح تقریبا جدید هست که از سال ۲۰۰۹ بوجود آمده.

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

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

تقدم و تاخری بین یادگیری فرانتند و بکند نیست و میشه هرکدوم رو که دوست دارین اول یاد بگیرید. چون اگر وارد دنیای کار بشید ناخودآگاه با قسمت‌هایی از کار تیم مقابل هم آشنا میشین. من توی دو تا پست در ادامه همین پست، نقشه راه بکند و فرانتند رو مینویسم

و البته چه فرانتد و چه بکند دولوپر باشید باید بتونید با گیت کار کنید، قوانین ورژن زدن رو بدونین، کار با ترمینال رو بلد باشین، ساختمان داده و طراحی الگوریتم بدونید، بتونید به سرور ssh وصل بشید و کار کنید و دیزاین پترن‌ها رو بشناسید.

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

گردآوری توسط ایده طلایی

تنبلی و تنبلی

موقع تنبلیم یاد کوالا میوفتم آخه (منبع عکس)

از اولین پستم دو روز میگذره، یکم تنبلیم گرفت و نتونستم دیروز پست رو بذارم…

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

دو روز پیش با خودم قرار گذاشتم که آموزش زبان جاوا رو از صفر شروع کنم و تا دو ماه هر روز ساعت ۱۸ تا ۲۱ فقط یادگیری زبان جاوا رو پیگیری کنم که برای تقویت برنامه نویسیم بهتر باشه! ولی متاسفانه پروژه ای که دیروز از سمت کارفرما تایید شد دستخوش تغییرات اساسی در کد نویسی شد و از اپلیکیشن اندروید به وب اپلیکیشن تغییر کرد! من هم تا یک ساعتی تو کما بودم…

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

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

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

البته ممکنه بتونیم متقاعدشون کنیم با .Net Core روی لینوکس کار کنیم و با raspberry board پروژه شون رو اجرا کنیم.

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

کسی میتونه تو این زمینه راهنماییم کنه؟ قراره زبانی انتخاب کنم که بتونه هم به سخت افزار raspberry board دسترسی داشته باشه مخصوصا پورت COM و اینکه با Angular بتونه کار کنه و یه وب سرویس عالی هم داشته باشه.

ممنون میشم راهنماییم کنید.

با سپاس از اینکه وقت گذاشتین و پست بنده رو خوندین.

نوشته تنبلی و تنبلی اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

پیدا کردن منشا خطا در برنامه با آنالیز فایل Dump

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

ابزارهایی وجود دارند که حافظه را مورد کاوش قرار داده و فعالیت هایی که یک پروسس انجام می دهد را مانیتور می کنند. در حال حاضر ابزارهای مختلفی وجود دارند از جمله Visual Studio, ProcDump, DebugDiag و WinDbg که ما در این پست از ProcDump استفاده می کنیم.

برای شروع من یک برنامه ساده ایجاد کردم که شامل یک button است و با فشردن آن یک خطای نامشخص اتفاق می افتد.

برنامه را اجرا میکنیم، سپس به TaskManager رفته و آیدی پروسس برنامه را پیدا میکنیم.

آیدی پروسس ما ۱۰۸۹۶ می باشد.

ProcDump را دانلود کرده و توسط CMD به این صورت اجرا کرده تا تمامی فعالیت های پروسس موردنظر را زیرنظر بگیرد و فایل Dump را تولید کند.

procdump.exe -ma -e 10896

حالا نوبت به کلیک روی Button جهت ایجاد خطا می رسد. روی باتون کلیک کرده و منتظر می شویم تا Dump از حافظه جمع آوری و در سیستم تولید شود.

عملیات با موفقیت انجام شده و فایل Dump در ادرس مشخص ایجاد می شود.

پیدا کردن منشا خطا

بعد از ایجاد فایل Dump نوبت به پیدا کردن منشا خطا و رسیدن به کد موردنظر می رسد. ویژوال استودیو را باز کنید و فایل Dump را درون VS درگ/دراپ کنید.

در پنجره ای که باز میشود میتوانید مشخصات کاملی از برنامه را مشاهده کنید. سمت راست چند گزینه وجود دارد که با توجه به نوع برنامه (مدیریت شده یا محلی) و زبان برنامه نویسی باید انتخاب کنید. از آنجایی که برنامه ما با زبان سی شارپ ایجاد شده گزینه اول یعنی Debug with Managed only را انتخاب می کنیم.

بعد از انتخاب این گزینه بلافاصله به کدی که باعث ایجاد خطا میشود هدایت می شویم

کلام آخر اینکه سعی کنید تا حد ممکن خودتان خطاها را مدیریت کنید و از ابزارهای خطایاب مانند AppCenter نیز استفاده کنید. اخیرا WPF و WinForm نیز به AppCenter اضافه شده اند.

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

گردآوری توسط ایده طلایی

معرفی نسخه ۲ Web Template Studio برای VSCode

Web Template Studio چیست؟

Web Template Studio یکسری قالب از پیش تعریف شده هستش که توسط ویزاردی که در اختیار برنامه نویس قرار میده میتونه محیط توسعه برنامه رو همراه با کامپوننت های موردنیاز پیکربندی و آماده کنه، فلسفه اصلی طراحی همچین افزونه ای کاهش زمان برنامه نویس ها برای اماده کردن محیط برنامه نویسی هست

در حال حاظر Web Template Studio از React , Vue, Angular و از Nodejs و Flask برای بک اند پشتیبانی میکنه.

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

WTS کاملا متن باز هستش و توسط کارآموزهای شرکت ماکروسافت ایجاد شده

راه اندازی

ابتدا افزونه رو از اینجا دانلود و نصب کنید

با فشردن کلید های Ctrl + Shift + P و نوشتن Web Template Studio ویزارد رو باز کنید

قدم اول : نام پروژه و محل ذخیره

قدم دوم : انتخاب فریمورک

قدم سوم : افزودن صفحات به پروژه

این صفحات برای بازدهی بالا بازطراحی شده اند. برای شروع شما میتوانید انواع مختلف قالب های صفحه را ایجاد کنید که شامل blank، grid، list و حالت master details می باشد.

شما می توانید با کلیک روی preview پیشنمایش این صفحات را مشاهده کنید.

قدم چهارم : سرویس های ابری

درحال حاظر سرویس ابری Azure پشتیبانی میشود

قدم پنجم : بازبینی و ایجاد پروژه

در این مرحله شما میتوانید نمای کلی از پروژه را مشاهده کنید و تغییرات موردنیاز را در صورت لزوم اعمال کنید سپس با کلیک روی Create Project پروژه را ایجاد کنید.

قدم ششم : اجرای برنامه

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

yarn install

سپس

yarn start

نوشته معرفی نسخه ۲ Web Template Studio برای VSCode اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

۱::۲ – آشنایی با HTML

هفته اول :: جلسه دوم

به نام حضرت دوست که هرچه داریم از اوست

در جلسه ی دوم دوره ی عملی برنامه نویسی وب (Web Development Advanced Bootcamp) قصد داریم آشنایی ابتدایی با مفاهیم HTML بدست بیاریم تا در ادامه جلسات با تمرین های و کارهای عملی که انجام میدهیم آرام آرام این آشنایی عمیق تر و عمیق تر شود.

در جلسه ی قبل با روش کار WEB آشنا شدیم و نقش HTML را در فرآیندهای وب فهمیدیم چیست.

ساختار یک فایل HTML

یک فایل HTML به شکل زیر می باشد.




This is my Web Page Title




زبان HTML زبانی است بر پایه ی برچسب (tag) ها. همانطور که در بالا میبینیم تمامی عبارت های قرار کرفته در بین <> ها تگ هستند. که هر کدام ویژگی خاص خود را دارد. در ادامه تگ ها و ویژگی هاشون رو توضیح خواهم داد.

خط اول : همانطور که در جلسه ی قبل گفته شد وقتی فایل HTML از سرور به کامپیوتر ما میرسد Browser ما شروع میکند به خواندن و تحلیل کردن آن. خوب برای اینکه به Browser بگوییم الان با چه نوع فایلی رو بروست خط اول را مینویسم تا مرورگر مانند یک فایل HTML با فایل رسیده برخورد کند.

خط دوم : این تگ که به تگ ریشه (Root) هم معروف است تگ اصلی HTML است که در ابتدای صفحه باز شده و در انتهای صفحه بسته شده است .

خط سوم : این تگ مشخصات سربرگ یک فایل html را مشخص میکند. مقدار های موجود در این بخش که خطوط ۳ تا ۵ می باشد در صفحه ی ما نمایش داده نمیشود. با مقدار هایی که در این بخش قرار خواهند گرفت به مرور زمان طی دوره آشنا خواهیم شد.

خط چهار : عنوان صفحه ی ما را مشخص میکند در تصویر ۱ محل نمایش این عنوان را مشاهده میکنید.

تصویر ۱ – title

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

تمرین ۱ : همین الان notepad را بازکنید و کدهای html بالا را در آن بنویسید البته به جای … می تونید یک عبارتی را بنویسید و در title هم اسم خودتان را بنویسید. حالا فایل حاصل شده را با پسوند .html برروی کامپیوترتان ذخیره کنید. روی فایل دابل کلیک کنید تا فایل در یکی از مرورگرهای کامپیوترتان باز شود. (تبریک میگم اولین صفحه ی وب تان را ساختید)

Element and Attribute

همانطور که گفتیم زبان html از تگ ها درست شده است و حالا با Elementها آشنا میشیم که به ترکیب تگ باز ، تگ بسته و ویژگی های آن تگ گفته میشود. برای مثال به Element زیر نگاه کنید.

Hamid Reza Madani

اسم element

a

تگ باز – opening tag

تگ بسته – closing tag

ویژگی – attribute

href=”http://www.hrmadani.ir”

محتوا – Content

Hamid Reza Madani

بعضی از element ها هم در html تگ بسته ندارند مانند:

آشنایی با چند Tag پرکاربرد


Hamid Reza Madani

I’m an experienced web developer


src=”https://files.virgool.io/upload/users/4295/avatar/qR3j1J.png?x-oss-process=image/resize,h_90,w_90,center” alt=”hrmadani” />
You can follow me with @hrmadani in all social media

Follow me in the Instagram
href=”https://www.instagram.com/hrmadani/”>@hrmadani
and you can read my posts in
href=”https://virgool.io/@hrmadani”>virgool.io

Thank you…

Copyright © 2019 HRMadani Personal Blog

اولین تگ پر کاربردی که قصد دارم بهتون معرفی کنم تگهای

تا

است که تیتر درست میکند. که

بزرگترین تیتر و

هم کوچکترین آنهاست.

تگ دوم

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

یکی از اون تگ هایی هست که برای خودش یه ویژگی های ظاهری رو دارد. این تگ معرف پاراگراف است.

یکی دیگر از تگ هایی که نقش یک جعبه رو بازی میکند بدون اینکه ویژگی ظاهری داشته باشه تگ

است.

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

تگی که به ما امکان میدهد تا تصاویر را در وب نمایش دهیم تگ است که این تگ هم ویژگی ای دارد به نام src که منبع عکس را به ما معرفی میکند.

همانطور که میبینید یکسری از تگ ها مثل دارای تگ بسته هم هستند و یکسری های دیگر مثل دیگر تگ بسته نخواهند داشت و این تگ ها داخل خودشان بسته میشوند.

/>

آدرس دهی نصبی

همانطور که در بالا دیدید برای تگ های img و a نیاز داریم به جایی آدرس بدهیم. در اینجا باید با مفهوم آدرس دهی نصبی آشنا بشیم. آدرس دهی نصبی در یک عبارت ساده یعنی بدانیم کجا هستیم تا از همانجا با قوانین آدرس دهی کامپیوتری بتوانیم به مقصد برسیم.

۱- آدرس دهی به سایتی دیگر

@hrmadani

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

۲- آدرس منبعی در سایت دیگر

ممکن است شما بخواهید یک عکس را که در سایتی دیگر است در صفحه ی خودتان نمایش دهید. با قرار دادن آدرس کامل آن عکس در ویژگی SRC میتوانید آن عکس را نمایش دهید.

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

۳- آدرس صفحه ی دیگری در وب سایت خودتان

Home

برای مثال در صفحه ی about.html هستید و قصد دارید به صفحه ی اصلی سایت منتقل شوید که فایل این دو صفحه در کنار یک دیگر قرار دارد شما برای این کار میتوانید با ثبت اسم فایل به آن صفحه لینک داشته باشید.

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

الان قصد داریم در فایل index.html لینکی درست کنیم که با کلیک برروی آن به File1.html منتقل شویم. لینک مورد نظر به چه شکلی خواهد بود؟

File1

حالا میخواهیم در Index.html لینک ورود به File2.html را داشته باشیم. حالا چطور؟

حالا قصد داریم در File3.html لینک انتقال به File1.html را داشته باشیم. لینک مورد نظر به چه شکلی خواهد شد؟

همانطور که در بالا دیدیم برای رفتن به پوشه ی بالاتر کافیست از “/..” استفاده کنیم.

تمرین ۲ : حالا شما با ساختن این درخت سعی کنید در تمام فایل ها لینک رسیدن به فایلهای دیگر را ایجاد کنید.

Image Element

به ویژگی های تگ img زیر دقت کنید.

در تگ بالا ویژگی های زیر را میتوانیم مشاهده کنیم.

alt

این ویژگی کمک میکند تا در زمانی که به هر دلیلی عکس ما نمایش داده نشد این متن به جای تصویر مورد نظر ما نمایش داده شود. البته این ویژگی کمک های بیشتری به ما میکند از جمله اینکه به SEO (بهینه سازی سایت برای موتورهای جستجو – این موضوع را در آینده توضیح خواهم داد.) سایت کمک میکند و …

title

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

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

HTML Comment

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

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

تمرین نهایی این جلسه

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

htmlتمرین نهایی

با کلیک برروی دکمه ی Top به بالای صفحه منقل میشویم.

https://www.instagram.com/hrmadani/

عالم عامل عاشق باشید.

نوشته ۱::۲ – آشنایی با HTML اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی