सभी को नमस्कार!
आपका ध्यान लेखक के एक लेख के अनुवाद के लिए आमंत्रित किया गया है जो पहले से ही हैबे पर जाना जाता है । इस बार वह अपने दृष्टिकोण को साझा करता है कि अपने दैनिक विकास में जावा भाषा के कुछ गुणों को लागू करने के लिए कितनी बार आवश्यक है।

जावा शक्तिशाली मानक सुविधाओं के साथ एक भाषा है, लेकिन
"महान शक्ति महान जिम्मेदारी देती है ।
" मैंने बहुत सारे जावा कोड देखे जिनमें भाषा के "दुर्लभ" गुणों का अत्यधिक उपयोग किया गया था (और अक्सर गलत तरीके से), जबकि मूल बातें की मूल बातें लगभग पूरी तरह से नजरअंदाज कर दी गई थीं। इन टिप्पणियों ने एक लेख लिखने के लिए एक प्रोत्साहन के रूप में कार्य किया।
यह भाषा सुविधाओं की सूची
नहीं है जिसका उपयोग प्रत्येक प्रोग्रामर को करना चाहिए। बल्कि, इसके विपरीत। मैंने उन्हें 3 समूहों में विभाजित किया: "
रोजमर्रा के उपयोग के लिए ", "
आवधिक उपयोग के लिए " और "
केवल रूपरेखा और पुस्तकालयों के लिए! " नियम सरल है: यदि आप समझते हैं कि आप इन गुणों का उपयोग अनुशंसित से अधिक बार करते हैं, तो सबसे अधिक संभावना है कि आपका कोड गलत तरीके से विकसित हो रहा है। यदि इसके विपरीत, आप शायद ही कभी मेरे द्वारा सुझाए गए गुणों का उपयोग करते हैं, तो आप भाषा की कुछ दिलचस्प और महत्वपूर्ण विशेषताओं को याद कर रहे हैं।
कृपया ध्यान दें कि मैं विशिष्ट सर्वर-साइड व्यावसायिक अनुप्रयोगों (JVM, JDK, बस इतना ही) के विकास के बारे में बात कर रहा हूं और मैं किसी भी ढांचे के संबंध में सिफारिशें नहीं देता हूं।
हर रोज इस्तेमाल के लिए
कक्षाएं, इंटरफेस, पैकेजहां, अपना कोड कक्षाओं में रखें। अध्ययन के बाद से, आपको शायद याद है कि एक वर्ग डेटा है और इस डेटा के साथ काम करने के तरीके। एक वर्ग जिसमें केवल डेटा होता है, उसे "संरचना" कहा जाता है। एक वर्ग जिसमें केवल विधियाँ हैं, वास्तव में, केवल तार्किक रूप से कुछ कार्यक्षमता जोड़ती है। इंटरफेस आवश्यक होने पर ही प्रयोग करें। लेकिन एक एकल कार्यान्वयन के साथ एक इंटरफ़ेस बनाने से पहले दो बार सोचें। शायद आपको मध्यस्थ से छुटकारा चाहिए? अंत में,
नामकरण सम्मेलनों का पालन करने के लिए याद करते हुए, पैकेजों में कक्षाएं और इंटरफेस रखें।
स्थैतिक तरीकेउनसे डरो मत, लेकिन उन्हें केवल उपयोगिता विधियों के रूप में उपयोग करें जो एक राज्य के अस्तित्व का मतलब नहीं है। स्थिर तरीकों में कोई व्यावसायिक तर्क नहीं!
ExecutorService, थ्रेड पूलफ्यूचर <T> प्रकार के थ्रेड्स , क्वीन्स और ऑब्जेक्ट्स के
पूल को समझना और सही ढंग से उपयोग करना अत्यावश्यक है
। अपने स्वयं के पूल को लागू करके पहिया को सुदृढ़ न करें।
Producer-Consumer
बारे में सुनकर उन्हें सबसे पहले आपके दिमाग में आना चाहिए
परमाणु परिवार- *काउंटरों और संदर्भों को पढ़ने / बदलने के लिए
synchronized
का उपयोग न करें।
Atomic-*
परिवार
"विनिमय के साथ तुलना" के आधार पर बहुत कुशलता से कार्यान्वित किया जाता है सुनिश्चित करें कि आप इन वर्गों द्वारा प्रदान की गई गारंटियों को समझते हैं।
डिजाइन पैटर्नतकनीकी रूप से, वे जावा भाषा का हिस्सा नहीं हैं, लेकिन मुझे उनके महत्व को देखते हुए उनका उल्लेख करना चाहिए। आपको उन्हें स्वतंत्र रूप से जानना, समझना और उनका उपयोग करना होगा, लेकिन उचित सीमा के भीतर। (साथ ही इंटरफेस, वैसे)।
गैंग ऑफ़ फोर और
कॉर्पोरेट एप्लिकेशन टेम्प्लेट को आपके कोड में व्यापक रूप से दर्शाया जाना चाहिए। लेकिन उनका उपयोग आपके आवेदन की आवश्यकताओं के अधीन होना चाहिए, न कि इसके विपरीत।
बहु-थ्रेड सहित मानक संग्रहआपको बिल्ट-इन कलेक्शन का पूरी तरह से पता होना चाहिए और उनका उपयोग करना चाहिए,
List
,
Map
और
Set
बीच अंतर को समझें थ्रेड सुरक्षित कार्यान्वयन का उपयोग करना एक समस्या नहीं होनी चाहिए। आपको प्रदर्शन की बुनियादी विशेषताओं को जानना होगा और कार्यान्वयन के विवरण का विचार करना होगा। हम यहां
BlockingQueue के विभिन्न कार्यान्वयनों का ज्ञान जोड़ते हैं। समानांतर कंप्यूटिंग पहले से ही जटिल है, आपको भाषा के उपलब्ध साधनों का उपयोग करने की आवश्यकता है, और अपनी साइकिलों को सुदृढ़ नहीं करना चाहिए।
इनलाइन एनोटेशनवे पहले से ही यहां हैं और यह लंबे समय से है, इसलिए बेझिझक
@Deprecated
का उपयोग करें और
@Deprecated
बारे में मत भूलना
अपवादस्पष्ट प्रतिक्रिया की आवश्यकता होने पर त्रुटियों और असामान्य सिस्टम स्थितियों की रिपोर्ट करने के लिए
RuntimeExceptions
का उपयोग करें। जांचे हुए अपवादों के साथ रहने के बारे में जानें। स्टैक के निशान पढ़ना सीखें।
कोशिश-साथ-संसाधनोंइस बेहतरीन डिज़ाइन को जानिए । यदि आपकी कक्षा को अपना काम पूरा करने के बाद संसाधनों को मुक्त करने की आवश्यकता है, तो
AutoCloseable लागू करें।
इनपुट / आउटपुट को अवरुद्ध करनारीडर /
राइटर ,
इनपुटस्ट्रीम /
आउटपुटस्ट्रीम क्लास का उपयोग करें । उनके बीच के मतभेदों से अवगत रहें, बफरिंग और अन्य सज्जाकारों का उपयोग करने के लिए स्वतंत्र महसूस करें।
इस पर, "हर दिन" सूची समाप्त होती है। यदि आपने किसी भी चीज़ के बारे में नहीं सुना है, या यदि आपने इसे अपने कान के कोने से सुना है - अध्ययन करें, तो यह आपके काम आएगा।
सामयिक उपयोग के लिए
नीचे वर्णित जावा गुण का उपयोग और उपयोग किया जाना चाहिए, लेकिन कट्टरता के बिना। यदि आप हर दिन दोपहर के भोजन से पहले इस खंड से कुछ लागू करने का प्रबंधन करते हैं - तो निश्चित रूप से आपके आवेदन की वास्तुकला में कुछ गड़बड़ है। मैं दोहराता हूं - बैक-एंड के विकास के दृष्टिकोण से, ये चीजें उपयोगी हैं, लेकिन शायद ही कभी।
वंशानुक्रम और अमूर्त वर्गईमानदारी से, मैं शायद ही कभी विरासत का उपयोग करता हूं और यह नहीं कहूंगा कि मैं उसे बहुत याद करता हूं। पॉलीमॉर्फिज़्म इंटरफेस के आधार पर बहुत लचीला है, विशेष रूप से जावा (
* ) में अमूर्तता की सभी कमियों को ध्यान में रखते हुए। मैं भी
विरासत पर रचना पसंद
करता हूं । बहुत बड़े पदानुक्रम हार्ड-से-बनाए कोड का उत्पादन करते हैं
नियमित अभिव्यक्तिकुछ प्रोग्रामर, जब वे एक समस्या का सामना करते हैं, तो सोचते हैं कि "ओह, मैं नियमित अभिव्यक्ति का उपयोग करूंगा!" और दो समस्याएं आती हैं। नियमित अभिव्यक्ति के बिना एक दुनिया बहुत अधिक उबाऊ और बोझिल होगी। वे
नियमित सेट (
HTML को छोड़कर ) पार्स करने के लिए महान हैं, लेकिन फिर से, इसे अति करना बहुत आसान है। यदि आप पूरे दिन नियमित अभिव्यक्ति का उपयोग करते हैं, तो आपने गलत टूल चुना है। हर समय हिट:
public static boolean isNegative(int x) { return Integer.toString(x).matches("-[0-9]+"); }
सेमाफोर , काउंटडाउनचैच , साइक्लिक बैरियर आदि।बेशक, ये वर्ग कुख्यात युगल
wait()/notify()
तुलना में अधिक उपयोगी परिमाण का एक क्रम है। लेकिन वे मल्टीथ्रेडिंग का उपयोग करते समय आपको त्रुटियों से नहीं बचाते हैं। यदि आप अक्सर सिंक्रनाइज़ेशन के लिए इस तंत्र का उपयोग करते हैं, तो यह थ्रेड-सुरक्षित संग्रह या विशेष रूपरेखा की दिशा में देखने का समय है।
उपयोगकर्ता-परिभाषित परिमाणित प्रकार (जेनरिक)सामान्य तौर पर, अंतर्निहित संग्रह और अन्य डेटा प्रकारों का उपयोग करना जो पैरामीटर का समर्थन करते हैं, प्रोग्रामर के लिए एक सामान्य बात है। लेकिन यहां मैं आपके कोड में पैरामीटर का उपयोग करने के बारे में बात कर रहा हूं जब आपके तरीके सामान्य प्रकारों को स्वीकार या वापस करते हैं। उदाहरण के लिए:
public <T, F> ContractValidator<T extends Contract> T validate(Validator<T>, F object)
कभी-कभी यह आवश्यक है, लेकिन फिर से - बहुत दूर नहीं जाना महत्वपूर्ण है। स्थैतिक टाइपिंग और सुरक्षित प्रकार का रूपांतरण हमेशा सबसे आगे होगा, लेकिन अत्यधिक परिमाणीकरण से बचा जाता है।
JVM पर भाषाओं को स्क्रिप्टक्या आप जानते हैं कि
JDK में एक अंतर्निहित जावास्क्रिप्ट दुभाषिया है ? और यह कि आप मक्खी पर अन्य भाषाओं को जोड़ सकते हैं, जैसे कि ग्रूवी और जॉरी? तेजी से बदलते बाजारों के युग में, कभी-कभी एप्लिकेशन को फिर से तैयार करने के लिए भी पर्याप्त समय नहीं होता है, और अंत उपयोगकर्ता द्वारा इसे संपादित करने की क्षमता के साथ एक छोटी स्क्रिप्ट को पेश करना एक अच्छा विचार है। लेकिन याद रखें कि यदि स्क्रिप्ट की संख्या सिस्टम में कुल पंक्तियों की संख्या का 1% से अधिक है, तो आपको समर्थन के साथ कठिनाइयों के लिए तैयार रहने की आवश्यकता है।
जावा एनआईओइसे सही ढंग से उपयोग करना कठिन है और इससे वास्तव में लाभान्वित होना और भी कठिन है। कभी-कभी आपको इसका उपयोग प्रदर्शन और मापनीयता से बाहर निकालने के लिए करना होगा। लेकिन विशेष पुस्तकालयों का उपयोग करना बेहतर है, खासकर क्योंकि ज्यादातर मामलों में सामान्य इनपुट-आउटपुट पर्याप्त है।
synchronized
आपको एक साधारण कारण के लिए इसका दुरुपयोग करने की आवश्यकता नहीं है - ऐसे अधिक ब्लॉक, जितना अधिक बार वे निष्पादित होते हैं और प्रदर्शन कम होता है। साथ ही, आपको हमेशा इस बारे में बहुत आश्वस्त होने की आवश्यकता है कि कौन सी विशेष वस्तु एक म्यूटेक्स है। बेहतर उपयोग धागा-सुरक्षित संग्रह और
Atomic-*
।
इसलिए, मैं इस खंड में सूचीबद्ध भाषा गुणों को महत्वपूर्ण और उपयोगी मानता हूं, लेकिन रोजमर्रा के उपयोग के लिए आवश्यक नहीं है। यदि आप उन्हें लगातार उपयोग करते हैं, तो यह एक अतिभारित वास्तुकला का संकेत है ... या एक अनुभवहीन डेवलपर। सरल बनाने की क्षमता अनुभव के साथ आती है। लेकिन अगर आपके सिस्टम के लिए कोई विशेष आवश्यकताएं हैं, तो यह तीसरे समूह पर जाने का समय है।
केवल चौखटे और पुस्तकालयों के डेवलपर्स के लिए!
प्रभावी ढंग से रूपरेखा और पुस्तकालयों का उपयोग करने के लिए, आपको नीचे सूचीबद्ध भाषा गुणों के सिद्धांतों को समझना चाहिए। StackOverflow सवालों से भरा है, जिसके उत्तर आसानी से स्वयं ढाँचों के स्रोत कोड में पाए जा सकते हैं। लेकिन "समझ" जरूरी "उपयोग" का मतलब नहीं है। ये सभी चीजें - वे काफी निम्न-स्तरीय और जटिल हैं, और यहां तक कि थोड़ी मात्रा में भी काफी सिरदर्द पैदा कर सकती हैं।
सॉकेटहाँ, आपने सही सुना, सॉकेट। आपको समझना चाहिए कि टीसीपी / आईपी स्टैक कैसे काम करता है, सत्र, प्रवाह, और डेटा की सही व्याख्या करने में सक्षम है। लेकिन नेटवर्क स्तर पर सीधे काम से बचें। HTTP, FTP, NTP, SMB, ई-मेल के लिए सैकड़ों उच्च-स्तरीय लाइब्रेरी हैं ... समान
Apache कॉमन्स नेट लें । एक सभ्य HTTP क्लाइंट या सर्वर को लिखना कितना मुश्किल है, इस पर आपको शायद ही संदेह हो। और अगर आपको किसी प्रकार के मालिकाना प्रोटोकॉल के लिए सर्वर की आवश्यकता है - मैं अनुशंसा करता हूं कि आप खुद को
नेट्टी के साथ परिचित करें
प्रतिबिंबएप्लिकेशन कोड में, कक्षाओं और विधियों की आंतरिक संरचना के स्तर पर काम के लिए कोई जगह नहीं है। यह चौखटे के लिए महत्वपूर्ण है, लेकिन मुझे व्यक्तिगत रूप से इसकी आवश्यकता नहीं है। प्रतिबिंब आपके कोड को निम्न-स्तर, असुरक्षित और सरल बनाता है ... गंदा। AOP अधिकांश समस्याओं का हल करता है। मैं यह भी कहूंगा कि
Class<?>
उदाहरणों के साथ सरल कार्य
Class<?>
प्रकार पहले से ही खराब है।
गतिशील प्रॉक्सी और बाईटकोड के साथ कामप्रॉक्सी महान है, लेकिन प्रतिबिंब की तरह, इसके साथ फ्रेमवर्क और लाइब्रेरी की दया पर काम छोड़ना बेहतर है। प्रॉक्सी एक हल्के AOP के निर्माण का आधार है। यदि आपका व्यावसायिक अनुप्रयोग सीधे
बायोटेक (
** ) के साथ काम करता है (उदाहरण के लिए,
एएसएम या
सीजीएलआईबी के माध्यम से) -
आप * केवल आपसे प्रार्थना कर सकते हैं।
classloaders... और उनसे जुड़ी हर चीज - भट्टी में! फिर से - आपको यह समझने की आवश्यकता है कि वे कैसे काम करते हैं, पदानुक्रम, बाइटकोड, आदि। लेकिन अगर आप अपना बूटलोडर लिखते हैं, तो यह नरक की सड़क है। ऐसा नहीं है कि यह मुश्किल था, लेकिन बस क्यों? एप्लिकेशन सर्वर को ऐसा करने दें।
Object.clone ()मुझे याद नहीं है कि क्या मैंने अपने पूरे अभ्यास में कम से कम एक बार इस पद्धति का उपयोग किया है। और, मुझे याद आया - मैंने निश्चित रूप से इसका उपयोग नहीं किया है! और मैं यह भी नहीं सोच सकता कि मुझे इसकी आवश्यकता क्यों है। मैं स्पष्ट कॉपी कंस्ट्रक्टर पसंद करता हूं, और इससे भी बेहतर, अपरिवर्तनीय वस्तुएं। क्या आपको वास्तव में क्लोन की आवश्यकता है? ऐसा लग रहा है कि कोई नब्बे के दशक में फंस गया है ...
देशी तरीकेजेडीके में, आप इनमें से कई को देख सकते हैं, विशेष रूप से,
साइन की गणना करने का
कार्य। लेकिन जावा लंबे समय से धीमी गति वाला नहीं है, इससे पहले भी, इसके विपरीत। और मैं यह नहीं सोच सकता कि मानक या तृतीय-पक्ष लाइब्रेरी किस कार्य को हल नहीं कर सकती हैं। इसके अलावा, देशी तरीके अपने दम पर मुश्किल हैं, वे बहुत कम-स्तरीय त्रुटियों को उत्पन्न करते हैं, विशेष रूप से स्मृति के साथ काम करने के मामले में।
samopisny संग्रहमूल JavaDoc (अचानक)
कठिन कार्य के सभी अनुबंधों के अनुसार संग्रह को सही ढंग से लागू करें हाइबरनेट अपने स्वयं के कार्यान्वयन का उपयोग करता है, लेकिन आपको उनकी आवश्यकता क्यों हो सकती है - मुझे नहीं पता।
ThreadLocalफ्रेमवर्क और लाइब्रेरी इस तकनीक का उपयोग अक्सर करते हैं, लेकिन आपको दो कारणों से इससे बचना चाहिए। पहला - एक अर्ध-वैश्विक चर अक्सर थ्रेडलोक के मुखौटे के नीचे छिपा होता है। यह कोड की समझ और परीक्षण को जटिल करता है। दूसरा - थ्रेडलोकल गलत सफाई के मामले में स्मृति रिसाव का कारण बनता है। उदाहरण के लिए, हम
यहाँ ,
यहाँ ,
यहाँ और
यहाँ और
यहाँ और इतने पर पढ़ते
हैं ...
कमज़ोरपन और
नरमताये कक्षाएं काफी निचले स्तर की हैं और कचरे के कलेक्टर के साथ कसकर एकीकृत किए गए कैश को लागू करने के लिए उपयुक्त हैं। सौभाग्य से, ऐसे कैश के लिए कई ओपन-सोर्स लाइब्रेरी हैं, इसलिए खुद को एक और लिखने की आवश्यकता नहीं है। बस पता है कि ऐसी कक्षाएं मौजूद हैं और कल्पना करें कि वे कैसे काम करते हैं।
com.sun.*
और sun.*
संकुल, विशेष रूप से sun.misc.Unsafe
इन पैकेजों के
पीट बोग्स से दूर रहें, क्योंकि ... हाँ, बस दूर और यही है! भविष्य में पिछड़े अनुकूलता को बनाए रखने की गारंटी के बिना ये विशुद्ध रूप से विशेष, अविभाजित वर्ग हैं। जरा कल्पना है कि वे नहीं कर रहे हैं। और
आपको Unsafe
आवश्यकता क्यों होगी ?
वास्तव में, यह सब है बेशक, यह सब मेरी पूर्ण IMHO है। यदि आपको लगता है कि कुछ जगह से बाहर है, या मैं कुछ महत्वपूर्ण के बारे में भूल गया हूं, तो मैं कमेंटरी में पूछता हूं ताकि भविष्य में मैं कोड-समीक्षा करने या परियोजना का मूल्यांकन करने में मदद करने के लिए किसी तरह के संदर्भ गाइड को तैयार कर सकूं।
(*) अभिव्यक्ति का एक और अधिक सटीक अनुवाद "
जावा में लक्षणों की दर्दनाक कमी " का स्वागत है
(**) मैंने
मॉकिटो के बारे
में पारित नहीं किया