जावा के छोटे टोटके। भाग २

पहले लेख की निरंतरता में , मैं सबसे सामान्य त्रुटियों और बस खराब कोड के बारे में कुछ और स्पर्श जोड़ूंगा, जिन्हें आपको पहले से ही लिखित परियोजनाओं के साथ काम करते समय अक्सर निपटना पड़ता है। मैं इसे पहले भाग में नहीं रख सकता था, क्योंकि ये परिस्थितियाँ बहुत कम आम हैं, लेकिन चूंकि पहले भाग में बहुत अधिक सकारात्मक प्रतिक्रिया हुई, इसलिए मैंने इसे जारी रखने का निर्णय लिया। सभी टिप्पणीकारों, प्रतिक्रिया और टिप्पणियों के लिए धन्यवाद। मैं गलतियों से बचने की कोशिश करूंगा। तो, चलिए जारी रखते हैं:

बफर स्ट्रीम

// InputStream is = new FileInputStream(file); int val; while ((val = is.read()) != -1) { } // InputStream is = new BufferedInputStream(new FileInputStream(file)); int val; while ((val = is.read()) != -1) { } 

यह प्रतीत होता है - स्पष्ट सत्य, है ना? लेकिन जैसा कि किसी और के कोड और साक्षात्कार के उम्मीदवारों के अनुभव से पता चला है, कुछ डेवलपर्स निश्चित रूप से यह नहीं समझते हैं कि बफर धाराओं का क्या फायदा है। जो अभी भी समझ में नहीं आया है - FileInputStream वर्ग की रीड () विधि:
 public native int read() throws IOException; 

सहमत हूँ, एक बाइट को पढ़ने के लिए हर बार एक सिस्टम कॉल करना कुछ हद तक बेकार है। दरअसल, इस समस्या से बचने के लिए, शेल बफ़र्स बनाए गए थे। वे जो कुछ भी करते हैं वह पहली बार सिस्टम रीड () को पढ़ता है (वे निर्दिष्ट बफर आकार के आधार पर, जो कि डिफ़ॉल्ट रूप से 8 kb है) और अगली बार जब वे पढ़ते हैं () तो वे बफर से पहले ही डेटा पढ़ लेते हैं। प्रदर्शन का लाभ परिमाण का एक क्रम है। सिस्टम कॉल, वास्तव में, हमेशा खराब नहीं होती हैं, उदाहरण के लिए:
 System.arraycopy(src, srcPos, dest, destPos, length); 

सरणी की प्रतिलिपि बनाने के मामले में, सिस्टम विधि जावा में लागू होने की तुलना में बहुत तेज होगी। और फिर भी - बैचों में डेटा पढ़ें, और बाइट्स नहीं, यह भी एक सभ्य बचत की अनुमति देगा।

Enum बनाम स्ट्रिंग

 // String status = plan.getStatus(); if (status.equals("draft")) { //do stuff } else if (status.equals("submitted")) { //do stuff } // PlanStatus status = plan.getStatus(); if (status == PlanStatus.DRAFT) { //do stuff } else if (status == PlanStatus.SUBMITTED) { //do stuff } 

पूर्वनिर्धारित मॉडल राज्यों के लिए एनम का उपयोग करें जहां संभव हो। यह न केवल कोड की समझ को आसान बनाता है, बल्कि इन राज्यों की तुलना करने की प्रक्रिया को भी तेज करता है। संदर्भ की तुलना निश्चित रूप से तार या अन्य वस्तुओं की तुलना में तेजी से परिमाण का एक क्रम है। सच है, इस मामले में एक बड़ा ऋण है - आवेदन के समर्थन की लागत बढ़ जाती है, यह विशेष रूप से ध्यान देने योग्य हो जाता है जब आपको मौजूदा राज्यों में से एक को जोड़ने, हटाने या बदलने की आवश्यकता होती है। लेकिन अगर ये साल के महीने की तरह अपरिवर्तनीय गुण हैं, तो सुरक्षित रूप से गणना का उपयोग करें।

ArrayList बनाम हैशसेट

संग्रह में डेटा संग्रहीत करने के बारे में बहुत सावधान रहें। बहुत बार, सेट का उपयोग किया जाता है जहां एक सूची को तिरस्कृत किया जा सकता है, और एक सूची जहां एक सरणी को तिरस्कृत किया जा सकता है। उदाहरण के लिए, उन कक्षाओं में जो डेटाबेस तालिकाओं में मैप करते हैं। इससे बचें, सही निर्भरता और सही प्रश्नों का निर्माण करें। यह आपको कुछ मेमोरी को बचाएगा, क्योंकि यह कोई रहस्य नहीं है कि HashSet को HashMap पर लागू किया गया है, और HashMap, बदले में, आंतरिक एंट्री क्लास का उपयोग करता है, जिसमें कुंजी और मूल्य के अलावा एक हैश और अगली एंट्री ऑब्जेक्ट का लिंक भी संग्रहीत होता है। इसके अलावा - लगातार एक हैश जोड़ना है, जो जटिल वस्तुओं के लिए महंगा हो सकता है।

डेटा रीडिंग

 // byte[] fileBinaryData = readFile(filepath); // InputStream fileStream = readFile(filepath); 

इन निर्दोष पंक्तियों के साथ क्या गलत है? हां, सामान्य तौर पर, इस तथ्य के अलावा कि हम जिस फ़ाइल को पढ़ रहे हैं उसका आकार नहीं जानते हैं। एक फ़ाइल के बजाय, कुछ भी हो सकता है - एक खुला सॉकेट जो डेटा, पोस्ट अनुरोध से डेटा, सब कुछ स्वीकार करता है ... सामान्य तौर पर, बाइट्स की एक सरणी में सब कुछ नहीं पढ़ने की कोशिश करें, आपके पास बस पर्याप्त मेमोरी नहीं हो सकती है। इसलिए, किसी भी डेटा के आकार के साथ सावधान रहें। भागों में डेटा को संसाधित और अग्रेषित करने का प्रयास करें। और हमेशा उपयोगकर्ता डेटा के आकार पर नज़र रखें और जब भी संभव हो इसे सीमित करें।

लॉग फ़ील्ड

 // private Logger logger = Logger.getLogger(Plan.class); // private static final Logger logger = Logger.getLogger(Plan.class); 

कक्षा में लॉगिंग का उपयोग करें? हमेशा एक लॉग चर को स्थिर फाइनल के रूप में परिभाषित करें। सबसे पहले: आपको कभी भी किसी वस्तु को क्रमबद्ध और निष्क्रिय करने में समस्या नहीं होगी। दूसरी बात: क्लास ऑब्जेक्ट बनाते समय निरंतर इनिशियलाइज़ेशन के बजाय केवल 1 बार इनिशियलाइज़ेशन होता है।

फ़ील्ड्स आरंभीकरण

 // class Plan { private String name = null; private Boolean isNew = false; private Set<Document> documents = new HashSet<Document>(); } // class Plan { private String name; private Boolean isNew; private Set<Document> documents; } 

जब तक आप इस बारे में बहुत आश्वस्त न हों, तब तक समय से पहले वर्ग के क्षेत्रों को शुरू करने की कोशिश न करें। फिर भी, इन उद्देश्यों के लिए आपके पास एक निर्माता है। यदि वर्ग फ़ील्ड के मानों को स्पष्ट रूप से निर्दिष्ट किया गया है, तो उन्हें निर्माणकर्ता को कॉल करने से पहले आरंभीकृत किया जाएगा, जो उन मामलों में अतिरिक्त लागतों को बढ़ाता है जहां आपको प्रारंभिक मानों का उपयोग करने की आवश्यकता नहीं होती है, उदाहरण के लिए, जब आप ऑब्जेक्ट बनाने के तुरंत बाद प्रारंभिक फ़ील्ड के लिए अन्य मान सेट करते हैं। खैर, यह मत भूलो कि वर्ग फ़ील्ड हमेशा डिफ़ॉल्ट मानों के साथ आरंभिक होते हैं।

खाली तार

 // if (name.equals("")) { // if (name.isEmpty()) { 

यदि आपको यह जांचने की आवश्यकता है कि क्या स्ट्रिंग में कोई रिक्त मान है, तो isEmpty () विधि का उपयोग करें। क्यों नहीं बराबर ()? यह कॉर्न धीमी है। यदि आप एक स्ट्रिंग के लिए इसके कार्यान्वयन को देखते हैं, तो आप तुरंत सब कुछ समझ जाएंगे। आश्चर्यचकित न हों, कई डेवलपर्स अभी भी इस पद्धति के बारे में नहीं जानते हैं।

ऑब्जेक्ट [] बनाम कस्टम क्लास

 // Object[] data = new Object[3]; data[0] = row.getUserCount(); data[1] = row.getOwnerCount(); data[2] = row.getLocations(); return data; // RowResult data = new RowResult(); data.setUserCount(row.getUserCount()); data.setOwnerCount(row.getOwnerCount()); data.setLocations(row.getLocations()); return data; 

ऑब्जेक्ट के साथ कोड पूरी तरह से अपठनीय है जब आपको कहीं और वापसी मूल्य के साथ काम करना होगा। यही है, यह समझने के लिए कि रिटर्न वैल्यू अपने आप में क्या है, आपको कॉल क्लास में वापस जाने और विधि पर टिप्पणियों को पढ़ने की आवश्यकता है, यदि, ज़ाहिर है, वे हैं, और यदि आप कोड में नहीं आते हैं, जो बहुत प्रभावी नहीं है। वास्तव में, मैं खुद कभी-कभी इस पाप को करता हूं जब मैं जल्दी में होता हूं। आप इसके साथ रख सकते हैं यदि यह बहुत दुर्लभ है, लेकिन, फिर भी, ऐसी स्थितियों में एक नया वर्ग बनाना बेहतर है। आपके बाद आने वालों के लिए जीवन आसान बनाएं।

अनाम वर्ग

बेनामी कक्षाएं एक महान विशेषता हैं, लेकिन उन्हें केवल अपने आवेदन के सभी स्थानों पर न छोड़ें, क्योंकि यह आपको एक मिनट का समय बचाएगा। अनाम कक्षाओं के साथ कोड पढ़ने के लिए बहुत कठिन है और पढ़ने के लिए कठिन है। बेशक, उन्हें अलग-अलग वर्गों में रखना बेहतर होगा, उन मामलों को छोड़कर जहां एक अनाम वर्ग बहुत उपयुक्त है।

तुलना क्रम

 // if (name.equals("broadcast")) { // if ("broadcast".equals(name)) { 

यह विधि आपको अनावश्यक अशक्त जांच से छुटकारा पाने की अनुमति देती है। लेकिन अगर आप पहले लेख से नियमों का पालन करते हैं, तो यह विधि आवश्यक नहीं है।

निष्कर्ष

हां, जो लिखा गया है वह स्पष्ट से अधिक स्पष्ट है। लेकिन अगर ऐसा है, तो यह सब परियोजना से परियोजना के लिए कहां आता है? यह लेख किसी भी तरह से आपके आवेदन के प्रदर्शन को बेहतर बनाने के लिए एक मार्गदर्शिका नहीं है। यह सिर्फ एक अच्छी, सही शैली है। आशा है कि यह आपकी मदद करता है।

Source: https://habr.com/ru/post/In132374/


All Articles