نمودارها ساختار داده نیستند

در طول عمر یک برنامه نویس ، شما باید با هزاران ساختار سر و کار داشته باشید. به عبارت دیگر ، شما همیشه تصمیم می گیرید که چگونه داده های خود را سازماندهی کنید. گزینه های زیادی در آنجا وجود دارد ، از متغیرهای منفرد گرفته تا ماتریس های پیچیده ساختارهای تعریف شده سفارشی. یکی از این رویکردهای متداول نمودارها است.
اما نمودارها ساختار داده نیستند: آنها ساختارهای ریاضی هستند.
البته ، می توانید آنها را به عنوان ساختار داده اعمال کنید. بنابراین بسیاری از نرم افزارها به آنها بستگی دارند. حتی اگر متوجه آن نشوید ، همیشه با نمودارها سر و کار دارید. به عنوان مثال ، یک لیست مرتبط فقط یک مورد خاص از یک نمودار کارگردانی است.
اما هنگام در نظر گرفتن نمودارها به عنوان سازه های ریاضی و نه ساختار داده صرف ، آنها به ابزاری بسیار قدرتمندتر تبدیل می شوند. در اینجا من دو برنامه دیگر از نمودارها را در توسعه نرم افزار ارائه می دهم: به عنوان یک طراحی پردازش و به عنوان بازنمایی پایگاه کد.
توجه: اگرچه این یک پست برنامه نویسی کلی است ، اما من از نمونه های کد استفاده می کنم.
پردازش توسط نمودارها
بیایید با این مشکل مقابله کنیم:
ما باید حداقل دمای هر روز یک شهر (X) را انجام دهیم ، X³ و سپس نتیجه مربع نتیجه یا لگاریتم طبیعی مخالف آن را انجام دهیم. سپس ، نتیجه را در یک نقشه ذخیره کنید و از نتیجه به عنوان کلید و گواهی آن به عنوان مقدار استفاده کنید.
اما ما باید مراقبت کنیم:
- اعداد دارای عدد صحیح 8 بیتی -128 هستند. 127
- دست زدن به گروه های شماره واقعی
- اگر
x < 0
، انجام دادنsqrt(x³)
منجر به خطای ریاضی خواهد شد. در چنین مواردی از این برنامه استفاده خواهد کردlogn(-x)
- اگر
x³
سرریز کردنint8
مقدار حداکثر ، به دنبال خواهد بودlogn(-x³)
- هنگامی که به دنبال ورود به سیستم هستید ، از یک سرویس از راه دور برای امضای خطا درخواست خواهیم کرد
آیا این یک مشکل واقع گرایانه است؟ البته نه اما ایده انتزاعی در اینجا وجود دارد.
بیایید با یک رویکرد سنتی فکر کنیم:
func process(input []int8, certs map[float64]string) {
for i := 0; i < len(input); i++ {
var result float64
var needCert bool
var cert = "no_need"
x := input[i]
switch {
case x > 0 && x*x*x < 0: // testing for overflow scenarios
x = x * x * x
// we want the same behavior as x < 0
// Note: In Go, fallthrough transfers control to the
// next case rather than breaking out of the switch
fallthrough
case x < 0:
needCert = true
result = math.Log(float64(-x))
default:
x = x * x * x
result = math.Sqrt(float64(x))
}
if needCert {
cert = askCert(x)
}
certs[result] = cert
}
}
اکنون ، ما مشکل داریم: ما یک به یک ورودی را پردازش می کنیم ، ما در تلاش هستیم همه را در یک مکان انجام دهیم ، در دسته ای پردازش و منتظریم askCert(x)
پاسخ قبل از پردازش ورودی دیگر. به طور خلاصه ، ما کارآمد نیستیم و از کدهای تمیز استفاده نمی کنیم.
بنابراین ، برای تمیز کردن این ظروف سرباز یا مسافر ، می توانیم رویکرد متفاوتی بگیریم: نمودارها.
بیایید فرض کنیم که ما فرآیندها را به عنوان رئوس و ارتباطات به عنوان لبه رفتار می کنیم. هر فرآیند یکی از عملیات اتمی ما را انجام می دهد: x³
با x < 0
با sqrt(x)
وت log(x)
، و ارتباطات از طریق کانال ها انجام می شود.
برای اجرای این کار ، بیایید با فرض اینکه به طور نامحدود (به عنوان گره) اجرا شود ، هر عملکرد را ایجاد کنیم. سپس ، ما کانال های ورودی و خروجی (لبه ها) را به آنها منتقل می کنیم. واضح ترین رویکرد برای اعلام لبه ها این است که ابتدا یک ماتریس مجاور را تعریف کنید ، سپس انواع کانال مربوطه را مشخص کنید و در آخر ، وزن لبه را اختصاص دهید (به عنوان مثال ، با استفاده از اندازه بافر در GO). البته انجام این روش کاملاً ضروری نیست ؛ در مثال اجرای کامل در زیر ، من هر کانال را به صورت دستی اعلام می کنم ، انتظار دارم که در اهداف واضح تر باشد:
اجرای کد زمین بازی
اما ، چرا ما می خواهیم این آشفتگی را ایجاد کنیم؟ دو عامل اصلی: کنترل و عملکرد. دلیل این امر این است که مثال ما فقط پایه ای برای شروع فکر کردن است. فرایندها به همان اندازه انعطاف پذیر هستند که تصور می کنیم. یکی از مهمترین سناریوهایی که باید اعمال شود ، زمانی است که شما بسیاری از عملیات I/O را انجام می دهید. می توانید از یک فرآیند vertex برای شروع تماس های پس زمینه به عملکرد I/O خود استفاده کنید و پاسخ آن را به برخی از راس دیگر ارسال کنید که در آن می دانید که از آن استفاده خواهد شد. این امر با جلوگیری از اضافه بار تماس ها ، زمان انتظار را بدون به خطر انداختن منبع از راه دور کاهش می دهد (انتزاع سیستم موجودی “فقط در زمان”).
در ابر (x) ما از این رویکرد برای تقویت پردازش داده های مشتری خود استفاده کردیم – با دستیابی به بهبود 16 برابر در بازده زمان ترکیبی و استفاده از منابع.
کد به عنوان نمودار
فایده دیگر این است که در مطالعه و نگهداری نرم افزار کمک می کند. شما می توانید برای درک پایگاه کد خود از تئوری نمودار استفاده کنید و حتی قبل از نوشتن هر کد ، رفتار آن را پیش بینی کنید.
مطالعه کد به خودی خود چیزی است که به عنوان برنامه نویسان ، ما معمولاً این کار را نمی کنیم. اما ما باید آن موضوع توسط مورد مطالعه قرار گرفته است German Cárdenas
در انتشار او “ارزیابی تکنیک تجسم مبتنی بر نمودار: یک آزمایش کنترل شده“
استفاده از نمودارها برای مطالعه پایه های کد ایده جدیدی نیست. در سال 2002 ، Eva Van Emden
وت Leon Moonen
منتشر شده “تضمین کیفیت جاوا با تشخیص بوی کد“. در آن تحقیق ، آنها نماینده بودند”موجودات“از نرم افزار با استفاده از نمودارها: بسته ها ، کلاس ها ، روش ها و غیره.
داشتن نمودارها در یک مرحله طراحی نسبتاً متداول است ، اما ما در واقع چقدر زمان برای مطالعه و حفظ این نمودارها سرمایه گذاری می کنیم؟ در تجربه من ، تقریباً هیچ کس نموداری را که در مراحل اولیه پروژه ایجاد شده است ، به روز نمی کند. به علاوه ، این نمودار صرفاً به عنوان یک مرجع بصری و نه به عنوان یک ابزار توسعه فعال ، خدمت می کند.
یک نمودار کاملاً به روز شده را تصور کنید که عملکردی ، تماس ها و مدل ها را شامل می شود. ما قادر خواهیم بود به سرعت تلاش یک تغییر را تحقق بخشیم. شما می توانید درخواست کنید Depth First Search
یا Breadth First Search
برای اینکه بدانید چند قسمت از کد شما تحت تأثیر قرار خواهد گرفت. سپس ، خود را بگیرید Dominators Tree
برای ارزیابی خطرات برنامه خود. و البته اگر نمودار قطع شود (اتصال شما از 1 بیشتر است) ، شما به سرعت متوجه خواهید شد که برای مقابله با آن کد مرده دارید.
بیایید وزنه ها را نیز به لبه ها اختصاص دهیم تا زمان اجرای مورد انتظار توابع را نشان دهد. این به ما اجازه می دهد تا زمان پاسخ یک نقطه پایانی را با استفاده از آن تخمین بزنیم Dijkstra's algorithm
بشر ما می توانیم محاسبه کنیم که تعداد منابع لازم برای ارائه تعداد مورد انتظار کاربران همزمان ، و چه بخش هایی از نرم افزار ما نیاز به بهینه سازی بیشتری دارند.
این موضوع به اندازه خود تئوری نمودار گسترده است. مطالعات و مستندات زیادی در دسترس است. این به عنوان یک توسعه دهنده به عهده شماست که این دانش را اتخاذ کرده و آن را در کار روزانه خود اعمال کنید.
پایان
ما به عنوان توسعه دهندگان نرم افزار ، می دانیم که ابزارهای زیادی در دسترس هستند. تقریباً هر سال ، یک فناوری یا به روزرسانی جدید با ویژگی های شگفت انگیز در بازار منتشر می شود ، و بسیاری از ما انتظار دارند که به روز بمانیم و آنها را در اسرع وقت اتخاذ کنیم تا در صدر صنعت فناوری بمانیم. در نتیجه ، ما از اصول اساسی دور می شویم.
بحث دوره ای در مورد اصول علوم کامپیوتر به ما کمک می کند تا ابزارهای ارزشمند ، ترفندها و بهترین شیوه ها را دوباره کشف کنیم. این به ما یادآوری می کند که ما باید به طور مداوم در مورد اجرای خود تأمل کنیم و رفتار آنها را به جای اینکه فقط به طور مکرر از همان فرمول استفاده کنیم ، مطالعه کنیم.
این بار ، نمودارها مورد بحث قرار گرفته اند. مزایای آنها بسیار زیاد است. ما باید به جای استفاده از آنها صرفاً برای ساختار داده ها ، پتانسیل کامل آنها را مهار کنیم. به یاد داشته باشید:
نمودارها ساختار داده نیستند.