{"id":2333,"date":"2009-01-04T23:41:30","date_gmt":"2009-01-04T15:41:30","guid":{"rendered":"http:\/\/ihower.idv.tw\/blog\/?p=2333"},"modified":"2011-04-09T02:03:34","modified_gmt":"2011-04-08T18:03:34","slug":"practices-of-an-agile-developer-5-debug","status":"publish","type":"post","link":"https:\/\/ihower.tw\/blog\/2333-practices-of-an-agile-developer-5-debug","title":{"rendered":"\u5be6\u6230\u654f\u6377\u958b\u767c Practices of an Agile Developer (5) \u9664\u932f\u7bc7"},"content":{"rendered":"<p>Update(2009\/9\/22): \u770b\u5230\u53e6\u4e00\u7bc7<a href=\"http:\/\/www.wretch.cc\/blog\/kojenchieh\/15344161\">\u8aaa\u660e bug report \u8a72\u6709\u4ec0\u9ebc\u5167\u5bb9<\/a>\u3002<\/p>\n<p>debugging \u6700\u5927\u554f\u984c\u5728\u65bc\uff0c\u5b83\u662f\u4e00\u500b\u672a\u77e5\u7684\u6642\u9593\u7bb1\u5b50\uff0c\u4e0d\u77e5\u9053\u8981\u82b1\u591a\u4e45\u624d\u80fd debug \u5b8c\u3002\u9019\u7ae0\u8ac7\u7684\u662f\u5e7e\u500b\u9664\u932f\u4e0a\u7684\u6280\u5de7\u3002<\/p>\n<p>\u8aaa\u5230\u9664\u932f\uff0c\u6211\u4e5f\u63a8\u85a6\u95b1\u8b80<a href=\"http:\/\/www.chiark.greenend.org.uk\/~sgtatham\/bugs-tw.html\">\u5982\u4f55\u6709\u6548\u5730\u5831\u544a\u932f\u8aa4<\/a>\u9019\u4e00\u7bc7\u6587\u7ae0\uff0c\u8ac7\u7684\u662f\u5982\u4f55\u6b63\u78ba\u56de\u5831\u932f\u8aa4\uff0c\u597d\u7684\u932f\u8aa4\u56de\u5831\u53ef\u4ee5\u7bc0\u7701\u5f88\u591a\u6642\u9593\uff0c\u800c\u4e0d\u50c5\u50c5\u53ea\u662f\u4e00\u53e5 &#8220;\u7a0b\u5f0f\u4e0d\u6703\u52d5&#8221; \u800c\u5df2\u3002<\/p>\n<h3>Keep a Solutions Log (\u7d00\u9304\u4e0b\u89e3\u6c7a\u554f\u984c\u7684\u8fa6\u6cd5)<\/h3>\n<p>\u89e3\u6c7a\u554f\u984c\u4e00\u76f4\u662f\u8edf\u9ad4\u958b\u767c\u8005\u7684\u5de5\u4f5c\u9805\u76ee(\u9019\u88e1\u6307\u7684\u554f\u984c\u6bd4\u8f03\u50cf\u662f\u8edf\u9ad4\u5b89\u88dd\u3001\u7248\u672c\u3001\u51fd\u5f0f\u5eab\u4f7f\u7528\u7b49\u7b49\u554f\u984c\uff0c\u4f8b\u5982 windows \u4e0a\u5982\u4f55\u628a MySQL Ruby gem \u88dd\u8d77\u4f86\u7b49\u7b49)\uff0c\u4e0d\u904e\u6709\u6642\u5019\u6703\u78b0\u5230\u4f3c\u66fe\u76f8\u4f3c\u7684\u554f\u984c\uff0c\u7591\uff1f\u6211\u4ee5\u524d\u662f\u600e\u9ebc\u89e3\u6c7a\u7684\uff1f\u62dc\u7db2\u8def\u767c\u9054\u4e4b\u8cdc\uff0cGoogle \u641c\u5c0b\u4e00\u4e0b\u901a\u5e38\u6703\u6709\u4e0d\u5c11\u5e6b\u52a9\uff0c\u4f46\u662f\u9084\u662f\u5f97\u82b1\u4e0d\u5c11\u6642\u9593\u627e\u5c0b\u89e3\u7b54\u3002<\/p>\n<p>\u81ea\u5df1\u7dad\u8b77\u4e00\u4efd\u7c21\u55ae\u7684 solutions log \u5427\uff0c\u7d00\u9304\u4e0b\u65e5\u671f\u3001\u554f\u984c\u63cf\u8ff0\u3001\u89e3\u6cd5\u3001\u53c3\u8003\u7db2\u5740\u7b49\u7b49\u8cc7\u8a0a\uff0c\u4e4b\u5f8c\u78b0\u5230\u985e\u4f3c\u7684\u554f\u984c\u5c31\u53ef\u4ee5\u641c\u5c0b\u7684\u5230\u3002\u5c07\u9019\u4efd log \u7528 wiki \u7dad\u8b77\u4e5f\u662f\u4e0d\u932f\u7684\u4e3b\u610f\u3002\u6216\u662f\u5beb\u5728 Blog \u4e0a\uff0c\u9019\u6a23 google \u641e\u4e0d\u597d\u9084\u6703\u641c\u5c0b\u5230\u81ea\u5df1\u4ee5\u524d\u5beb\u7684\u89e3\u6cd5&#8230;XD<\/p>\n<h3>Warnings Are Really Errors (\u628a\u8b66\u544a\u7576\u771f)<\/h3>\n<p>\u7de8\u8b6f\u5668(\u9019\u88e1\u6cdb\u6307 complier \u6216 interpreter) \u7684\u8b66\u544a\u5e38\u5e38\u6709\u4eba\u662f\u5ffd\u7565\u4e0d\u770b\u7684\uff0c\u53cd\u6b63\u53ef\u4ee5\u7de8\u8b6f\u57f7\u884c\u4e0d\u6703 error \u5c31\u597d\u4e86\uff1f\u66f8\u4e0a\u8209\u4e86 C++ \u7684\u4f8b\u5b50\uff0c\u7de8\u8b6f\u5668\u7684\u8b66\u544a\u9084\u662f\u883b\u6709\u7528\u7684(\u6211\u60f3\u7279\u5225\u662f static \u8a9e\u8a00)\u53ef\u4ee5\u5e6b\u52a9\u4f60\u627e\u5230\u8ddf\u907f\u514d\u6f5b\u5728\u7684 Bugs\uff0c\u8acb\u4e0d\u8981\u5ffd\u7565\u3002\u8acb\u5c07\u7de8\u8b6f\u5668\u7684\u8b66\u544a\u4e5f\u7576\u4f5c\u7a0b\u5f0f\u932f\u8aa4\u6216\u7121\u6cd5\u901a\u904e\u6e2c\u8a66\u7684\u7a0b\u5f0f\u4e00\u6a23\u8a8d\u771f\u8655\u7406\u3002<\/p>\n<p>\u6211\u81ea\u5df1\u5beb Ruby\/Rails \u7684\u7d93\u9a57\uff0c\u6700\u5e38\u898b\u7684\u8b66\u544a\u50cf\u662f\u6709\uff1a <\/p>\n<p><code><br \/>\nlink_to ( 'login', login_path ) # warning: don't put space before argument parentheses<br \/>\n<\/code><br \/>\n\u56e0\u70ba\u4e2d\u9593\u591a\u4e86\u4e00\u500b\u6c92\u7528\u7684\u7a7a\u767d\u3002\u6216\u662f<br \/>\n<code><br \/>\np Array.new 3, 1 # warning: parenthesize argument(s) for future version<br \/>\n<\/code><br \/>\n\u56e0\u70ba interpreter \u89ba\u5f97 ambiguities \u4e0d\u6e05\u695a\uff0c\u9019\u6642\u8981\u8acb\u4f60\u62ec\u865f\u62ec\u6e05\u695a\u3002\u53e6\u5916\u5c31\u662f DEPRECATION WARNING \u8b66\u544a\u4e86\uff0c\u544a\u8a34\u4f60\u9019\u51fd\u5f0f\u5c07\u4f86\u7684\u7248\u672c\u5c07\u6703\u79fb\u9664\uff0c\u8acb\u4e0d\u8981\u518d\u7528\u4e86 :p<\/p>\n<h3>Attack Problems in Isolation (\u9694\u96e2\u9664\u932f)<\/h3>\n<p>\u8981\u5728\u4e00\u500b\u5927\u7cfb\u7d71\u627e\u7279\u5b9a\u554f\u984c\uff0c\u4e0d\u8981\u6574\u500b\u7cfb\u7d71\u4e00\u8d77\u6e2c\uff0c\u800c\u662f\u5c07\u5206\u958b\u9694\u96e2\u627e\u51fa\u75c5\u56e0\u3002\u5982\u679c\u6709\u505a unit tests\uff0c\u6211\u5011\u77e5\u9053\u53ef\u4ee5\u5c07 dependence \u7684\u6771\u897f\u7528 mock object \u9694\u96e2\u51fa\u4f86\uff0c\u9019\u6a23\u6e2c\u8a66\u7684\u6642\u5019\u5c31\u4e0d\u6703\u88ab\u5916\u90e8\u56e0\u7d20\u5e72\u64fe\u3002\u540c\u7406\u5728\u6293\u6574\u500b\u7cfb\u7d71\u4e2d\u7684\u7279\u5b9a Bugs \u7684\u6642\u5019\uff0c\u5fc5\u8981\u7684\u8a71\u53ef\u4ee5\u505a\u4e00\u4e9b\u5047\u7684 prototype \u5143\u4ef6\u7528\u4ee5\u9694\u96e2\u6293\u51fa\u554f\u984c\u6240\u5728\uff0c\u540c\u6642\u4e5f\u6bd4\u8f03\u597d\u9664\u932f\u6e2c\u8a66\u3002<\/p>\n<p>\u6211\u81ea\u5df1\u571f\u6cd5\u7149\u92fc\u9664\u932f CSS \u4e5f\u662f\u5982\u6b64\uff0c\u5148\u79fb\u9664 CSS \u6a94\u6848\u7684\u4e00\u534a\uff0c\u770b\u770b\u554f\u984c\u662f\u4e0d\u662f\u51fa\u5728\u9019\u88e1\uff0c\u7136\u5f8c\u518d\u780d\u4e00\u534a\u76f4\u5230\u627e\u5230\u6709\u554f\u984c\u7684\u90a3\u4e00\u884c\u3002(Binary search?)<\/p>\n<h3>Report All Exceptions (\u56de\u5831\u6240\u6709\u7684\u4f8b\u5916)<\/h3>\n<p>\u5982\u679c\u547c\u53eb\u4e00\u500b\u53ef\u80fd\u6703\u4e1f\u4f8b\u5916\u7684\u51fd\u5f0f\uff0c\u7576\u78b0\u5230\u4f8b\u5916\u6642\uff0c\u76e1\u91cf\u53ef\u4ee5\u8655\u7406\u5c31\u8655\u7406\uff0c\u4e0d\u7136\u8acb\u8b93\u4ed6\u81ea\u7136\u50b3\u64ad(Propagate)\u4e0a\u53bb\u7d66\u4e0a\u4e00\u5c64 Caller \u8655\u7406\uff0c\u4e0d\u8981\u6514\u4e0b\u4f86\u53c8\u4ec0\u9ebc\u90fd\u4e0d\u505a\u3002\u5982\u679c\u5728\u6574\u500b call stack \u4e2d\u6709\u500b\u50a2\u4f19\u5beb\u4e86\u500b\u7a7a\u500b catch \u6240\u6709\u4f8b\u5916\uff0c\u7136\u5f8c return null \u4ec0\u9ebc\u90fd\u4e0d\u505a\uff0c\u5230\u6642\u5019\u8981\u627e Bugs \u4f60\u5c31\u6703\u5f88\u60f3\u6bba\u4eba\u4e86\uff0c\u56e0\u70ba\u975e\u5f97 trace \u9032\u53bb call stack \u624d\u80fd\u627e\u5230\u539f\u56e0\u3002<\/p>\n<p>\u4e0d\u8981\u89ba\u5f97\u81ea\u5df1\u4e0d\u6703\u9019\u6a23\u5beb\uff0c\u5176\u5be6\u5e38\u5e38\u6211\u5011\u6703\u60f3&#8221;\u66ab\u6642&#8221;\u4e0d\u60f3\u8655\u7406\u9019\u500b\u4f8b\u5916\uff0c\u65bc\u662f\u5c31\u7559\u4e0b\u9019\u6a23\u7a7a\u7684\u4f8b\u5916\u8655\u7406\u7a0b\u5f0f\u78bc(\u7136\u5f8c\u7e7c\u7e8c\u7559\u5230 Production code)\u3002\u6c7a\u5b9a\u8981\u5728\u54ea\u4e00\u5c64\u8655\u7406\u4f8b\u5916\u662f\u500b\u8a2d\u8a08\u4e0a\u7684\u8003\u91cf\uff0c\u4f46\u662f\u5982\u679c\u547c\u53eb\u4e00\u500b\u51fd\u5f0f\u537b\u8981\u8003\u616e\u8655\u7406\u4e8c\u4e09\u5341\u7a2e\u4ee5\u4e0a\u7684\u4f8b\u5916\u53ef\u80fd\u5c31\u6709\u8a2d\u8a08\u4e0a\u7684\u554f\u984c\u4e86\u3002<\/p>\n<h3>Provide Useful Error Messages (\u63d0\u4f9b\u4f7f\u7528\u8005\u6709\u7528\u7684\u932f\u8aa4\u8a0a\u606f)<\/h3>\n<p>\u4e00\u822c\u6027\u7684\u932f\u8aa4\u8a0a\u606f\u5982 &#8220;Something went wrong&#8221; \u5c0d\u4f7f\u7528\u8005\u4f86\u8aaa\uff0c\u53ef\u8aaa\u662f\u4e00\u9ede\u5e6b\u52a9\u4e5f\u6c92\u6709\uff0c\u65e2\u6c92\u6709\u544a\u8a34\u7528\u6236\u53ef\u4ee5\u600e\u9ebc\u89e3\u6c7a\uff0c\u5c31\u7b97\u4f7f\u7528\u8005\u60f3\u8981\u6c42\u52a9\u4e5f\u4e0d\u77e5\u9053\u767c\u751f\u4ec0\u9ebc\u4e8b\u60c5\u3002\u6240\u4ee5\u76e1\u91cf\u63d0\u4f9b\u8a73\u7d30\u7684\u8a0a\u606f\u544a\u8a34\u4f7f\u7528\u8005\u767c\u751f\u4ec0\u9ebc\u4e8b\u60c5\u3002<\/p>\n<p>\u7576\u7136\uff0c\u5982\u679c\u662f\u6bd4\u8f03\u56b4\u91cd\u7684\u7a0b\u5f0f\u4f8b\u5916\u932f\u8aa4\uff0c\u5c0d\u958b\u767c\u8005\u4f86\u8aaa\uff0c\u56e0\u70ba\u6709 logging \u7684\u95dc\u4fc2\uff0c\u6240\u4ee5\u770b log \u61c9\u8a72\u53ef\u4ee5\u77e5\u9053\u5927\u6982\u7684\u60c5\u6cc1\u4e26\u6392\u9664\uff0c\u9019\u985e\u7684\u932f\u8aa4\u5c0d\u4f7f\u7528\u8005\u4f86\u8aaa\u4e5f\u6c92\u8fa6\u6cd5\u81ea\u884c\u6392\u9664\uff0c\u4e5f\u53ea\u80fd\u544a\u8a34\u7528\u6236\u8aaa\u9019\u4e0d\u662f\u56e0\u70ba\u4ed6\u5011\u64cd\u4f5c\u932f\u8aa4\u7684\u539f\u56e0\u3002<\/p>\n<p>\u95dc\u65bc\u9019\u500b\u8b70\u984c\u9019\u4e00\u7bc0\u8b1b\u7684\u4e0d\u662f\u5f88\u6e05\u695a\uff0c\u6211\u500b\u4eba\u63a8\u85a6\u6709\u672c 37 signals \u7684\u5c0f\u66f8\u53ef\u4ee5\u7ffb\u7ffb\uff1a<a href=\"http:\/\/www.amazon.com\/Defensive-Design-Web-improve-messages\/dp\/073571410X\">Defensive Design for the Web<\/a> \u5716\u6587\u4e26\u8302\u5171\u670940\u689d Guideline \u544a\u8a34\u4f60\u5982\u4f55\u6539\u9032\u7db2\u7ad9\u7684\u932f\u8aa4\u63d0\u793a\u8a0a\u606f\u3001\u8868\u55ae\u586b\u5beb\u7b49\u7b49\uff0c\u4f8b\u5982\uff1a<\/p>\n<ul>\n<li>\u932f\u8aa4\u8a0a\u606f\u8981\u660e\u986f\uff0c\u4f7f\u7528\u984f\u8272\u3001Icons \u7b49\u6548\u679c<\/li>\n<li>\u932f\u8aa4\u8a0a\u606f\u5305\u542b\u9019\u662f\u4ec0\u9ebc\u932f\u8aa4\u4ee5\u53ca\u5982\u4f55\u4fee\u5fa9<\/li>\n<li>\u6574\u500b\u7db2\u7ad9\u7528\u4e00\u81f4\u7684\u932f\u8aa4\u63d0\u793a\u65b9\u5f0f<\/li>\n<li>\u5728\u932f\u8aa4\u63d0\u793a\u5f8c\uff0c\u4e0d\u9700\u8981\u518d\u56de\u4e0a\u4e00\u9801\u624d\u80fd\u4fee\u6b63\u554f\u984c<\/li>\n<li>\u7528\u6613\u61c2\u3001\u79ae\u8c8c\u7684\u5b57\u53e5<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Update(2009\/9\/22): \u770b\u5230\u53e6\u4e00\u7bc7\u8aaa\u660e bug report \u8a72\u6709\u4ec0\u9ebc\u5167\u5bb9\u3002 debugging &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/ihower.tw\/blog\/2333-practices-of-an-agile-developer-5-debug\" class=\"more-link\">\u95b1\u8b80\u5168\u6587<span class=\"screen-reader-text\">\u3008\u5be6\u6230\u654f\u6377\u958b\u767c Practices of an Agile Developer (5) \u9664\u932f\u7bc7\u3009<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[51,9],"tags":[],"class_list":["post-2333","post","type-post","status-publish","format-standard","hentry","category-agile","category-books","entry"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1q6tG-BD","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/posts\/2333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/comments?post=2333"}],"version-history":[{"count":37,"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/posts\/2333\/revisions"}],"predecessor-version":[{"id":5554,"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/posts\/2333\/revisions\/5554"}],"wp:attachment":[{"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/media?parent=2333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/categories?post=2333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ihower.tw\/blog\/wp-json\/wp\/v2\/tags?post=2333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}