رتبه موضوع:
  • 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
علت بوجود آمدن برخی مشکلات برنامه نویسی ؟
#1
سلام
دقت کردید گاهی دراجرای  برنامه ها در هر زبانی به مشکلات عجیب برخورد میکنید ؟!
بعنوان مثال به تصویر ضمیمه نگاه کنید
همانطور که میبینید دو رشته String s1,s2 داریم که مقدار مساوی دارند ودر قسمت پایین صفحه نمایش داده شده
این تصویر لحظه دیباگ برنامه است
مقدارs1 و s2 همانطور که در شکل معلوم است "0104"  است اما با وجود اینکه شرط if(s1==s2) برقرار است ولی وارد else برنامه میشود
این مشکل در خیلی از زبانها دیده شده در زبان c ودلفی نیز مشاهده میشد اینجا نیز همچنان که میبینید دیده میشود
البته همیشه هم دلیلش اشکال در قسمت دیگری از برنامه بوده که در چنین جای بی ربطی بروز میکند
گنه کرد در بلخ آهنگری به شوشتر زدند گردن مسگری
شما با چنین مشکلاتی برخورد داشتید ؟
رابطه ای که بتوان مشکل را سریعتر پیدا کرد برایش یافته اید ؟
پیدا کردنش توی برنامه های بزرگ خیلی سخته !


فایل‌های پیوست تصاویر بندانگشتی
   
پاسخ
تشکر شده توسط:
#2
منکه جاواکار نیستم، اما خیلی از مسائل برنامه نویسی بین تمام زبانها مشترک است.
مثلا یک منشاء خطاهای عجیبی مثل این میتونه مثلا در برنامه های مالتی ترد باشه، که متغییرهایی میتونن همزمان توسط چند ترد مورد دسترسی و تغییر قرار بگیرن. در اینگونه موارد باید از مکانیزم هایی مثل قفل (mutex و امثالهم)، برای محدود کردن دسترسی همزمان، استفاده بشه.

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

بعد گذشته از تمام اینها بنده اخیرا یک مطلبی در وبلاگم گذاشتم: http://hamidreza-mz2.tk/?p=1730
البته باید توجه داشت بطور معمول امکان رخداد این نوع از خطاها خیلی کمه، ولی بهرحال غیرممکن هم نیست. ولی قاعدتا بطور معمول این خطاها نباید بصورت مستمر رخ بدن و تنها گهگاهی بصورت رندوم ظاهر بشن. اگر خطایی دارید که مدام یا حداقل چند بار پشت سر هم رخ میده، به احتمال زیاد دلیلش soft error نیست.

ضمنا یک وقت ممکنه اصلا خود سخت افزار هم تاحدی معیوب باشه و مثلا بعضی سلول های RAM گهگاه دچار خطا بشن. یا حتی ممکنه CPU و قسمتهای دیگر معیوب باشن. اینو خودم تاحالا دیدم که سخت افزار معیوب اولش ممکنه با خطاهای نرم افزاری عادی و مسائل دیگه اشتباه گرفته بشه. ضمنا طرف دیگر سخت افزار اگر کم کیفیت باشه ممکنه در برابر soft error هم آسیب پذیرتر بشه و بنابراین نرخ خطاهای soft error اون خیلی بالاتر بره.

میشه گفت 99% موارد اشکال از کار برنامه نویس است در خود کد منبع است، ولی منشاء 1% موارد هم میتونن چیزهای دیگر باشن. پس شما اول باید دنبال ایراد برنامه نویسی خودتون بگردید.
پاسخ
تشکر شده توسط: shpegah
#3
بله البته مطمئنم یه جایی از برنامه خودم مشکل داره همونطور که گفتم این اولین باری نیست که با این مشکل برخورد میکنم وهر بار هم برمیگشت به تخریب بخشی از حافظه به دلیل آزاد نشدن به موقع آن ودسترسی به بخشی که در دسترس قرار داده نشده
در ضمن من از تردی هم استفاده نکردم و همون ترد اصلی است منتها ریکرسیو دارم
تک تک متدها ومتغییر ها رو هم بررسی کردم ولی چون زیادن تریس کردنشون کار سختیه وتمرکز دوچندان میخواد
بازهم از راهنماییتون ممنون
پاسخ
تشکر شده توسط:
#4
جالبه الان دقیقا مشابه همین مشکل واسه منم پیش اومده، یک ساعته دارم باهاش سر و کله میزنم بفهمم علتش چیه هنوز موفق نشدم!

الان یه کد مثال دارم اینطوری:
String tmp2=new String("yes");
				String tmp3=new String("yes");
		
				if(tmp2==tmp3) {
ولی if اش اجرا نمیشه!!

میگم نکنه باگی چیزی توی جایی هست مثلا توی جاوا یا اندروید؟
پاسخ
تشکر شده توسط:
#5
اوه یه چیزی!
الان این کد درست کار میکنه:
String tmp2="yes";
String tmp3="yes";
if(tmp2==tmp3) {

این منو به شک میندازه که مشکل احتمالا به نحوه متفاوت مقایسه آبجکت هایی که در heap ایجاد میشن با متغییرهای معمولی مربوط میشه. منظورم اینه احتمالا درمورد اونایی که مقایسه درست جواب نمیده بخاطر اینه که مقایسه رو بر اساس آدرس حافظهء اونا انجام میده (اینکه آیا واقعا هر دو متغییر به یک شیء یکسان اشاره میکنن یا نه) و نه مقدارشون.

من جاوا کار نکردم بخاطر همین نمیتونم مطمئن باشم این جزیی از ساختار جاواست یا باگی چیزی هست. باید برم روی کارش تحقیق کنم!
پاسخ
تشکر شده توسط: shpegah
#6
oh my god
یافتم یافتم  Big Grin

ظاهرا علتش دقیقا همون بود که حدس زده بودم:

java67.blogspot.com/2012/11/difference-between-operator-and-equals-method-in.html

باید از این کد استفاده کرد:

String tmp2=new String("yes");
String tmp3=new String("yes");
if(tmp2.equals(tmp3)) {
پاسخ
تشکر شده توسط: shpegah
#7
اوه اوه این جاوا عجب زبانیه! توش باید خیلی دقیق باشی. آسان گیر نیست اصلا!

مثلا این متد equals هم یه جاهایی جواب نمیده. چه جاهایی؟ خب معلومه وقتی متغییر بجای آبجکت، null باشه! چون اونوقت دیگه شیء ای وجود نداره که بخواد متد equals داشته باشه.

مثلا من بخاطر همین از این روش برای مقایسه استفاده کردم:

"yes".equals(vars.getString("via_builtin_app"))

حداقل اون yes اونجا متد equals رو داشت دمش گرم Big Grin

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

فک کنم باید یه مقاله توی وبلاگم درمورد این قضیه بنویسم اصلا!
بنظرم خیلی برنامه نویسان با این مسئله مشکل دارند و خواهند داشت. بخصوص کسانی مثل ما که جاواکار نبودن ولی الان اومدن برنامه نویسی اندروید بکنن دارن با جاوا کار میکنن.
پاسخ
تشکر شده توسط: shpegah
#8
برای مقایسه رشته ها باید حتماً از متد equals استفاده کنید. عملگر == داره خود اشیاء رو مقایسه میکنه نه متن داخلشون رو. مثل اینکه من یه شئ داشته باشم با کلی فیلد و بعد یه شئ دیگه هم از همون کلاس ایجاد بشه و فیلدها هم مقادیرشون یکسان باشه. با اینحال اشیاء با هم برابر نیستن و دو شئ متفاوت هستن. متد equals داره مقدار متن داخل شئ String رو مقایسه میکنه. این سختگیریهای جاوا توی پروژه های Enterprise واقعاً لازمه و همین چیزهاست که اون رو تبدیل به اولین زبان مطرح در دنیا کرده و پروژه هایی که باهاش نوشته میشه، باگهای سیستمی خیلی کمی داره و اکثر باگها ناشی از نقص در کدنویسی و منطق برنامه هستن.
پاسخ
تشکر شده توسط: Eshpilen , shpegah
#9
(20-09-1394، 02:08 ب.ظ)ADMIN نوشته: برای مقایسه رشته ها باید حتماً از متد equals استفاده کنید. عملگر == داره خود اشیاء رو مقایسه میکنه نه متن داخلشون رو. مثل اینکه من یه شئ داشته باشم با کلی فیلد و بعد یه شئ دیگه هم از همون کلاس ایجاد بشه و فیلدها هم مقادیرشون یکسان باشه. با اینحال اشیاء با هم برابر نیستن و دو شئ متفاوت هستن. متد equals داره مقدار متن داخل شئ String رو مقایسه میکنه. این سختگیریهای جاوا توی پروژه های Enterprise واقعاً لازمه و همین چیزهاست که اون رو تبدیل به اولین زبان مطرح در دنیا کرده و پروژه هایی که باهاش نوشته میشه، باگهای سیستمی خیلی کمی داره و اکثر باگها ناشی از نقص در کدنویسی و منطق برنامه هستن.
بهرحال خیلی غیرمنتظره هست همچنین چیزی بخصوص درمورد String که یکی از انواع داده ای پایه و درونی جاواست و توی بیشتر زبانها چنین داستانی نداره تاجاییکه یاد دارم.

آدم وقتی دوتا رشتهء معمولی رو مقایسه میکنه انتظار نداره زبان برنامه نویسی هم طور دیگه ای عمل کنه. بخصوص اینکه فقط درمورد رشته هایی که روی heap ایجاد میشن اینطوره، آدم رو بیشتر گمراه و سردرگم میکنه. آخه دوتا رشتهء معمولی دیگه جز مقدارش معمولا اهمیت و کاربرد دیگری در برنامه نویسی نداره کسی میخواد آبجکت هاشون رو مقایسه کنه که چی بشه! یکم نامفهوم هست دیگه. ولی خب حتما جاوا بخاطر consistency این کار رو کرده خواسته رفتارش درمورد تمام آبجکت ها یکسان و سازگار باشه.

خیلی از برنامه نویسان اندروید، مثل خودم، چون قبلا جاوا رو یاد نگرفتن جاوا کار نکردن بنابراین اینطور چیزا رو نمیدونن. حتما باید توی منابع این قبیل gotcha های متداول رو مطرح کنن که ملت حواسشون جمع بشه برنامه هاشون نره روی هوا!
پاسخ
تشکر شده توسط: shpegah
#10
دقیقاً همینطوره. مسئله همینه که String جزو انواع داخلی زبان و اصلاحاً Primitive Datatype ها نیست و یک کلاس هست که متدهایی مثل ()length و... داره و برای همین مثل بقیه اشیاء از متد equals براش استفاده شده. بهرحال خوندن راهنما و مستندات میتونه کمک زیادی در این زمینه بکنه.
پاسخ
تشکر شده توسط: Eshpilen , shpegah




کاربران در حال بازدید این موضوع: 3 مهمان