1- جهت پشتیبانی از ارث بری چندگانه در PHP میتونید توسط trait
ها اون رو شبیه سازی کنید.
trait PHP { public function printPHP() { echo 'PHP '; } } trait Java { public function printJava() { echo 'Java '; } } trait PHPJava { use PHP, Java; } class ProgrammingLanguages { use PHPJava; }
2- اگر در حین کار با Composer یا PHPUnit با خطای module openssl is already installed on Unknown in line 0 مواجه شدید، کافیه اکستنشن openssl رو در PHP.ini غیرفعال کنید:
ویندوز ;extension=php_openssl.dll لینوکس ;extension=php_openssl.so
1- بهتره همیشه شماتیک :file رو در کلاس WebView
رو مسدود کنید.
کلاس WebView
قابلیت نمایش صفحات وب در داخل اکتیویتی رو فراهم میکنه، و از اونجایی که دیگر برنامه ها قادرن Intent URI به WebView
ایجاد شده بفرستن، پس این امکان رو هم دارن تا بتونن فایل یا آدرس URI آلوده رو در دستگاه بارگذاری کنن...
راه حل:
String _intentUrl = getIntent().getStringExtra("http://blog.ir"); if (!_intentUrl.startsWith("file:")) { loadUrl = _intentUrl; }
2- از انجایی که همه برنامه ها قادرن محتوای logcat
رو read کنن، هرگز اطلاعات حساس رو برای دیباگ Log
نکنید، مخصوصاً درخواستها و پاسخهای HTTP رو.
3- اگر در حین بازکردن برنامه Eclipse با خطای Java was started but returned exit code 13 مواجه شدید، این یعنی مثلاً Java 64bit نصب کردید، درصورتی که Eclipse تون 32bit هستش. یا Java 32bit نصب کردید، درصورتی که Eclipse تون 64bit هستش.
بنابراین باید معماری هردو یکی باشه... مثلاًً هردو 32bit یا هردو 64bit باشن.
نکته: در صورت حل نشدن مشکل با نصب معماری مناسب، فایل eclipse.ini رو که در کنار فایل اجرایی Eclipse تون هست رو باز کنید و بدنبال واژه –vm بگردید... بعد در زیر این واژه مسیر نصب شده Java رو جایگزینش کنید...
و یا برنامه Eclipse رو باز کنید و به مسیر Menu -> Prefecences -> Java -> Installed JREs برید و مسیرنصب شده Java رو بهش بدید...
نکته اینکه دستور در نرم افزار Android Studio 3 و Gradle 3 و جدیدتر منسوخ شده و بجاش باید از دستور compile
implemention
استفاده بشه. (میتونید براحتی و بدون مشکل جایگزینشون کنید)
پس باید بگیم فرق دستور api
با دستور implemention
چیه:
api
به اصطلاح حکم public کردن یک کتابخانه رو دارههمونطور که با public کردن یک متد میتونید اون متد رو برای همه کلاس ها و پکیج ها share و قابل دسترسی کنید، توسط دستور api
هم میتونید محتویات یک کتابخانه رو برای کل پروژه share و قابل استفاده کنید. (درواقع توسط دستور api
، کتابخانه مورد نظر در همه جای پروژه "رخنه" میکنه)
implemention
به اصطلاح حکم private کردن یک کتابخانه رو دارههمونطور که با private کردن یک متد میتونید اون متد رو از همه کلاس ها و پکیج ها "مخفی و غیر قابل دسترسی" کنید که " فقط در محل خودش قابل استفاده باشه"، توسط دستور implemention
هم میتونید محتویات یک کتابخانه رو فقط برای برنامه یا کتابخانه ای که ازش استفاده کرده "نمایان و قابل استفاده" کنید. implementation
کتابخانه رو برای ماژولهای دیگر پروژه پنهان میکنه و به کدهای داخلی محدود میکنه.
مثلا:
MyApp -> Lib -> Lib2
👆 در اینجا برنامه MyApp به کتابخانه Lib وابستست، و کتابخانه Lib به کتابخانه Lib2 وابستست...
با api
کردن Lib2 باعث میشید تا محتویات این کتابخانه در کل پروژه قابل دسترس باشه.
اما آیا واقاً لازم دارید؟
dependencies { api project(':Lib2') }
مثلا اگر متد sendRequest()
در کتابخانه Lib2 قرار گرفته باشه و فقط کتابخانه Lib از این متد استفاده کرده باشه، با api
کردن Lib2 اون متد هم در اختیار شما و کل پروژه خواهد بود. چیزی که واقاً لازم نیست...
زمانی باید از دستور api
استفاده کنید که میخوایید از محتویات یک کتابخانه که برای یک کتابخانه دیگر هست استفاده کنید. 👆 مثل Lib2
یا پروژه تون کلاً یک کتابخانست. مثل SugarORM یا Log4J یا Volley یا ApacheHTTP...
✅ همیشه باید از دستور implemention
استفاده کنید. اینطوری خود Gradle plugin تشخص میده که آیا لازمه به api
تغییر کنه یا نه.
درصورت بروز خطا، بدونید که به اشتباه از متدهای کتابخانه های تودرتو و زیرین استفاده کردید پس باید رفعش کنید.
Android Gradle plugin engineer Jerome Dochez: When you switch to the new Android Gradle plugin 3, you should replace all yourcompile
(andapi
) with theimplementation
keyword.implementation / testImplementation / androidTestImplementation
1- همیشه از تابع mysql_tquery()
بجای mysql_query()
استفاده کنید. تابع mysql_tquery از نوع multi-thread هستش و میزان وقفه/lag در سرور رو بسیار کاهش میده. (عملیات رو بین Thread ها تقسیم میکنه)
2- درصورتی که از سیستم های ضد hack/cheat استفاده می کنید، همیشه EnableStuntBonusForAll
رو 0 قرار بدید.
در غیراینصورت سرور کاربر رو هکر قلمداد میکنه.
3- توسط پلاگین crashdetect میتونید crash های سرور رو ردیابی کنید.
https://github.com/Zeex/samp-plugin-crashdetect
نکته: برای استفاده از این پلاگین در ویندوز، مطعمن بشید که VC++ runtime 2010 - VC10 نگارش x86 و x64 رو نصب دارید.
4- همیشه دستورات AddPlayerClass()
رو در مختصات مناسب و قابل دسترس تنظیم کنید تا در صورت بروز باگ یا مشکلات شبکه ای(packet lost) کاربر به موقعیت مناسبی teleport بشه.
در Java چندین کلاس برای نوشتن و خواندن ورودی و فایلهای متنی وجود داره... اما کدام کلاس مناسبتره، کدام سریعتره و کدام نیازهای کاربر رو برطرف میکنه؟
برای خواندن ورودی/فایل stream بصورت خط به خط از نوع string.
دارای بیش از 20 متد public داخلی.
پشتیبانی از متد close()
برای بستن file handle.
توانایی خواندن ورودی از System.in (یا stdin)
این کلاس thread-safe هست. (میتوان BufferedReader رو در بین thread ها share کرد)
دارای حافظه buffer با سایز 8 کیلوبایت.
میتواند کلاس FileReader و InputStreamReader رو بعنوان reader در سازنده دریافت کند.
این کلاس synchronized هست.
پیاده سازی شده در JDK 1.1 و جدیدتر.
دارای کمترین system calls و کاملاً بهینه.
در صورت وقوع استثنا IOException اونرو throw میکنه.
عدم پشتیبانی از Encoding بصورت مستقیم.
زیر مجموعه پکیج java.io.
دارای پرفورمنس بالا نسبت به کلاسهای Scanner و FileReader.
توانایی خواندن ورودی فقط با نوع string.
مناسب برای محیط های multi-thread.
مناسب برای خواندن متن/ورودی طولانی بصورت string و خط به خط. (مثل فایلهای log, books)
برای خواندن ورودی/فایل بصورت parse کردن داده های نوع primitive. (مثل int, long, double, string)
دارای بیش از 60 متد public داخلی.
پشتیبانی از متد close()
برای بستن file handle.
توانایی خواندن ورودی از System.in (یا stdin)
این کلاس thread-safe نیست. (نمیتوان Scanner رو در بین thread ها share کرد)
دارای حافظه buffer با سایز 1 کیلوبایت.
میتواند کلاس FileReader و BufferedReader رو بعنوان reader در سازنده دریافت کند.
این کلاس synchronized نیست.
پیاده سازی شده در JDK 1.5 و جدیدتر.
دارای system calls پایین و تقریباً بهینه.
در صورت وقوع استثنا IOException اونرو مخفی میکنه.
عدم پشتیبانی از Encoding بصورت مستقیم.
زیر مجموعه پکیج java.util.
دارای پرفورمنس پایین نسبت به کلاسهای BufferedReader و FileReader.
توانایی خواندن ورودی با نوع int, long, string, float...
به دلیل استفاده از regular expression حافظه/CPU بیشتری نسبت به کلاس BufferedReader مصرف میکنه.
مناسب برای خواندن متن/ورودی و parse کردنش توسط delimiter. (مثل فایلهای xml, ini, config, json)
برای خواندن فقط فایل از نوع string.
دارای 20 متد public داخلی.
پشتیبانی از متد close()
برای بستن file handle.
عدم توانایی خواندن ورودی از System.in (یا stdin)
بدون قابلیت buffer.
پیاده سازی شده در JDK 1.1 و جدیدتر.
دارای بیشترین system calls و بسیار کند.
در صورت وقوع استثنا IOException اونرو throw میکنه.
عدم پشتیبانی از Encoding. (درواقع پیشفرض platform رو استفاده میکنه)
زیر مجموعه پکیج java.io.
دارای پرفورمنس بسیار پایین نسبت به کلاسهای Scanner و BufferedReader.
توانایی خواندن ورودی فقط با نوع string.
بهتر است بصورت مستقیم استفاده نشود.
کتابخانه OkHTTP
توسط Square تولید شده. مناسب برای Streaming و استفاده General مبتنی بر HTTP. پشتیبانی از POST, GET, UPLOAD. دارای مستندات آموزشی. زیربنای پیشفرض Retrofit و Picasso. یکی از زیربناهای Volley هستش. دارای disk cache. پشتیبانی از conn pooling. از پروتکل SPDY پشتیبانی می کنه. از اندروید 4.4 به بعد بصورت builtin در زیربنای اندروید استفاده شده. پشتیبانی از NewIO و...
کتابخانه Retrofit
توسط Square تولید شده. مناسب برای RESTful API / Web Service. پشتیبانی از POST, GET, PUT, DELETE, Multipart. دارای مستندات آموزشی. مبتنی بر کلاینت OkHTTP. دارای disk cache. پشتیبانی از async با کمترین کد. دارای cancellation و retryy برای درخواست ها. پشتیبانی از Dynamic URL. کمی کندتر از Volley اما سریعتر از AsyncTask هستش. دارای مفسر پیشفرض JSON و تبدیلش به POJO بکمک GSON. پشتیبانی از NewIO. پشتیبانی از فعالیت های background.
کتابخانه Volley
توسط Google پشتیبانی شده. مناسب برای استفاده General و کار با تصاویر. پشتیبانی از POST, GET, PUT, DELETE. دارای مستندات آموزشی. دارای کلاینت های OkHTTP, Apache, HttpUrlConnection. دارای memory cache. پشتیبانی از conn pooling. پشتیبانی از async با کمترین کد. دارای prioritization, cancellation, retrying برای درخواست ها. پشتیبانی از Dynamic URL. کمی سریعتر از Retrofit هستش. پشتیبانی از Image loading. دارای bitmap caching. سازگاری مناسب با activity lifecycle. دارای memory error handing مناسب. هندل کننده duplicate calls. استفاده نسبتاً آسان.
البته اگر بدنبال کتابخانه های سبکتر و کوچیکتر HTTP می گردید این گزینه ها هم میتونن انتخاب خوبی باشن:
LoopJ's android-async-http (HttpClient)
http://loopj.com/android-async-http/
Fast-Android-Networking
https://github.com/amitshekhariitbhu/Fast-Android-Networking
jus
https://github.com/apptik/jus
RoboSpice
https://github.com/stephanenicolas/robospice
این نکته رو هم در نظر داشته باشید که هرکدوم مزایا و معایب خودشونو دارن و باید درجای مناسبش کتابخانه مناسب رو انتخاب کنید.
ابتدا باید بگم استاندارد رسمی برای سبک ها و workflow ها وجود نداره، اما در این مقاله سعی می کنم از تجربیاتم، قوائد همگانی و معمولترین موارد موجود در Atlassian، Kernel و git manpage استفاده کنم...
مقالات مرتبط:
دانلود، نصب و راه اندازی Git در ویندوز
کدام پروتکل: //:git یا //:ssh یا //:https
فهرست مندرجات:
1- هنگام Multi-thread کردن کدهاتون فراموش نکنید برای دسترسی به اشیاء lazy-initialize(یا همون load on demand) وضعیت نهایی شی باید synchronize باشه تا با مشکل race condition مواجه نشید.
2- برای نرمال سازی ستونها و جلوگیری از افزونگی/redundancy داده باید از اصول زیر پیروی کنید:
- هیچ ستونی نباید بیشتر از یک نوع/type داده رو نگهداری کنه. (مثل int + char + float...)
- هیچ ستونی نباید داده های تکراری/مشابه به دیگر ستون ها رو در خودش نگهداری کنه.
- داده هارو در جداول مختلف نگهداری کنید و درصورت لزوم اونهارو توسط کلید خارجی/foreign key بهم متصل کنید.
3- جهت افزایش پرفورمنس، همیشه کلاس والد و اینترفیس رو در خطوط قبل از کلاس ارث بر تعریف کنید. در غیراینصورت موتور PHP برای پیدا و پردازش کردن کلاس والد مجبور به انجام عملیات های اضافی خواهد شد. (بر اساس OpCode تولید شده)
interface IData { } class MyClass implements IData { }
نکته: حتی اگر در فایلهای جداگانه تعریفشون می کنید این قائده باز هم باید رعایت بشه.
4- یادتون باشه که Dependency Injection نه تنها از طریق Constructor، بلکه از طریق Setter, Interface و Property هم قابل انجامه.
نکته: زمانی از نوع Constructor استفاده کنید که کل کلاس نیازمند اون dependency هستش یا شی dependency نباید در طول life time تغییر بکنه.