این دیاگرام رو درست کردم تا روند(internals) تفسیر، کامپایل و اجرای سورس های PHP رو نشون بده:
برای بزرگنمایی کلیک کنید
php internals diagram
یکی از کاملترین و دقیق ترین دیاگرامهای PHP internals موجود در اینترنت هستش
این دیاگرام رو درست کردم تا روند(internals) تفسیر، کامپایل و اجرای سورس های PHP رو نشون بده:
برای بزرگنمایی کلیک کنید
php internals diagram
یکی از کاملترین و دقیق ترین دیاگرامهای PHP internals موجود در اینترنت هستش
CLASSPATH: یک متغیر در Environment variables و حاوی کتابخانه و dependency هایی هستش که هنگام Run-time و Compile-time مورد استفاده برنامه های جاوا قرار میگیره.
این متغیر برای استفاده System ClassLoader ماشین Java طراحی شده و حاوی کلاسهای کامپایل شده bytecode(در Java با پسوند class یا JAr) و کلاسهای کامپایل شده nativecode(در C با پسوند o. یا obj.) هستش. درواقع CLASSPATH بخشی از پکیج پلتفرم Java هستش و به برنامه java یا javac اعلام میکنه که کلاسهای کامپایل شده در کجا قرار دارن.
بصورت پیشفرض، محل فیزیکی CLASSPATH به پوشه "جاری پروژه" و پوشه lib در JDK/JRE نصب شده اشاره میکنه. اما اگر بخوایید میتونید این مسیر رو تغییر بدید.
نکته: با اضافه کردن کتابخانه به محل فیزیکی CLASSPATH، کتابخانه مورد نظر در تمام پروژه ها (system-wide) در دسترس قرار میگیرن، لیکن بصورت Relative link.
توجه: هرگز بصورت دستی مسیرهای jre/lib و jre/lib/ext رو داخل متغیر CLASSPATH اضافه نکنید، این مسیرها توسط ماشین جاوا بصورت خودکار پیمایش خواهند شد.
نکته: مقدار متغیر CLASSPATH میتونه توسط پارامتر -cp
در برنامه java و javac یا پراپرتی Class-Path
در فایل manifest.mf تغییر پیدا کنه. اما در نهایت پراپرتی Class-Path
نسبت به متغیر CLASSPATH و پارامتر -cp
اولویت داره! یعنی Class-Path property > CLASSPATH > -cp
نکته 2: در صورت وجود یک کتابخانه تکراری در همه مسیرهای موجود در متغیر CLASSPATH، همیشه اولین مسیر انتخاب خواهد شد.
نکته 3: تنظیمات متغیر CLASSPATH در برنامه IntelliJ IDEA در مسیر File -> Project structure -> Global libraries قرار داره و در برنامه Eclipse در مسیر Preferences -> [Java/C] -> Build path -> Classpath قرار داره.
تشریح ClassNotFoundException و NoClassDefFoundError:
- مشکل ClassNotFoundException: از نوع Exception هستش و زمانی پرتاب میشه که ماشین جاوا بصورت Dynamic سعی در load کردن کلاس موردنظر حین Run-time از مسیر CLASSPATH کنه اما نتونه پیداش کنه.
- مشکل NoClassDefFoundError: از نوع Error هستش و زمانی بوجود میاد که کلاس موردنظر در مسیر CLASSPATH حین Compile-time وجود داره اما حین Run-time وجود نداره.
Build path: مسیری هست که برای تولید/compile پروژه طراحی شده، حاوی سورس ها و کتابخانه های پروژه هستش، بخشی از workspace ویرایشگر هستش، به ویرایشگر/IDE اعلام میکنه که فایلهای سورس پروژه در کجا قرار دارن... این مسیر مخصوص ویرایشگر/IDE هستش و در هر ویرایشگری به محل متفاوتی اشاره میکنه. (مثل VSCode, Eclipse, IntelliJ IDEA, Borland...)
Include path: مسیر هست که برای parse کردن فایلهای پروژه طراحی شده، میتونه حاوی فایلهای header، سورس یا inc باشه، کد completion ویرایشگر رو اعمال میکنه و کلاً برای پیدا کردن محتوا و منابع استفاده شده در پروژه هستش.
نکته: در Include path آدرس های path داده شده باید بصورت relative باشن تا بتونن توسط IDE پردازش بشن. (relative path = ./file.jpg, absoloute path = c:\www\root\test\file.jpg)
این دیاگرام رو درست کردم تا روند(internals) کامپایل، تولید و اجرای برنامه های جاوا رو نشون بده:
برای بزرگنمایی کلیک کنید
Java internals, Java structure, JVM internals, ساختار جاوا، ساختمان جاوا
یکی از کاملترین و دقیق ترین دیاگرامهای Java/JVM internals موجود در اینترنت هستش
اطلاعات بیشتر:
http://blog.jamesdbloom.com/JVMInternals.html
💡 مقایسه سرعت الگوریتم binary search مقابل الگوریتم linear search برای آرایه های مرتب شده(sorted)
(برای آرایه های عددی سنگین)
$needle = range(1, 500000);
❌ Linear search algorithm
function search(array $numbers, $needle) { $_totalItems = count($numbers); for ($i = 0; $i < $_totalItems; $i ++) { if ($numbers[$i] === $needle) { return TRUE; } } return FALSE; }
📊 نتیجه(ms)
0.031199932098389
0.031199932098389
0.031199932098389
0.031199932098389
0.031199932098389
0.031199932098389
0.031200170516968
0.031200170516968
0.046799898147583
0.046800851821899
✅ Binary search algorithm
function search(array $numbers, $needle) { $_low = 0; $_high = count($numbers) - 1; while ($_low <= $_high) { $_middle = (int) (($_low + $_high) / 2); if ($numbers[$_middle] > $needle) { $_high = $_middle - 1; } else if ($numbers[$_middle] < $needle) { $_low = $_middle + 1; } else { return TRUE; } } return FALSE; }
📊 نتیجه(ms)
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
x64 Hardware
32bit OS
PHP 5.6 CLI
کد از کتاب "PHP 7 Data Structures and Algorithms"
ظاهراً در PHP هرچیزی بعد از دستور exit
بصورت ناقص(؟) پردازش میشه ولی بصورت کامل حافظه مورد نیازش رو allocate میکنه...
خروجی یک صفحه ساده:
<?php echo memory_get_usage(); // 217992
خروجی یک صفحه متغیر دار ولی exit
شده:
<?php echo memory_get_usage(); // 220552 exit; // <---------- !! $simpleVar = 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabbcdabcdabcdabcdabcdabcdabcd'; $simpleVar .= 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabbcdabcdabcdabcdabcdabcdabcd'; $simpleVar .= 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabbcdabcdabcdabcdabcdabcdabcd'; $simpleVar .= 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabbcdabcdabcdabcdabcdabcdabcd'; $simpleVar .= 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabbcdabcdabcdabcdabcdabcdabcd'; echo $simpleVar;
مسله indentation در کدنویسی جزییه و بیشتر شخصیه... ولی گفتن نکاتی درموردش خالی از لطف نیست
اول اینکه بیشتر Coding-style های موجود در اینترنت بروزرسانی نمیشن یا برای ویرایشگرها و مانیتورهای قدیمی طراحی شدن... یا حتی ناقص هستن! دوم اینکه چقدر خوب بود اگر مرجع رسمی براشون وجود داشت تا یک الگو، الگوی همگان میشد. نه اینکه هر شرکت و تیمی سبک انحصاریش رو طراحی و تعیین کنه و اسمشو بذاره قرارداد/convention رسمی
فکر کنید برنامه نویسایی که با دو یا چند زبان مختلف برنامه نویسی میکنن، برحسب عادت چقدر براشون سخته که از قوائد مختلف پیروی کنن...
Tab:
Space:
پیشنهاد من: SPACE با سایز 3 کاراکتر
1- فراموش نکنید که مقدار صفت android:updatePeriodMillis
در تگ <appwidget-provider
فایل xml/widget_info.xml بیانگر تایمری هست که کالبک onUpdate
کلاس ویدجت صدا زده میشه.
2- در metadata ویدجت، مقدار صفت android:minHeight
و android:minWidth
تعیین کننده حداقل اندازه ویدجت هستش که باید 72dp (یعنی 1x1) باشه. ولی صفت android:layout_width
و android:layout_height
در layout ویدجت، تعیین کننده اندازه کنونی ویدجت هستش.
3- از انجایی که List
متدی برای اضافه کردن عنصر نداره و سایزش هم ثابت هست، برای تبدیل Array
به ArrayList
باید به این روش عمل کنید:
ArrayList<String> _arrayList = new ArrayList<String>(Arrays.asList(myArray));
4- برای چک کردن وجود یک مقدار در آرایه کافیست به این صورت عمل کنید:
Arrays.asList(myArray).contains(targetValue);
5- نکته جزیی: فراموش نکنید که HashMap
در جاوا در واقع همون data structure هستش و نه آرایه!
در دنیای امنیت اطلاعات(Information security)، اصطلاحاتی مثل فرمت دهی (Encoding) ، رمزنگاری (Encryption) ، هشینگ (Hashing) و مبهم سازی (Obfuscation) بسیار به کار میرن... این تکنیک ها هر کدوم برای اهداف مختلف طراحی شدن و راه ها(الگوریتم ها) مختلفی هم برای پیاده سازی اونها وجود داره. شاید اولش کمی گیج کننده باشه، ولی در واقع هر کدوم از این تکنیک ها کاربرد خاص خودش رو دارن و اصلاً ارتباطی با هم ندارن!
توی این مقاله سعی کردم به زبان ساده توضیح بدم که هر کدوم دقیقاً چیکار میکنن، چه الگوریتم هایی دارن و چرا باید بدونیم که کدوم رو کی استفاده کنیم.
1- برای رفع خطای OutOfMemory هنگام کار با تصاویر راه های زیر رو دنبال کنید:
- مقدار خاصیت largeHeap
در فایل مانیفست رو true
قرار بدید.
- سعی کنید از LRU cache manager استفاده کنید.
- تصاویر رو compress کنید.
- کدهارو بررسی کنید که memory leak رخ نداده باشه. (که 90% بخاطر بی توجهی به activity life cycle رخ میده)
- برای سرویس ها و Toast ها از ApplicationContext استفاده کنید.
- دقت کنید که broadcast receiver ها رو Unreg
کنید.
- همه Observer ها رو بعد از استفاده delete کنید.
- همه resource ها رو(مثل XML) بعد از استفاده destroy کنید.
مقاله کامل و قابل فهم از حافظه Stack و حافظه Heap.
2- مقدار صفت android:targetSdkVersion
در تگ uses-sdk
فایل AndroidManifest.xml، به دستگاه با نسخه مشابه SDK فرمان میده که سیستم compability رو غیرفعال کنه. بنابراین سرعت پردازش برنامه افزایش و کارایی برنامه بهبود پیدا می کنه.
3- یادتون باشه که synchronized
و Thread-Safe در جاوا یک مفهوم دارن: دسترسی همزمان به کد توسط چند Thread بدون بروز مشکلات. یعنی کد/متد synchronized
اجازه دسترسی همزمان چند Thread به کد/متد رو نمیده، پس Thread ها باید نوبتی به کد/متد دسترسی پیدا کنن بنابراین آخرین وضعیت کد/متد در همه Thread ها مشترک هستش.
نکته: این مسئله فقط در مورد برنامه های Multi-Thread صدق میکنه و نه Single-Thread.
4- برای حل مشکل minSdk(API x) != deviceSdk(API y) در Android Studio یکی از راه های زیر رو دنبال کنید:
راه اول: داخل گوشی/emulator به مسیر Settings -> منوی Developer options برید و گزینه USB debugging رو فعال کنید.
راه دوم: زمانی که گوشی/emulator رو وصل می کنید، داخل گوشی پنجره Allow USB Debugging باز میشه که حاوی fingerprint هم هست... اون رو ALLOW کنید.
راه سوم: مطمعن شید که حافظه گوشی/emulator پر نشده باشه... اگر شده خالیش کنید.
راه چهارم: داخل گوشی/emulator به مسیر Settings -> منوی Storage برید و از بالا options رو باز کنید، سپس گزینه USB computer connection رو بزنید و نهایتا Media device MTP رو فعال کنید. (اگر درست نشد، Camera device رو فعال کنید)
راه پنجم: نسخه targetSdkVersion و compileSdkVersion رو یکی کنید.
راه ششم: فایل build.gradle رو باز کنید و مقدار عددی minSdkVersion رو به مقدار عددی deviceSdk تغییر بدید.
راه هفتم: داخل Android Studio به منوی Tools -> گزینه Android برید و ADB Integration رو فعال کنید.
راه هشتم: داخل Android Studio به قسمت Build Tools Version برید و نسخه رو به مقدار عددی minSdk یا deviceSdk تغییر بدید.
راه نهم: کلاً از device های سری Preview, N, L استفاده نکنید.