The IGNOU MCS-024 Solved Question Paper PDF Download page is designed to help students access high-quality exam resources in one place. Here, you can find ignou solved question paper IGNOU Previous Year Question paper solved PDF that covers all important questions with detailed answers. This page provides IGNOU all Previous year Question Papers in one PDF format, making it easier for students to prepare effectively.
- IGNOU MCS-024 Solved Question Paper in Hindi
- IGNOU MCS-024 Solved Question Paper in English
- IGNOU Previous Year Solved Question Papers (All Courses)
Whether you are looking for IGNOU Previous Year Question paper solved in English or ignou previous year question paper solved in hindi, this page offers both options to suit your learning needs. These solved papers help you understand exam patterns, improve answer writing skills, and boost confidence for upcoming exams.
IGNOU MCS-024 Solved Question Paper PDF

This section provides IGNOU MCS-024 Solved Question Paper PDF in both Hindi and English. These ignou solved question paper IGNOU Previous Year Question paper solved PDF include detailed answers to help you understand exam patterns and improve your preparation. You can also access IGNOU all Previous year Question Papers in one PDF for quick and effective revision before exams.
IGNOU MCS-024 Previous Year Solved Question Paper in Hindi
Q1. (a) एक क्लास और एक ऑब्जेक्ट को परिभाषित करें। क्लास के साथ डेटा मेम्बर और मेम्बर फंक्शन होने का क्या फायदा है? (b) एक्सेप्शन और एरर शब्दों को परिभाषित करें। एक्सेप्शन रूटीन हमें असामान्य प्रोग्राम समाप्ति से निपटने में कैसे मदद करते हैं? (c) प्रक्रियाओं की तुलना में थ्रेड्स ‘लाइटवेट’ कैसे होते हैं? अपने उत्तर को सही ठहराएं। (d) ऑब्जेक्ट-सीरियलाइज़ेशन किसी ऑब्जेक्ट की स्थिति को बचाने में कैसे मदद करता है? (e) उदाहरणों के साथ जावा में स्ट्रिंग-क्लास की प्रमुख विशेषताओं पर चर्चा करें। (f) एक एप्लेट और एप्लीकेशन प्रोग्राम के बीच उनके जीवन चक्र के साथ अंतरों को सूचीबद्ध करें। (g) कंटेनर और कंपोनेंट क्लास के संबंध में लेआउटमैनेजर की भूमिका की व्याख्या करें। (h) एक डायग्राम के साथ 3-टियर मॉडल में JDBC-आर्किटेक्चर की व्याख्या करें।
Ans.
(a) क्लास और ऑब्जेक्ट
एक क्लास (Class) ऑब्जेक्ट बनाने के लिए एक ब्लूप्रिंट या टेम्पलेट है। यह गुणों (डेटा मेम्बर्स) और व्यवहारों (मेम्बर फंक्शन्स) को परिभाषित करता है जो क्लास के सभी ऑब्जेक्ट्स के लिए सामान्य हैं। उदाहरण के लिए, एक `Car` क्लास में रंग, मॉडल जैसे गुण और `start()`, `stop()` जैसे व्यवहार हो सकते हैं।
एक ऑब्जेक्ट (Object) एक क्लास का एक इंस्टेंस है। यह एक वास्तविक-विश्व की इकाई है जिसमें स्थिति (state) और व्यवहार (behavior) होता है। जब एक क्लास से एक ऑब्जेक्ट बनाया जाता है, तो यह क्लास में परिभाषित डेटा मेम्बर्स के लिए मेमोरी आवंटित करता है। उदाहरण के लिए, `myCar` `Car` क्लास का एक ऑब्जेक्ट हो सकता है।
डेटा मेम्बर और मेम्बर फंक्शन के लाभ:
क्लास के भीतर डेटा मेम्बर्स (वेरिएबल्स) और मेम्बर फंक्शन्स (मेथड्स) को एक साथ बंडल करने की अवधारणा को एनकैप्सुलेशन (Encapsulation) कहा जाता है। इसके प्रमुख लाभ हैं:
- डेटा हाइडिंग (Data Hiding): यह क्लास के बाहर से डेटा तक सीधी पहुंच को प्रतिबंधित करता है, जिससे डेटा की अखंडता और सुरक्षा में सुधार होता है। डेटा को केवल क्लास के मेम्बर फंक्शन्स के माध्यम से ही एक्सेस और संशोधित किया जा सकता है।
- मॉड्यूलरिटी (Modularity): यह कोड को आत्मनिर्भर और प्रबंधनीय इकाइयों में व्यवस्थित करने में मदद करता है। प्रत्येक क्लास एक अलग इकाई के रूप में कार्य करती है, जिससे कोड को समझना, बनाए रखना और डीबग करना आसान हो जाता है।
- पुन: प्रयोज्यता (Reusability): एक बार परिभाषित की गई क्लास का उपयोग विभिन्न प्रोग्रामों में कई ऑब्जेक्ट बनाने के लिए किया जा सकता है, जिससे कोड पुन: प्रयोज्यता को बढ़ावा मिलता है।
(b) एक्सेप्शन और एरर
एक्सेप्शन (Exception): एक एक्सेप्शन एक ऐसी घटना है जो प्रोग्राम के निष्पादन के दौरान होती है और प्रोग्राम के निर्देशों के सामान्य प्रवाह को बाधित करती है। ये ऐसी स्थितियाँ हैं जिनसे एक अच्छी तरह से लिखा गया एप्लिकेशन उबरने का प्रयास कर सकता है। उदाहरण: `FileNotFoundException`, `ArithmeticException`।
एरर (Error): एक एरर एक गंभीर समस्या को इंगित करता है जिससे एक सामान्य एप्लिकेशन को उबरने का प्रयास नहीं करना चाहिए। ये समस्याएं असामान्य होती हैं और आमतौर पर JVM में या सिस्टम स्तर पर होती हैं, जैसे `OutOfMemoryError` या `StackOverflowError`।
एक्सेप्शन रूटीन की भूमिका:
एक्सेप्शन हैंडलिंग रूटीन, आमतौर पर `try-catch-finally` ब्लॉक का उपयोग करके कार्यान्वित किए जाते हैं, प्रोग्राम को असामान्य समाप्ति से बचाने में मदद करते हैं।
- जब एक `try` ब्लॉक के भीतर एक एक्सेप्शन होता है, तो प्रोग्राम का सामान्य प्रवाह बाधित हो जाता है और JVM संबंधित `catch` ब्लॉक की तलाश करता है।
- यदि एक मैचिंग `catch` ब्लॉक मिलता है, तो उसमें मौजूद कोड निष्पादित होता है। यह प्रोग्रामर को समस्या को संभालने, उपयोगकर्ता को सूचित करने, संसाधनों को साफ करने या वैकल्पिक कार्रवाई करने का अवसर देता है।
- यदि कोई एक्सेप्शन हैंडल नहीं किया जाता है, तो JVM डिफ़ॉल्ट एक्सेप्शन हैंडलर का उपयोग करता है, जो स्टैक ट्रेस प्रिंट करता है और प्रोग्राम को समाप्त कर देता है।
इस तंत्र का उपयोग करके, एक्सेप्शन रूटीन यह सुनिश्चित करते हैं कि प्रोग्राम अचानक क्रैश न हो, जिससे यह अधिक मजबूत और उपयोगकर्ता-अनुकूल बन जाता है। (c) थ्रेड्स बनाम प्रक्रियाएं
थ्रेड्स को प्रक्रियाओं (processes) की तुलना में ‘लाइटवेट’ माना जाता है क्योंकि वे अपने पैरेंट प्रक्रिया के संसाधनों को साझा करते हैं। औचित्य इस प्रकार है:
- साझा मेमोरी स्पेस (Shared Memory Space): एक प्रक्रिया के भीतर बनाए गए सभी थ्रेड्स समान मेमोरी स्पेस (डेटा और हीप सेगमेंट) साझा करते हैं। इसके विपरीत, प्रत्येक प्रक्रिया का अपना अलग मेमोरी स्पेस होता है। इससे थ्रेड्स के बीच संचार (inter-thread communication) बहुत तेज हो जाता है क्योंकि वे सीधे डेटा साझा कर सकते हैं।
- संसाधन ओवरहेड (Resource Overhead): एक नई प्रक्रिया बनाने में एक नया मेमोरी स्पेस, फाइल डिस्क्रिप्टर, और अन्य सिस्टम संसाधन आवंटित करना शामिल है, जो एक महंगा और समय लेने वाला ऑपरेशन है। एक थ्रेड बनाने में बहुत कम ओवरहेड होता है क्योंकि यह मौजूदा प्रक्रिया के संसाधनों का उपयोग करता है।
- संदर्भ स्विचिंग (Context Switching): थ्रेड्स के बीच स्विच करना प्रक्रियाओं के बीच स्विच करने की तुलना में तेज है। ऐसा इसलिए है क्योंकि थ्रेड स्विच के लिए केवल थ्रेड-विशिष्ट डेटा (जैसे प्रोग्राम काउंटर, स्टैक पॉइंटर) को सहेजना और पुनर्स्थापित करना आवश्यक है, जबकि प्रोसेस स्विच के लिए मेमोरी मैनेजमेंट यूनिट (MMU) जानकारी सहित बहुत अधिक संदर्भ को बदलना पड़ता है।
इन कारणों से, थ्रेड्स उन अनुप्रयोगों के लिए एक कुशल समाधान प्रदान करते हैं जिन्हें समवर्ती (concurrent) निष्पादन की आवश्यकता होती है, विशेष रूप से I/O-बाउंड या GUI-आधारित अनुप्रयोगों में। (d) ऑब्जेक्ट-सीरियलाइज़ेशन
ऑब्जेक्ट-सीरियलाइज़ेशन जावा में एक तंत्र है जिसके द्वारा किसी ऑब्जेक्ट की स्थिति को बाइट स्ट्रीम में परिवर्तित किया जा सकता है। यह बाइट स्ट्रीम तब एक फ़ाइल में सहेजी जा सकती है, नेटवर्क पर प्रेषित की जा सकती है, या डेटाबेस में संग्रहीत की जा सकती है। बाद में, इस बाइट स्ट्रीम का उपयोग ऑब्जेक्ट की स्थिति को फिर से बनाने के लिए किया जा सकता है, इस प्रक्रिया को डी-सीरियलाइज़ेशन (deserialization) कहा जाता है।
यह निम्नलिखित तरीकों से किसी ऑब्जेक्ट की स्थिति को बचाने में मदद करता है:
- दृढ़ता (Persistence): सीरियलाइज़ेशन किसी ऑब्जेक्ट की स्थिति को डिस्क पर सहेजने की अनुमति देता है। जब एप्लिकेशन को पुनरारंभ किया जाता है, तो ऑब्जेक्ट को उसकी पिछली स्थिति में पुनर्स्थापित किया जा सकता है, जिससे एप्लिकेशन को वहीं से फिर से शुरू करने में सक्षम बनाया जा सकता है जहां से उसने छोड़ा था।
- संचार (Communication): रिमोट मेथड इनवोकेशन (RMI) जैसे वितरित सिस्टम में, ऑब्जेक्ट्स को सीरियलाइज़ किया जाता है और नेटवर्क पर एक JVM से दूसरे में भेजा जाता है। प्राप्त करने वाला JVM ऑब्जेक्ट को डी-सीरियलाइज़ करता है और उसका उपयोग करता है।
जावा में एक ऑब्जेक्ट को सीरियलाइज़ करने योग्य बनाने के लिए, उसकी क्लास को `java.io.Serializable` इंटरफ़ेस को लागू करना होगा। यह एक मार्कर इंटरफ़ेस है, जिसका अर्थ है कि इसमें कोई मेथड नहीं है। वास्तविक सीरियलाइज़ेशन और डी-सीरियलाइज़ेशन `ObjectOutputStream` और `ObjectInputStream` क्लास द्वारा किया जाता है। (e) जावा में स्ट्रिंग-क्लास की विशेषताएं
जावा में `java.lang.String` क्लास की कई प्रमुख विशेषताएं हैं:
- अपरिवर्तनीयता (Immutability): स्ट्रिंग ऑब्जेक्ट अपरिवर्तनीय होते हैं। एक बार जब एक स्ट्रिंग ऑब्जेक्ट बना दिया जाता है, तो उसकी सामग्री को बदला नहीं जा सकता है। कोई भी ऑपरेशन जो एक स्ट्रिंग को संशोधित करता प्रतीत होता है, जैसे `concat()` या `substring()`, वास्तव में एक नया स्ट्रिंग ऑब्जेक्ट बनाता है। उदाहरण: `String s = “Java”; s.concat(” World”);` `s` अभी भी “Java” को संदर्भित करेगा। परिणाम को पकड़ने के लिए, आपको `s = s.concat(” World”);` करना होगा, जो `s` को एक नए ऑब्जेक्ट को संदर्भित करने के लिए बनाता है।
- स्ट्रिंग पूल (String Pool): जावा मेमोरी बचाने के लिए हीप में एक विशेष क्षेत्र में एक “स्ट्रिंग कॉन्स्टेंट पूल” बनाए रखता है। जब एक स्ट्रिंग लिटरल बनाया जाता है, तो JVM पहले पूल की जाँच करता है। यदि स्ट्रिंग पहले से मौजूद है, तो नए ऑब्जेक्ट बनाने के बजाय मौजूदा इंस्टेंस का एक संदर्भ लौटाया जाता है।
- शाब्दिक निर्माण (Literal Creation): स्ट्रिंग्स को `new` कीवर्ड का उपयोग किए बिना सीधे बनाया जा सकता है, जैसे `String name = “John”;`। यह स्ट्रिंग पूल तंत्र का उपयोग करता है।
- रिच एपीआई (Rich API): `String` क्लास स्ट्रिंग मैनिपुलेशन के लिए बड़ी संख्या में उपयोगी मेथड प्रदान करती है, जैसे `length()`, `charAt(int index)`, `substring(int beginIndex, int endIndex)`, `equals(Object anObject)`, `equalsIgnoreCase(String anotherString)`, `trim()`, और `split(String regex)`।
(f) एप्लेट बनाम एप्लीकेशन प्रोग्राम
एप्लेट और एप्लीकेशन जावा प्रोग्राम लिखने के दो अलग-अलग तरीके हैं। उनके बीच मुख्य अंतर नीचे दिए गए हैं:
- निष्पादन (Execution):
- एप्लीकेशन: ये स्टैंडअलोन प्रोग्राम हैं जो JVM द्वारा सीधे निष्पादित होते हैं। उन्हें एक `public static void main(String[] args)` मेथड की आवश्यकता होती है जो निष्पादन का प्रवेश बिंदु है।
- एप्लेट: ये छोटे जावा प्रोग्राम हैं जो एक वेब ब्राउज़र के भीतर या एक एप्लेट व्यूअर टूल में चलने के लिए डिज़ाइन किए गए हैं। उनमें `main()` मेथड नहीं होता है।
- जीवन चक्र (Life Cycle):
- एप्लीकेशन: इनका एक सरल जीवन चक्र होता है, जो `main()` मेथड से शुरू होता है और जब `main()` समाप्त होता है या `System.exit()` कॉल किया जाता है तो समाप्त होता है।
- एप्लेट: इनका एक जटिल, ईवेंट-संचालित जीवन चक्र होता है जिसे ब्राउज़र द्वारा प्रबंधित किया जाता है। प्रमुख मेथड हैं: `init()`, `start()`, `paint()`, `stop()`, और `destroy()`।
- सुरक्षा (Security):
- एप्लीकेशन: डिफ़ॉल्ट रूप से, इनके पास स्थानीय सिस्टम के संसाधनों (जैसे फाइलें, नेटवर्क कनेक्शन) तक पूर्ण पहुंच होती है।
- एप्लेट: ये एक प्रतिबंधित वातावरण में चलते हैं जिसे “सैंडबॉक्स” कहा जाता है। यह उन्हें स्थानीय फाइल सिस्टम तक पहुंचने या नेटवर्क कनेक्शन बनाने जैसे खतरनाक ऑपरेशन करने से रोकता है।
- आवश्यकताएँ (Requirements):
- एप्लीकेशन: इन्हें चलाने के लिए केवल JRE की आवश्यकता होती है।
- एप्लेट: इन्हें चलाने के लिए जावा-सक्षम वेब ब्राउज़र या एप्लेट व्यूअर की आवश्यकता होती है।
(g) लेआउटमैनेजर की भूमिका
AWT (Abstract Window Toolkit) और स्विंग में, một `LayoutManager` एक इंटरफ़ेस है जो एक कंटेनर के भीतर कंपोनेंट्स की स्थिति और आकार का निर्धारण करने के लिए जिम्मेदार है। एक `Container` (जैसे `JFrame`, `JPanel`) एक या एक से अधिक `Component` (जैसे `JButton`, `JTextField`) ऑब्जेक्ट्स को रखता है।
लेआउटमैनेजर की भूमिका महत्वपूर्ण है क्योंकि यह निम्नलिखित कार्य करता है:
- प्लेटफ़ॉर्म स्वतंत्रता (Platform Independence): यह GUI के लेआउट को प्लेटफ़ॉर्म-विशिष्ट विवरणों से अलग करता है। विभिन्न ऑपरेटिंग सिस्टम में अलग-अलग फॉन्ट साइज, स्क्रीन रिज़ॉल्यूशन और विंडो डेकोरेशन हो सकते हैं। लेआउटमैनेजर स्वचालित रूप से इन भिन्नताओं को समायोजित करता है, यह सुनिश्चित करता है कि लेआउट विभिन्न प्लेटफार्मों पर प्रयोग करने योग्य बना रहे।
- स्वचालित पुन: आकार देना (Automatic Resizing): जब कंटेनर का आकार बदला जाता है, तो लेआउटमैनेजर स्वचालित रूप से भीतर के कंपोनेंट्स को अपनी नीति के अनुसार पुन: व्यवस्थित और पुन: आकार देता है। यह निरपेक्ष स्थिति (absolute positioning) के विपरीत है, जहां कंपोनेंट्स अपने आकार और स्थिति को बनाए रखते हैं, जिससे कंटेनर का आकार बदलने पर अजीब लेआउट हो सकता है।
- उपयोग में आसानी (Ease of Use): डेवलपर्स को प्रत्येक कंपोनेंट के लिए पिक्सेल-सटीक निर्देशांक की गणना करने की आवश्यकता नहीं है। इसके बजाय, वे एक उपयुक्त लेआउटमैनेजर (जैसे `FlowLayout`, `BorderLayout`, `GridLayout`, `GridBagLayout`) चुन सकते हैं और कंटेनर में कंपोनेंट्स जोड़ सकते हैं, और मैनेजर बाकी का ध्यान रखता है।
संक्षेप में, `LayoutManager` कंटेनर और कंपोनेंट क्लास के बीच एक मध्यस्थ के रूप में कार्य करता है, जो गतिशील, मजबूत और क्रॉस-प्लेटफ़ॉर्म GUI लेआउट के निर्माण को सरल बनाता है। (h) 3-टियर मॉडल में JDBC-आर्किटेक्चर
3-टियर आर्किटेक्चर एक क्लाइंट-सर्वर आर्किटेक्चर है जिसमें प्रेजेंटेशन, एप्लिकेशन प्रोसेसिंग और डेटा मैनेजमेंट तार्किक रूप से अलग-अलग प्रक्रियाएं हैं। JDBC (Java Database Connectivity) का उपयोग अक्सर इस मॉडल के एप्लिकेशन टियर में डेटाबेस के साथ संचार करने के लिए किया जाता है।
तीन टियर हैं:
- टियर 1: क्लाइंट टियर (प्रेजेंटेशन लेयर)
- यह यूजर इंटरफेस है। यह एक वेब ब्राउज़र हो सकता है जो HTML पेज प्रदर्शित करता है, या एक डेस्कटॉप एप्लिकेशन जो स्विंग या AWT का उपयोग करके बनाया गया है।
- इसका मुख्य काम उपयोगकर्ता से इनपुट लेना और परिणामों को प्रदर्शित करना है। यह सीधे डेटाबेस से इंटरैक्ट नहीं करता है।
- टियर 2: एप्लिकेशन सर्वर टियर (बिजनेस लॉजिक लेयर)
- यह आर्किटेक्चर का “मध्य” हिस्सा है। यह क्लाइंट से अनुरोध प्राप्त करता है।
- यह बिजनेस लॉजिक को लागू करता है और क्लाइंट से प्राप्त डेटा को संसाधित करता है।
- यह टियर डेटाबेस के साथ संचार करने के लिए JDBC API का उपयोग करता है। यह JDBC ड्राइवर के माध्यम से SQL क्वेरी भेजता है और डेटाबेस से परिणाम प्राप्त करता है।
- यह परिणामों को संसाधित करता है और उन्हें क्लाइंट टियर को वापस भेजता है (अक्सर HTML, XML, या JSON प्रारूप में)।
- टियर 3: डेटा सोर्स टियर (डेटा लेयर)
- यह वास्तविक डेटाबेस मैनेजमेंट सिस्टम (DBMS) जैसे MySQL, Oracle, या PostgreSQL है।
- इसका काम डेटा को स्टोर और पुनर्प्राप्त करना है। यह एप्लिकेशन सर्वर से SQL कमांड प्राप्त करता है, उन्हें निष्पादित करता है, और डेटा वापस करता है।
डायग्राम विवरण:
(क्लाइंट) — [HTTP/नेटवर्क] —> (एप्लिकेशन सर्वर) — [JDBC] —> (डेटाबेस)
फ्लो:
- उपयोगकर्ता क्लाइंट टियर पर इंटरैक्ट करता है (जैसे, एक फॉर्म सबमिट करता है)।
- क्लाइंट टियर एप्लिकेशन सर्वर टियर को एक अनुरोध भेजता है।
- एप्लिकेशन सर्वर बिजनेस लॉजिक को निष्पादित करता है और JDBC का उपयोग करके डेटाबेस टियर पर एक क्वेरी भेजता है।
- डेटाबेस क्वेरी को संसाधित करता है और परिणाम एप्लिकेशन सर्वर को वापस करता है।
- एप्लिकेशन सर्वर परिणामों को प्रारूपित करता है और उन्हें क्लाइंट टियर पर वापस भेजता है, जहां वे उपयोगकर्ता को प्रस्तुत किए जाते हैं।
यह पृथक्करण मापनीयता, लचीलापन और सुरक्षा में सुधार करता है।
Q2. (a) जावा में मेथड्स की ओवरलोडिंग की अवधारणा को एक उदाहरण के साथ समझाएं। (b) जावा भाषा में गारबेज कलेक्शन प्रक्रिया की व्याख्या करें। अन्य भाषाओं की तुलना में इसके प्रमुख लाभ क्या हैं?
Ans.
(a) जावा में मेथड ओवरलोडिंग
मेथड ओवरलोडिंग जावा में संकलन-समय बहुरूपता (compile-time polymorphism) का एक रूप है। यह एक ही क्लास में एक ही नाम के कई मेथड रखने की अनुमति देता है, जब तक कि उनके पैरामीटर अलग-अलग हों। कंपाइलर मेथड के नाम और पास किए गए तर्कों की संख्या और प्रकार के आधार पर यह निर्धारित करता है कि कौन सा मेथड कॉल करना है।
मेथड सिग्नेचर (नाम और पैरामीटर सूची) अलग होना चाहिए। पैरामीटर सूची में अंतर निम्नलिखित तरीकों से हो सकता है:
- पैरामीटर्स की संख्या में अंतर।
- पैरामीटर्स के डेटा प्रकार में अंतर।
- पैरामीटर्स के प्रकारों के क्रम में अंतर।
ध्यान दें: मेथड ओवरलोडिंग केवल मेथड के रिटर्न प्रकार को बदलकर प्राप्त नहीं किया जा सकता है।
लाभ:
- यह प्रोग्राम की पठनीयता (readability) को बढ़ाता है।
- यह कोड की पुन: प्रयोज्यता (reusability) में सुधार करता है।
- यह लचीलापन प्रदान करता है, जिससे एक ही ऑपरेशन को विभिन्न प्रकार के डेटा पर किया जा सकता है।
उदाहरण:
नीचे दिए गए उदाहरण में, `Calculator` क्लास में एक `add` मेथड है जिसे विभिन्न प्रकार के तर्कों के साथ ओवरलोड किया गया है।
class Calculator { // दो पूर्णांकों को जोड़ने के लिए मेथड public int add(int a, int b) { System.out.println(“दो int जोड़ने के लिए मेथड को कॉल किया गया”); return a + b; } // तीन पूर्णांकों को जोड़ने के लिए मेथड public int add(int a, int b, int c) { System.out.println(“तीन int जोड़ने के लिए मेथड को कॉल किया गया”); return a + b + c; } // दो डबल्स को जोड़ने के लिए मेथड public double add(double a, double b) { System.out.println(“दो double जोड़ने के लिए मेथड को कॉल किया गया”); return a + b; } } public class OverloadingExample { public static void main(String[] args) { Calculator calc = new Calculator(); // पहले मेथड को कॉल करता है (int, int) System.out.println(“Sum of 2 and 3 is: ” + calc.add(2, 3)); // दूसरे मेथड को कॉल करता है (int, int, int) System.out.println(“Sum of 2, 3, and 4 is: ” + calc.add(2, 3, 4)); // तीसरे मेथड को कॉल करता है (double, double) System.out.println(“Sum of 2.5 and 3.5 is: ” + calc.add(2.5, 3.5)); } }
इस उदाहरण में, `calc.add(…)` के लिए प्रत्येक कॉल पर, जावा कंपाइलर तर्कों के प्रकार और संख्या के आधार पर सही `add` मेथड का चयन करता है। (b) जावा में गारबेज कलेक्शन
गारबेज कलेक्शन (GC) जावा वर्चुअल मशीन (JVM) द्वारा प्रदान की जाने वाली स्वचालित मेमोरी प्रबंधन (automatic memory management) की प्रक्रिया है। इसका मुख्य उद्देश्य उन ऑब्जेक्ट्स द्वारा कब्जा की गई मेमोरी को पुनः प्राप्त करना है जो अब प्रोग्राम द्वारा उपयोग में नहीं हैं या संदर्भित नहीं हैं।
गारबेज कलेक्शन प्रक्रिया:
प्रक्रिया में आम तौर पर दो चरण होते हैं:
- पहचान (Identification): गारबेज कलेक्टर उन ऑब्जेक्ट्स की पहचान करता है जो अभी भी उपयोग में हैं और जो नहीं हैं। एक ऑब्जेक्ट को “गारबेज” माना जाता है यदि वह अब किसी भी सक्रिय थ्रेड या किसी अन्य जीवित ऑब्जेक्ट से पहुंच योग्य नहीं है। यह आमतौर पर “पहुंच क्षमता” (reachability) का विश्लेषण करके किया जाता है, जो प्रोग्राम के रूट (जैसे, स्टैक पर स्थानीय चर) से शुरू होता है और उन सभी ऑब्जेक्ट्स को चिह्नित करता है जिन्हें वहां से पहुंचा जा सकता है।
- पुनर्प्राप्ति (Reclamation): पहचान चरण के बाद, गारबेज कलेक्टर उन सभी अचिह्नित (unmarked) या गैर-पहुंच योग्य (unreachable) ऑब्जेक्ट्स द्वारा कब्जा की गई मेमोरी को हटा देता है। यह मेमोरी फिर हीप (heap) में वापस कर दी जाती है और भविष्य के ऑब्जेक्ट आवंटन के लिए उपलब्ध हो जाती है।
JVM में विभिन्न गारबेज कलेक्शन एल्गोरिदम (जैसे, मार्क-एंड-स्वीप, कॉपीइंग, जनरेशनल) होते हैं, और डेवलपर प्रदर्शन ट्यूनिंग के लिए विभिन्न कलेक्टर चुन सकते हैं।
अन्य भाषाओं की तुलना में लाभ:
C और C++ जैसी भाषाओं में, प्रोग्रामर को `malloc`/`free` या `new`/`delete` का उपयोग करके मैन्युअल रूप से मेमोरी आवंटित और डी-आवंटित करनी पड़ती है। जावा की स्वचालित गारबेज कलेक्शन कई महत्वपूर्ण लाभ प्रदान करती है:
- मेमोरी लीक की रोकथाम (Prevents Memory Leaks): मैन्युअल मेमोरी प्रबंधन में, यदि कोई प्रोग्रामर किसी ऑब्जेक्ट को डी-आवंटित करना भूल जाता है जिसकी अब आवश्यकता नहीं है, तो यह मेमोरी लीक का कारण बनता है। GC स्वचालित रूप से अप्रयुक्त ऑब्जेक्ट्स को साफ करके इस सामान्य बग को समाप्त करता है।
- डैंगलिंग पॉइंटर्स से बचाव (Avoids Dangling Pointers): डैंगलिंग पॉइंटर एक पॉइंटर होता है जो एक मेमोरी स्थान को संदर्भित करता है जिसे पहले ही मुक्त कर दिया गया है। ऐसे पॉइंटर का उपयोग करने से अप्रत्याशित व्यवहार या क्रैश हो सकता है। चूंकि जावा में कोई स्पष्ट डी-आवंटन नहीं है, इसलिए डैंगलिंग पॉइंटर्स की समस्या समाप्त हो जाती है।
- सरलीकृत विकास (Simplified Development): प्रोग्रामर्स को जटिल मेमोरी प्रबंधन कोड लिखने और डीबग करने की आवश्यकता नहीं होती है। यह उन्हें एप्लिकेशन के मुख्य तर्क पर ध्यान केंद्रित करने की अनुमति देता है, जिससे विकास का समय कम होता है और बग की संभावना कम हो जाती है।
- बढ़ी हुई सुरक्षा और मजबूती (Increased Safety and Robustness): मेमोरी प्रबंधन त्रुटियों को स्वचालित रूप से संभालकर, GC जावा अनुप्रयोगों को अधिक स्थिर और सुरक्षित बनाने में मदद करता है।
Q3. (a) उपयुक्त उदाहरणों के साथ जावा में चेक्ड और अनचेक्ड एक्सेप्शन के बीच अंतर करें। (b) एक फाइल I/O जावा प्रोग्राम लिखें जो उपयोगकर्ता से टेक्स्ट की एक लाइन पढ़ता है और इसे ‘Myfile.txt’ नामक फाइल में लिखता है। इसके अलावा, प्रोग्राम ‘Myfile.txt’ फाइल को पढ़ता है और इसकी सामग्री को आउटपुट स्क्रीन पर प्रदर्शित करता है।
Ans.
(a) चेक्ड बनाम अनचेक्ड एक्सेप्शन
जावा में, एक्सेप्शन को दो मुख्य श्रेणियों में बांटा गया है: चेक्ड एक्सेप्शन और अनचेक्ड एक्सेप्शन। यह वर्गीकरण इस बात पर आधारित है कि क्या कंपाइलर यह जाँचता है कि प्रोग्रामर ने एक्सेप्शन को हैंडल किया है या नहीं।
चेक्ड एक्सेप्शन (Checked Exceptions):
- ये वे एक्सेप्शन हैं जिन्हें कंपाइलर संकलन-समय (compile-time) पर जाँचता है।
- यदि कोई मेथड चेक्ड एक्सेप्शन फेंक सकता है, तो उसे या तो इसे `try-catch` ब्लॉक का उपयोग करके हैंडल करना चाहिए या इसे अपने सिग्नेचर में `throws` कीवर्ड का उपयोग करके घोषित करना चाहिए।
- ये आमतौर पर प्रोग्राम के नियंत्रण से बाहर की स्थितियों का प्रतिनिधित्व करते हैं, जैसे कि नेटवर्क या फ़ाइल सिस्टम के साथ समस्याएं। एक अच्छी तरह से लिखा गया एप्लिकेशन इनसे उबर सकता है।
- ये `java.lang.Exception` के प्रत्यक्ष उपवर्ग हैं लेकिन `java.lang.RuntimeException` के उपवर्ग नहीं हैं।
- उदाहरण: `IOException`, `SQLException`, `FileNotFoundException`, `ClassNotFoundException`।
उदाहरण (चेक्ड एक्सेप्शन):
import java.io.File; import java.io.FileReader; import java.io.FileNotFoundException; public class CheckedExceptionExample { public static void main(String[] args) { File file = new File(“non_existent_file.txt”); try { // यह लाइन FileNotFoundException फेंक सकती है, जो एक चेक्ड एक्सेप्शन है। FileReader fr = new FileReader(file); } catch (FileNotFoundException e) { // कंपाइलर हमें इसे पकड़ने या घोषित करने के लिए मजबूर करता है। System.out.println(“File not found: ” + e.getMessage()); } } }
अनचेक्ड एक्सेप्शन (Unchecked Exceptions):
- ये वे एक्सेप्शन हैं जिन्हें कंपाइलर संकलन-समय पर नहीं जाँचता है।
- एक मेथड को इन एक्सेप्शन को हैंडल करने या घोषित करने की आवश्यकता नहीं होती है।
- ये आमतौर पर प्रोग्रामिंग त्रुटियों या बग्स का परिणाम होते हैं, जैसे कि अमान्य तर्क, अशक्त पॉइंटर्स, या एरे सीमा से बाहर पहुंचना।
- ये `java.lang.RuntimeException` और उसके उपवर्ग हैं। `Error` और उसके उपवर्ग भी अनचेक्ड होते हैं।
- उदाहरण: `NullPointerException`, `ArrayIndexOutOfBoundsException`, `ArithmeticException`, `IllegalArgumentException`।
उदाहरण (अनचेक्ड एक्सेप्शन):
public class UncheckedExceptionExample { public static void main(String[] args) { String text = null; try { // यह लाइन NullPointerException फेंकेगी। // कंपाइलर हमें इसे पकड़ने के लिए मजबूर नहीं करता है। System.out.println(text.length()); } catch (NullPointerException e) { // इसे पकड़ना एक अच्छा अभ्यास है, लेकिन अनिवार्य नहीं है। System.out.println(“Caught NullPointerException: The string is null.”); }
int[] arr = {1, 2, 3}; // यह ArrayIndexOutOfBoundsException फेंकेगा। // System.out.println(arr[3]); } }
संक्षेप में, मुख्य अंतर यह है कि चेक्ड एक्सेप्शन को संकलन-समय पर अनिवार्य रूप से हैंडल किया जाना चाहिए, जबकि अनचेक्ड एक्सेप्शन को नहीं। (b) फाइल I/O जावा प्रोग्राम
यह जावा प्रोग्राम उपयोगकर्ता से इनपुट लेता है, उसे ‘Myfile.txt’ में लिखता है, और फिर उस फ़ाइल की सामग्री को पढ़कर कंसोल पर प्रदर्शित करता है। यह I/O संचालन के लिए `try-with-resources` स्टेटमेंट का उपयोग करता है, जो यह सुनिश्चित करता है कि संसाधन (जैसे फ़ाइल स्ट्रीम) स्वचालित रूप से बंद हो जाएं।
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; public class FileIOProgram { public static void main(String[] args) { String fileName = “Myfile.txt”; // चरण 1: उपयोगकर्ता से टेक्स्ट की एक लाइन पढ़ें और इसे फ़ाइल में लिखें writeToFile(fileName); // चरण 2: फ़ाइल पढ़ें और इसकी सामग्री को स्क्रीन पर प्रदर्शित करें readFromFile(fileName); } /
उपयोगकर्ता से इनपुट पढ़ता है और इसे निर्दिष्ट फ़ाइल में लिखता है।
*/ private static void writeToFile(String fileName) { // try-with-resources यह सुनिश्चित करेगा कि writer और reader स्वचालित रूप से बंद हो जाएं try ( // कंसोल से पढ़ने के लिए BufferedReader बनाएं BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
// फ़ाइल में लिखने के लिए BufferedWriter बनाएं BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)) ) { System.out.print(“Enter a line of text to write to the file: “);
// उपयोगकर्ता से टेक्स्ट की एक लाइन पढ़ें String textFromUser = consoleReader.readLine();
// टेक्स्ट को फ़ाइल में लिखें writer.write(textFromUser);
// एक नई लाइन जोड़ें (वैकल्पिक, लेकिन अच्छी प्रथा) writer.newLine();
System.out.println(“Successfully wrote to the file ‘” + fileName + “‘.”);
} catch (IOException e) { System.err.println(“An error occurred during file writing: ” + e.getMessage()); e.printStackTrace(); } } /
निर्दिष्ट फ़ाइल को पढ़ता है और इसकी सामग्री को कंसोल पर प्रदर्शित करता है।
*/ private static void readFromFile(String fileName) { System.out.println(“\nReading content from the file ‘” + fileName + “‘:”);
// try-with-resources यह सुनिश्चित करेगा कि reader स्वचालित रूप से बंद हो जाए try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) { String currentLine; // फ़ाइल को लाइन-दर-लाइन पढ़ें जब तक कि अंत न हो जाए while ((currentLine = reader.readLine()) != null) { System.out.println(currentLine); } } catch (IOException e) { System.err.println(“An error occurred during file reading: ” + e.getMessage()); e.printStackTrace(); } } }
कैसे चलाएं: 1. कोड को `FileIOProgram.java` के रूप में सहेजें। 2. इसे `javac FileIOProgram.java` का उपयोग करके संकलित करें। 3. इसे `java FileIOProgram` का उपयोग करके चलाएं। 4. प्रोग्राम आपको टेक्स्ट की एक लाइन दर्ज करने के लिए संकेत देगा। कुछ टेक्स्ट टाइप करें और एंटर दबाएं। 5. प्रोग्राम पुष्टि करेगा कि उसने फ़ाइल में लिखा है, और फिर उसी फ़ाइल से सामग्री को वापस पढ़कर आपको दिखाएगा।
Q4. (a) एक डायग्राम के साथ सभी फंक्शन्स/मेथड्स के साथ एक थ्रेड के जीवन चक्र की व्याख्या करें। थ्रेड प्राथमिकता की भी व्याख्या करें। (b) प्रिंटस्ट्रीम क्लास के विशेष संदर्भ में कैरेक्टर स्ट्रीम क्लास की विशेषताओं की व्याख्या करें।
Ans.
(a) थ्रेड का जीवन चक्र और प्राथमिकता
जावा में एक थ्रेड अपने जीवनकाल में विभिन्न अवस्थाओं से गुजरता है। थ्रेड के जीवन चक्र को इन अवस्थाओं और उनके बीच संक्रमण द्वारा परिभाषित किया गया है।
थ्रेड की अवस्थाएँ:
- New (नई): जब एक थ्रेड ऑब्जेक्ट का एक नया इंस्टेंस `new Thread(…)` का उपयोग करके बनाया जाता है, तो यह नई अवस्था में होता है। इस बिंदु पर, थ्रेड अभी तक जीवित नहीं है और सिस्टम ने इसके लिए कोई संसाधन आवंटित नहीं किया है।
- Runnable (चलाने योग्य): जब थ्रेड पर `start()` मेथड को कॉल किया जाता है, तो यह नई अवस्था से चलाने योग्य अवस्था में चला जाता है। इस अवस्था में एक थ्रेड निष्पादन के लिए पात्र है, लेकिन यह थ्रेड शेड्यूलर द्वारा सीपीयू समय आवंटित किए जाने की प्रतीक्षा कर रहा है। इसमें “रनिंग” और “रेडी” दोनों उप-अवस्थाएं शामिल हैं।
- Blocked/Waiting (अवरुद्ध/प्रतीक्षारत): एक थ्रेड इस अवस्था में प्रवेश करता है जब वह अस्थायी रूप से निष्क्रिय होता है। एक थ्रेड कई कारणों से अवरुद्ध हो सकता है:
- यह `sleep(milliseconds)` मेथड के कॉल के कारण एक निर्दिष्ट समय के लिए निलंबित है।
- यह एक I/O ऑपरेशन के पूरा होने की प्रतीक्षा कर रहा है।
- यह एक `synchronized` ब्लॉक/मेथड में प्रवेश करने की कोशिश कर रहा है जो वर्तमान में दूसरे थ्रेड द्वारा लॉक है।
- यह `wait()` मेथड को कॉल करने के कारण प्रतीक्षा कर रहा है। यह तब तक प्रतीक्षा करता है जब तक कोई अन्य थ्रेड उसी ऑब्जेक्ट पर `notify()` या `notifyAll()` को कॉल नहीं करता।
- यह `join()` मेथड को कॉल करने के कारण दूसरे थ्रेड के समाप्त होने की प्रतीक्षा कर रहा है।
- Terminated (समाप्त): एक थ्रेड इस अवस्था में प्रवेश करता है जब वह अपना कार्य पूरा कर लेता है। यह तब होता है जब उसका `run()` मेथड सामान्य रूप से बाहर निकल जाता है या जब कोई अनकॉट एक्सेप्शन के कारण यह अचानक समाप्त हो जाता है। एक बार समाप्त हो जाने के बाद, एक थ्रेड को फिर से शुरू नहीं किया जा सकता है।
जीवन चक्र का डायग्राम:
[ New ] — `start()` –> [ Runnable ] <–> [ Running ]
[ Running ] — I/O, `sleep()`, `wait()`, `join()` –> [ Blocked/Waiting ]
[ Blocked/Waiting ] — I/O complete, `sleep()` timeout, `notify()`, joined thread dies –> [ Runnable ]
[ Running ] — `run()` completes –> [ Terminated ]
थ्रेड प्राथमिकता (Thread Priority):
जावा में प्रत्येक थ्रेड की एक प्राथमिकता होती है। प्राथमिकताएं 1 और 10 के बीच की संख्याएं होती हैं। एक उच्च संख्या का अर्थ उच्च प्राथमिकता है। थ्रेड शेड्यूलर इन प्राथमिकताओं का उपयोग यह तय करने के लिए करता है कि कौन सा थ्रेड अगले निष्पादित किया जाना है।
- `Thread.MIN_PRIORITY` (मान 1)
- `Thread.NORM_PRIORITY` (मान 5, डिफ़ॉल्ट)
- `Thread.MAX_PRIORITY` (मान 10)
सिद्धांत रूप में, जब कई थ्रेड चलाने के लिए तैयार होते हैं, तो उच्चतम प्राथमिकता वाले थ्रेड को सीपीयू समय मिलने की संभावना सबसे अधिक होती है। हालांकि, थ्रेड शेड्यूलिंग का सटीक व्यवहार JVM और अंतर्निहित ऑपरेटिंग सिस्टम पर अत्यधिक निर्भर है। इसलिए, प्रोग्राम की शुद्धता के लिए थ्रेड प्राथमिकता पर निर्भर रहना उचित नहीं है; इसे केवल प्रदर्शन को प्रभावित करने के लिए एक संकेत के रूप में इस्तेमाल किया जाना चाहिए। आप `setPriority(int)` मेथड का उपयोग करके थ्रेड की प्राथमिकता सेट कर सकते हैं और `getPriority()` का उपयोग करके इसे प्राप्त कर सकते हैं। (b) कैरेक्टर स्ट्रीम क्लास और प्रिंटस्ट्रीम
जावा I/O API को दो मुख्य श्रेणियों में बांटा गया है: बाइट स्ट्रीम और कैरेक्टर स्ट्रीम।
कैरेक्टर स्ट्रीम क्लास की विशेषताएं:
- उद्देश्य: कैरेक्टर स्ट्रीम क्लास विशेष रूप से टेक्स्टुअल डेटा (कैरेक्टर्स) को पढ़ने और लिखने के लिए डिज़ाइन की गई हैं। वे आंतरिक रूप से 16-बिट यूनिकोड कैरेक्टर्स को संभालते हैं, जो उन्हें अंतर्राष्ट्रीयकरण (internationalization) के लिए उपयुक्त बनाता है।
- बेस क्लास: सभी कैरेक्टर इनपुट स्ट्रीम `java.io.Reader` एब्स्ट्रैक्ट क्लास से प्राप्त होती हैं, और सभी कैरेक्टर आउटपुट स्ट्रीम `java.io.Writer` एब्स्ट्रैक्ट क्लास से प्राप्त होती हैं।
- एनकोडिंग: वे कैरेक्टर्स और बाइट्स के बीच स्वचालित रूप से अनुवाद करते हैं, एक निर्दिष्ट या डिफ़ॉल्ट कैरेक्टर सेट (जैसे UTF-8, ISO-8859-1) का उपयोग करते हैं। यह उन्हें टेक्स्ट फ़ाइलों को संभालने के लिए बाइट स्ट्रीम की तुलना में अधिक सुविधाजनक और विश्वसनीय बनाता है।
- उदाहरण: `FileReader`, `FileWriter`, `BufferedReader`, `BufferedWriter`, `PrintWriter`।
बाइट स्ट्रीम, इसके विपरीत, रॉ 8-बिट बाइट्स के साथ काम करती हैं और बाइनरी डेटा (जैसे इमेज, ऑडियो) या निम्न-स्तरीय I/O के लिए उपयुक्त हैं।
`PrintStream` क्लास पर विशेष संदर्भ:
हालांकि `PrintStream` का उपयोग अक्सर टेक्स्ट आउटपुट के लिए किया जाता है (सबसे प्रसिद्ध उदाहरण `System.out` है, जो एक `PrintStream` है), यह एक ऐतिहासिक विसंगति है और वास्तव में एक बाइट स्ट्रीम है, कैरेक्टर स्ट्रीम नहीं । यह `java.io.OutputStream` का एक उपवर्ग है।
`PrintStream` की मुख्य विशेषताएं हैं:
- बाइट-ओरिएंटेड: यह एक आउटपुट स्ट्रीम है जो बाइट्स लिखती है। जब आप इसे कैरेक्टर या स्ट्रिंग्स पास करते हैं, तो यह उन्हें डिफ़ॉल्ट प्लेटफ़ॉर्म एनकोडिंग का उपयोग करके बाइट्स में परिवर्तित करता है। यह विभिन्न प्लेटफार्मों पर अप्रत्याशित व्यवहार का कारण बन सकता है यदि डिफ़ॉल्ट एनकोडिंग मेल नहीं खाती है।
- स्वरूपित आउटपुट: इसका मुख्य लाभ `print()`, `println()`, और `printf()` जैसे सुविधाजनक मेथड प्रदान करना है जो विभिन्न आदिम डेटा प्रकारों और ऑब्जेक्ट्स को एक पठनीय टेक्स्ट प्रारूप में परिवर्तित करते हैं।
- कोई `IOException` नहीं फेंकता: `PrintStream` को सुविधा के लिए डिज़ाइन किया गया है। यह अपने किसी भी सार्वजनिक मेथड से `IOException` नहीं फेंकता है। इसके बजाय, यदि कोई I/O त्रुटि होती है, तो यह एक आंतरिक त्रुटि ध्वज सेट करता है। आप `checkError()` मेथड को कॉल करके इस ध्वज की स्थिति की जांच कर सकते हैं। यह कंसोल आउटपुट के लिए सुविधाजनक है जहां एक I/O त्रुटि की संभावना नहीं है, लेकिन विश्वसनीय फ़ाइल या नेटवर्क लेखन के लिए इसे अनुपयुक्त बनाता है।
- ऑटो-फ्लशिंग: `PrintStream` को एक `boolean` ध्वज के साथ बनाया जा सकता है जो ऑटो-फ्लशिंग को सक्षम करता है। यदि `true` है, तो जब भी एक नई लाइन (`\n`) वर्ण लिखा जाता है या `println()` मेथड में से एक को कॉल किया जाता है, तो बफर स्वचालित रूप से फ्लश हो जाएगा।
`PrintWriter` के साथ तुलना:
`PrintWriter` कैरेक्टर-ओरिएंटेड समकक्ष है। यह `Writer` का एक उपवर्ग है और `PrintStream` के समान स्वरूपित आउटपुट मेथड प्रदान करता है। टेक्स्ट फ़ाइलों को लिखने के लिए, `PrintWriter` का उपयोग `PrintStream` पर पसंद किया जाता है क्योंकि यह कैरेक्टर एनकोडिंग को सही ढंग से संभालता है और प्लेटफ़ॉर्म-स्वतंत्र है।
Q5. (a) निम्नलिखित को प्रदर्शित करने के लिए एक जावा प्रोग्राम लिखें: (i) ‘Yes’ और ‘No’ लेबल वाले बटन। (ii) ‘Name’ लेबल के साथ नाम दर्ज करने के लिए टेक्स्ट फ़ील्ड। (iii) ‘Submit’ टेक्स्ट वाला सबमिट बटन। (b) java.net पैकेज के तरीकों के साथ जावा में TCP/IP प्रोग्रामिंग की अवधारणा की व्याख्या करें।
Ans.
(a) जावा स्विंग GUI प्रोग्राम
यह जावा प्रोग्राम स्विंग फ्रेमवर्क का उपयोग करके एक ग्राफिकल यूजर इंटरफेस (GUI) बनाता है। यह एक विंडो (`JFrame`) प्रदर्शित करेगा जिसमें निर्दिष्ट कंपोनेंट्स होंगे: दो लेबल वाले बटन, एक लेबल के साथ एक टेक्स्ट फ़ील्ड, और एक सबमिट बटन।
कोड स्विंग कंपोनेंट्स के निर्माण और व्यवस्था को प्रदर्शित करता है।
import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import java.awt.FlowLayout; // लेआउट मैनेजर के लिए public class SimpleGUI { public static void main(String[] args) { // एक नया फ्रेम (विंडो) बनाएं JFrame frame = new JFrame(“Simple GUI Example”); // जब विंडो बंद हो तो प्रोग्राम को समाप्त करने के लिए ऑपरेशन सेट करें frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // फ्रेम का आकार सेट करें frame.setSize(400, 150); // एक लेआउट मैनेजर सेट करें। FlowLayout कंपोनेंट्स को बाएं से दाएं लाइन में व्यवस्थित करता है। frame.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 20)); // (i) ‘Yes’ और ‘No’ लेबल वाले बटन JButton yesButton = new JButton(“Yes”); JButton noButton = new JButton(“No”); // (ii) ‘Name’ लेबल के साथ नाम दर्ज करने के लिए टेक्स्ट फ़ील्ड JLabel nameLabel = new JLabel(“Name:”); JTextField nameTextField = new JTextField(15); // 15 कॉलम चौड़ा // (iii) ‘Submit’ टेक्स्ट वाला सबमिट बटन JButton submitButton = new JButton(“Submit”);
// कंपोनेंट्स को फ्रेम में जोड़ें frame.add(yesButton); frame.add(noButton); frame.add(nameLabel); frame.add(nameTextField); frame.add(submitButton); // फ्रेम को दिखाई दें frame.setVisible(true); } }
कोड का स्पष्टीकरण:
- `JFrame` : यह मुख्य विंडो है जिसमें अन्य सभी GUI कंपोनेंट्स रखे जाते हैं।
- `setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)` : यह सुनिश्चित करता है कि जब उपयोगकर्ता विंडो के क्लोज बटन पर क्लिक करता है तो एप्लिकेशन बंद हो जाता है।
- `setLayout(new FlowLayout(…))` : यह `FlowLayout` मैनेजर को फ्रेम में कंपोनेंट्स को व्यवस्थित करने के लिए सेट करता है। कंपोनेंट्स एक पंक्ति में रखे जाते हैं, और यदि पंक्ति भर जाती है तो वे अगली पंक्ति में चले जाते हैं।
- `JButton` : एक मानक क्लिक करने योग्य बटन बनाता है।
- `JLabel` : टेक्स्ट या छवियों का एक स्थिर प्रदर्शन क्षेत्र बनाता है।
- `JTextField` : उपयोगकर्ता को टेक्स्ट की एक पंक्ति दर्ज करने और संपादित करने की अनुमति देता है।
- `frame.add(…)` : निर्दिष्ट कंपोनेंट को विंडो में जोड़ता है।
- `frame.setVisible(true)` : विंडो और उसके कंपोनेंट्स को स्क्रीन पर प्रदर्शित करता है।
यह प्रोग्राम केवल GUI का दृश्य भाग बनाता है; बटन क्लिक या टेक्स्ट प्रविष्टि को संभालने के लिए, आपको इवेंट श्रोताओं (event listeners) को जोड़ने की आवश्यकता होगी। (b) जावा में TCP/IP प्रोग्रामिंग
TCP/IP (ट्रांसमिशन कंट्रोल प्रोटोकॉल/इंटरनेट प्रोटोकॉल) इंटरनेट पर संचार के लिए मूलभूत प्रोटोकॉल सूट है। जावा `java.net` पैकेज के माध्यम से TCP/IP नेटवर्क प्रोग्रामिंग के लिए मजबूत समर्थन प्रदान करता है। TCP एक विश्वसनीय, कनेक्शन-ओरिएंटेड प्रोटोकॉल है, जिसका अर्थ है कि डेटा भेजने से पहले दो अनुप्रयोगों के बीच एक कनेक्शन स्थापित किया जाता है, और यह गारंटी देता है कि डेटा क्रम में और त्रुटियों के बिना वितरित किया जाएगा।
जावा में TCP/IP प्रोग्रामिंग आमतौर पर एक क्लाइंट-सर्वर मॉडल का अनुसरण करती है।
सर्वर साइड (Server Side): सर्वर एक विशिष्ट पोर्ट पर क्लाइंट कनेक्शन के लिए सुनता है।
- एक `ServerSocket` बनाएं: सर्वर एक `ServerSocket` ऑब्जेक्ट बनाकर शुरू होता है, जो एक विशिष्ट पोर्ट नंबर से बंधा होता है। यह सर्वर को उस पोर्ट पर आने वाले कनेक्शन अनुरोधों को सुनने की अनुमति देता है। मेथड: `ServerSocket serverSocket = new ServerSocket(portNumber);`
- एक कनेक्शन स्वीकार करें: सर्वर तब `accept()` मेथड को कॉल करता है। यह एक ब्लॉकिंग कॉल है, जिसका अर्थ है कि प्रोग्राम का निष्पादन तब तक रुक जाता है जब तक कि कोई क्लाइंट उस पोर्ट से कनेक्ट नहीं हो जाता। मेथड: `Socket clientSocket = serverSocket.accept();`
- एक `Socket` प्राप्त करें: जब कोई क्लाइंट कनेक्ट होता है, तो `accept()` मेथड एक `Socket` ऑब्जेक्ट लौटाता है। यह नया `Socket` ऑब्जेक्ट उस विशिष्ट क्लाइंट के साथ संचार के लिए समर्पित है। सर्वर अब अन्य क्लाइंट्स से कनेक्शन स्वीकार करने के लिए अपने `ServerSocket` पर `accept()` को फिर से कॉल करने के लिए स्वतंत्र है (अक्सर एक नए थ्रेड में)।
- संचार करें: `Socket` ऑब्जेक्ट से, सर्वर `getInputStream()` और `getOutputStream()` का उपयोग करके इनपुट और आउटपुट स्ट्रीम प्राप्त कर सकता है ताकि क्लाइंट से डेटा पढ़ सके और उसे डेटा भेज सके।
क्लाइंट साइड (Client Side): क्लाइंट एक सर्वर से कनेक्शन शुरू करता है।
- एक `Socket` बनाएं: क्लाइंट एक `Socket` ऑब्जेक्ट बनाता है, जो सर्वर के IP पते और पोर्ट नंबर को निर्दिष्ट करता है जिससे वह कनेक्ट होना चाहता है। मेथड: `Socket socket = new Socket(“server_ip_address”, portNumber);`
- संचार करें: यदि कनेक्शन सफलतापूर्वक स्थापित हो जाता है, तो क्लाइंट भी `getInputStream()` और `getOutputStream()` का उपयोग करके स्ट्रीम प्राप्त कर सकता है ताकि सर्वर के साथ डेटा का आदान-प्रदान कर सके।
`java.net` पैकेज के मुख्य मेथड और क्लास:
- `java.net.Socket` : यह क्लास एक संचार समापन बिंदु का प्रतिनिधित्व करती है। एक क्लाइंट एक `Socket` बनाता है और एक सर्वर से कनेक्ट होता है। एक सर्वर प्रत्येक क्लाइंट कनेक्शन के लिए एक `Socket` प्राप्त करता है।
- `getInputStream()`: इस सॉकेट के लिए एक `InputStream` लौटाता है।
- `getOutputStream()`: इस सॉकेट के लिए एक `OutputStream` लौटाता है।
- `close()`: सॉकेट कनेक्शन को बंद करता है।
- `java.net.ServerSocket` : यह क्लास सर्वर-साइड सॉकेट के लिए है। यह क्लाइंट्स से कनेक्शन के लिए सुनता है।
- `ServerSocket(int port)`: एक सर्वर सॉकेट बनाता है जो निर्दिष्ट पोर्ट से बंधा होता है।
- `accept()`: एक कनेक्शन के लिए सुनता है और उसे स्वीकार करता है।
- `close()`: सर्वर सॉकेट को बंद करता है।
- `java.net.InetAddress` : यह क्लास IP पते का प्रतिनिधित्व करती है। इसका उपयोग होस्टनाम को IP पते में हल करने के लिए किया जा सकता है।
यह क्लाइंट-सर्वर आर्किटेक्चर जावा को वेब सर्वर, चैट एप्लिकेशन और अन्य नेटवर्क सेवाओं जैसे मजबूत नेटवर्क एप्लिकेशन बनाने के लिए एक शक्तिशाली भाषा बनाता है।
IGNOU MCS-024 Previous Year Solved Question Paper in English
Q1. (a) Define a class and an object. What is the advantage of having data members and member functions with the class ? (b) Define the terms exception and error. How does exception routines help us to deal with abnormal program termination ? (c) How are threads ‘lightweight’ as compared to processes ? Justify your answer. (d) How does object-serialization help to save the state of an object ? (e) Discuss the prominent characteristics of string-class in Java with examples. (f) List the differences between an applet and application programs with their life cycle. (g) Explain the role of LayoutManager with respect to container and component classes. (h) Explain the JDBC-architecture in a 3-tier model with a diagram.
Ans. (a) Class and Object A Class is a blueprint or template for creating objects. It defines the properties (data members) and behaviors (member functions) that are common to all objects of that class. For example, a `Car` class might have properties like color and model, and behaviors like `start()` and `stop()`. An Object is an instance of a class. It is a real-world entity that has a state and behavior. When an object is created from a class, it allocates memory for the data members defined in the class. For example, `myCar` could be an object of the `Car` class. Advantage of having data members and member functions together: The concept of bundling data members (variables) and member functions (methods) together within a class is called Encapsulation . Its key advantages are:
- Data Hiding: It restricts direct access to data from outside the class, improving the integrity and security of the data. The data can only be accessed and modified through the member functions of the class.
- Modularity: It helps in organizing code into self-contained and manageable units. Each class acts as a separate entity, making the code easier to understand, maintain, and debug.
- Reusability: A class, once defined, can be used to create multiple objects in different programs, promoting code reuse.
(b) Exception and Error Exception: An exception is an event that occurs during the execution of a program and disrupts the normal flow of the program’s instructions. These are conditions that a well-written application might try to recover from. Examples: `FileNotFoundException`, `ArithmeticException`. Error: An error indicates a serious problem that a reasonable application should not try to catch. These problems are abnormal and typically happen within the JVM or at a system level, like `OutOfMemoryError` or `StackOverflowError`. Role of Exception Routines: Exception handling routines, typically implemented using `try-catch-finally` blocks, help prevent abnormal program termination.
- When an exception occurs within a `try` block, the normal flow of the program is disrupted, and the JVM looks for a corresponding `catch` block.
- If a matching `catch` block is found, the code within it is executed. This gives the programmer a chance to handle the problem, inform the user, clean up resources, or take alternative action.
- If no exception is handled, the JVM uses the default exception handler, which prints a stack trace and terminates the program.
By using this mechanism, exception routines ensure that the program doesn’t crash abruptly, making it more robust and user-friendly.
(c) Threads vs. Processes Threads are considered ‘lightweight’ compared to processes because they share the resources of their parent process. The justification is as follows:
- Shared Memory Space: All threads created within a process share the same memory space (data and heap segments). In contrast, each process has its own separate memory space. This makes inter-thread communication much faster as they can share data directly.
- Resource Overhead: Creating a new process involves allocating a new memory space, file descriptors, and other system resources, which is an expensive and time-consuming operation. Creating a thread has much less overhead because it utilizes the resources of the existing process.
- Context Switching: Switching between threads is faster than switching between processes. This is because a thread switch only requires saving and restoring the thread-specific data (like the program counter, stack pointer), whereas a process switch requires changing much more context, including Memory Management Unit (MMU) information.
For these reasons, threads provide an efficient solution for applications that require concurrent execution, especially in I/O-bound or GUI-based applications.
(d) Object Serialization Object serialization is a mechanism in Java by which an object’s state can be converted into a byte stream. This byte stream can then be saved to a file, transmitted across a network, or stored in a database. Later, this byte stream can be used to recreate the object’s state, a process called deserialization . It helps to save the state of an object in the following ways:
- Persistence: Serialization allows an object’s state to be saved to disk. When the application is restarted, the object can be restored to its previous state, enabling the application to resume from where it left off.
- Communication: In distributed systems like Remote Method Invocation (RMI), objects are serialized and sent over the network from one JVM to another. The receiving JVM deserializes the object and uses it.
To make an object serializable in Java, its class must implement the `java.io.Serializable` interface. This is a marker interface, meaning it has no methods. The actual serialization and deserialization are handled by the `ObjectOutputStream` and `ObjectInputStream` classes.
(e) Characteristics of String-class in Java The `java.lang.String` class in Java has several prominent characteristics:
- Immutability: String objects are immutable. Once a String object is created, its contents cannot be changed. Any operation that appears to modify a string, such as `concat()` or `substring()`, actually creates a new String object. Example: `String s = “Java”; s.concat(” World”);` `s` will still refer to “Java”. To capture the result, you must do `s = s.concat(” World”);`, which makes `s` refer to a new object.
- String Pool: Java maintains a “string constant pool” in a special area of the heap to save memory. When a string literal is created, the JVM first checks the pool. If the string already exists, a reference to the existing instance is returned instead of creating a new object.
- Literal Creation: Strings can be created directly without using the `new` keyword, like `String name = “John”;`. This utilizes the string pool mechanism.
- Rich API: The `String` class provides a large number of useful methods for string manipulation, such as `length()`, `charAt(int index)`, `substring(int beginIndex, int endIndex)`, `equals(Object anObject)`, `equalsIgnoreCase(String anotherString)`, `trim()`, and `split(String regex)`.
(f) Applet vs. Application Program Applets and Applications are two different ways of writing Java programs. The key differences between them are listed below:
- Execution:
- Application: These are standalone programs executed directly by the JVM. They require a `public static void main(String[] args)` method which is the entry point of execution.
- Applet: These are small Java programs designed to run within a web browser or an applet viewer tool. They do not have a `main()` method.
- Life Cycle:
- Application: Have a simple life cycle, starting with the `main()` method and ending when `main()` finishes or `System.exit()` is called.
- Applet: Have a complex, event-driven life cycle managed by the browser. The key methods are: `init()`, `start()`, `paint()`, `stop()`, and `destroy()`.
- Security:
- Application: By default, have full access to the resources of the local system (like files, network connections).
- Applet: Run in a restricted environment called a “sandbox.” This prevents them from performing dangerous operations like accessing the local file system or making network connections.
- Requirements:
- Application: Only require a JRE to run.
- Applet: Require a Java-enabled web browser or an applet viewer to run.
(g) Role of LayoutManager In AWT (Abstract Window Toolkit) and Swing, a `LayoutManager` is an interface responsible for determining the position and size of components within a container. A `Container` (like `JFrame`, `JPanel`) holds one or more `Component` objects (like `JButton`, `JTextField`). The role of the LayoutManager is crucial because it:
- Provides Platform Independence: It decouples the layout of the GUI from platform-specific details. Different operating systems can have different font sizes, screen resolutions, and window decorations. The LayoutManager automatically adjusts to these variations, ensuring the layout remains usable across different platforms.
- Handles Automatic Resizing: When the container is resized, the layout manager automatically rearranges and resizes the components within it according to its policy. This is in contrast to absolute positioning, where components retain their size and position, which can lead to awkward layouts when the container is resized.
- Offers Ease of Use: Developers do not need to calculate pixel-perfect coordinates for each component. Instead, they can choose a suitable layout manager (e.g., `FlowLayout`, `BorderLayout`, `GridLayout`, `GridBagLayout`), add components to the container, and the manager takes care of the rest.
In essence, the `LayoutManager` acts as a mediator between the container and component classes, simplifying the creation of dynamic, robust, and cross-platform GUI layouts.
(h) JDBC-Architecture in a 3-Tier Model The 3-tier architecture is a client-server architecture in which the presentation, application processing, and data management are logically separate processes. JDBC (Java Database Connectivity) is often used in the application tier of this model to communicate with the database. The three tiers are:
- Tier 1: Client Tier (Presentation Layer)
- This is the user interface. It can be a web browser displaying HTML pages, or a desktop application built using Swing or AWT.
- Its primary job is to take input from the user and display results. It does not interact directly with the database.
- Tier 2: Application Server Tier (Business Logic Layer)
- This is the “middle” part of the architecture. It receives requests from the client.
- It implements the business logic and processes the data received from the client.
- This tier uses the JDBC API to communicate with the database. It sends SQL queries through a JDBC driver and receives results from the database.
- It processes the results and sends them back to the client tier (often in HTML, XML, or JSON format).
- Tier 3: Data Source Tier (Data Layer)
- This is the actual Database Management System (DBMS) such as MySQL, Oracle, or PostgreSQL.
- Its job is to store and retrieve data. It receives SQL commands from the application server, executes them, and returns the data.
Diagram Description:
(Client) — [HTTP/Network] —> (Application Server) — [JDBC] —> (Database)
The flow is:
- The user interacts with the Client tier (e.g., submits a form).
- The Client tier sends a request to the Application Server tier.
- The Application Server executes business logic and sends a query to the Database tier using JDBC.
- The Database processes the query and returns the results to the Application Server.
- The Application Server formats the results and sends them back to the Client tier, where they are presented to the user.
This separation improves scalability, flexibility, and security.
Q2. (a) Explain the concept of overloading of methods in Java with an example. (b) Explain the garbage collection process in Java language. What are its major advantages compared to other languages ?
Ans. (a) Method Overloading in Java Method overloading is a form of compile-time polymorphism in Java. It allows a class to have multiple methods with the same name, as long as they have different parameters. The compiler determines which method to call based on the method name and the number and type of arguments passed. The method signature (name and parameter list) must be different. The difference in the parameter list can be in:
- Number of parameters.
- Data type of parameters.
- Sequence (order) of the types of parameters.
Note:
Method overloading cannot be achieved by changing only the return type of the method.
Advantages:
- It increases the readability of the program.
- It improves the reusability of the code.
- It provides flexibility, allowing the same operation to be performed on different types of data.
Example:
In the example below, the `Calculator` class has an `add` method that is overloaded with different types of arguments.
class Calculator { // Method to add two integers public int add(int a, int b) { System.out.println("Called method to add two ints"); return a + b; }// Method to add three integers public int add(int a, int b, int c) { System.out.println("Called method to add three ints"); return a + b + c; }
// Method to add two doubles public double add(double a, double b) { System.out.println("Called method to add two doubles"); return a + b; }}
public class OverloadingExample { public static void main(String[] args) { Calculator calc = new Calculator();
// Calls the first method (int, int) System.out.println("Sum of 2 and 3 is: " + calc.add(2, 3));
// Calls the second method (int, int, int) System.out.println("Sum of 2, 3, and 4 is: " + calc.add(2, 3, 4));
// Calls the third method (double, double) System.out.println("Sum of 2.5 and 3.5 is: " + calc.add(2.5, 3.5)); }}
In this example, at each call to `calc.add(…)`, the Java compiler selects the correct `add` method based on the type and number of arguments.
(b) Garbage Collection in Java Garbage Collection (GC) is the process of automatic memory management provided by the Java Virtual Machine (JVM). Its primary purpose is to reclaim the memory occupied by objects that are no longer in use or referenced by the program. The Garbage Collection Process: The process generally involves two phases:
- Identification: The garbage collector identifies which objects are still in use and which are not. An object is considered “garbage” if it is no longer reachable from any active thread or any other live object. This is typically done by performing a “reachability” analysis, starting from the program’s roots (e.g., local variables on the stack) and marking all objects that can be reached from there.
- Reclamation: After the identification phase, the garbage collector deallocates the memory occupied by all the unmarked or unreachable objects. This memory is then returned to the heap and becomes available for future object allocation.
The JVM has various garbage collection algorithms (e.g., Mark-and-Sweep, Copying, Generational), and developers can choose different collectors for performance tuning.
Advantages Compared to Other Languages:
In languages like C and C++, the programmer has to manually allocate and de-allocate memory using `malloc`/`free` or `new`/`delete`. Java’s automatic garbage collection offers several significant advantages:
- Prevents Memory Leaks: In manual memory management, if a programmer forgets to de-allocate an object that is no longer needed, it causes a memory leak. GC eliminates this common bug by automatically cleaning up unused objects.
- Avoids Dangling Pointers: A dangling pointer is a pointer that refers to a memory location that has already been freed. Using such a pointer can lead to unpredictable behavior or crashes. Since there is no explicit de-allocation in Java, the problem of dangling pointers is eliminated.
- Simplified Development: Programmers do not need to write and debug complex memory management code. This allows them to focus on the core logic of the application, reducing development time and the likelihood of bugs.
- Increased Safety and Robustness: By handling memory management errors automatically, GC helps make Java applications more stable and secure.
Q3. (a) Differentiate between checked and unchecked exceptions in Java with suitable examples. (b) Write a file I/O Java program which reads a line of text from user and writes it to a file ‘Myfile.txt’. Further, the program reads the file ‘Myfile.txt’ and displays its content to output screen.
Ans. (a) Checked vs. Unchecked Exceptions In Java, exceptions are classified into two main categories: checked exceptions and unchecked exceptions. This classification is based on whether the compiler checks if the programmer has handled the exception. Checked Exceptions:
- These are exceptions that the compiler checks at compile-time.
- If a method can throw a checked exception, it must either handle it using a `try-catch` block or declare it in its signature using the `throws` keyword.
- They typically represent conditions outside the program’s control, such as problems with the network or file system. A well-written application can often recover from them.
- These are direct subclasses of `java.lang.Exception` but not subclasses of `java.lang.RuntimeException`.
- Examples: `IOException`, `SQLException`, `FileNotFoundException`, `ClassNotFoundException`.
Example (Checked Exception):
import java.io.File;import java.io.FileReader;import java.io.FileNotFoundException;
public class CheckedExceptionExample { public static void main(String[] args) { File file = new File("non_existent_file.txt"); try { // This line can throw FileNotFoundException, which is a checked exception. FileReader fr = new FileReader(file); } catch (FileNotFoundException e) { // The compiler forces us to either catch or declare it. System.out.println("File not found: " + e.getMessage()); } }}
Unchecked Exceptions:
- These are exceptions that the compiler does not check at compile-time.
- A method is not required to handle or declare these exceptions.
- They are typically the result of programming errors or bugs, such as invalid arguments, null pointers, or accessing an array out of bounds.
- These are subclasses of `java.lang.RuntimeException`. `Error` and its subclasses are also unchecked.
- Examples: `NullPointerException`, `ArrayIndexOutOfBoundsException`, `ArithmeticException`, `IllegalArgumentException`.
Example (Unchecked Exception):
public class UncheckedExceptionExample { public static void main(String[] args) { String text = null; try { // This line will throw a NullPointerException. // The compiler does not force us to catch it. System.out.println(text.length()); } catch (NullPointerException e) { // It's good practice to catch it, but not mandatory. System.out.println("Caught NullPointerException: The string is null."); } int[] arr = {1, 2, 3}; // This would throw an ArrayIndexOutOfBoundsException. // System.out.println(arr[3]); }}
In summary, the key difference is that checked exceptions must be mandatorily handled at compile-time, while unchecked exceptions do not.
(b) File I/O Java Program This Java program takes input from the user, writes it to ‘Myfile.txt’, and then reads the content of that file to display it on the console. It uses the `try-with-resources` statement for I/O operations, which ensures that resources (like file streams) are closed automatically.
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;public class FileIOProgram {
public static void main(String[] args) { String fileName = "Myfile.txt";
// Step 1: Read a line of text from the user and write it to the file writeToFile(fileName);
// Step 2: Read the file and display its content to the screen readFromFile(fileName); }
/
- Reads input from the user and writes it to the specified file.
*/ private static void writeToFile(String fileName) { // try-with-resources will ensure the writer and reader are closed automatically try ( // Create a BufferedReader to read from the console BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in)); // Create a BufferedWriter to write to the file BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)) ) { System.out.print("Enter a line of text to write to the file: "); // Read a line of text from the user String textFromUser = consoleReader.readLine(); // Write the text to the file writer.write(textFromUser); // Add a new line (optional, but good practice) writer.newLine(); System.out.println("Successfully wrote to the file '" + fileName + "'."); } catch (IOException e) { System.err.println("An error occurred during file writing: " + e.getMessage()); e.printStackTrace(); } } /
- Reads the specified file and displays its content on the console.
*/ private static void readFromFile(String fileName) { System.out.println("\nReading content from the file '" + fileName + "':"); // try-with-resources will ensure the reader is closed automatically try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) { String currentLine; // Read the file line-by-line until the end is reached while ((currentLine = reader.readLine()) != null) { System.out.println(currentLine); } } catch (IOException e) { System.err.println("An error occurred during file reading: " + e.getMessage()); e.printStackTrace(); } }}
How to Run:
1. Save the code as `FileIOProgram.java`.
2. Compile it using `javac FileIOProgram.java`.
3. Run it using `java FileIOProgram`.
4. The program will prompt you to enter a line of text. Type some text and press Enter.
5. The program will confirm it wrote to the file, and then it will read the content back from the same file and show it to you.
Q4. (a) Explain the life cycle of a thread with all the — functions/methods with a diagram. Also explain thread priority. (b) Explain the characteristics of character stream classes with special reference to PrintStream class.
Ans. (a) Thread Life Cycle and Priority A thread in Java goes through various states during its lifetime. The life cycle of a thread is defined by these states and the transitions between them. States of a Thread:
- New: When a new instance of a Thread object is created using `new Thread(…)`, it is in the new state. At this point, the thread is not yet alive and the system has not allocated any resources for it.
- Runnable: When the `start()` method is called on the thread, it moves from the new state to the runnable state. A thread in this state is eligible for execution, but it is waiting for the thread scheduler to allocate CPU time. This includes both “Running” and “Ready” sub-states.
- Blocked/Waiting: A thread enters this state when it is temporarily inactive. A thread can be blocked for several reasons:
- It is suspended for a specified time due to a call to the `sleep(milliseconds)` method.
- It is waiting for an I/O operation to complete.
- It is trying to enter a `synchronized` block/method that is currently locked by another thread.
- It is waiting due to a call to the `wait()` method. It waits until another thread calls `notify()` or `notifyAll()` on the same object.
- It is waiting for another thread to terminate due to a call to the `join()` method.
- Terminated (Dead): A thread enters this state when it has finished its task. This happens when its `run()` method exits normally or when it terminates abruptly due to an uncaught exception. Once terminated, a thread cannot be started again.
Life Cycle Diagram:
[ New ] — `start()` –> [ Runnable ] <–> [ Running ]
[ Running ] — I/O, `sleep()`, `wait()`, `join()` –> [ Blocked/Waiting ]
[ Blocked/Waiting ] — I/O complete, `sleep()` timeout, `notify()`, joined thread dies –> [ Runnable ]
[ Running ] — `run()` completes –> [ Terminated ]
Thread Priority: Every thread in Java has a priority. Priorities are integers between 1 and 10. A higher number means a higher priority. The thread scheduler uses these priorities to decide which thread should be executed next.
- `Thread.MIN_PRIORITY` (value 1)
- `Thread.NORM_PRIORITY` (value 5, the default)
- `Thread.MAX_PRIORITY` (value 10)
In theory, when multiple threads are ready to run, the one with the highest priority is most likely to get CPU time. However, the exact behavior of thread scheduling is highly dependent on the JVM and the underlying operating system. Therefore, it’s not advisable to rely on thread priority for program correctness; it should only be used as a hint to affect performance. You can set a thread’s priority using the `setPriority(int)` method and get it using `getPriority()`.
(b) Character Stream Classes and PrintStream The Java I/O API is divided into two main categories: byte streams and character streams. Characteristics of Character Stream Classes:
- Purpose: Character stream classes are designed specifically for reading and writing textual data (characters). They internally handle 16-bit Unicode characters, making them suitable for internationalization.
- Base Classes: All character input streams are derived from the `java.io.Reader` abstract class, and all character output streams are derived from the `java.io.Writer` abstract class.
- Encoding: They automatically translate between characters and bytes, using a specified or default character set (e.g., UTF-8, ISO-8859-1). This makes them more convenient and reliable than byte streams for handling text files.
- Examples: `FileReader`, `FileWriter`, `BufferedReader`, `BufferedWriter`, `PrintWriter`.
Byte streams, in contrast, work with raw 8-bit bytes and are suitable for binary data (like images, audio) or low-level I/O.
Special Reference to `PrintStream` Class: Although `PrintStream` is often used for text output (the most famous example being `System.out`, which is a `PrintStream`), it is a historical anomaly and is actually a byte stream, not a character stream . It is a subclass of `java.io.OutputStream`. The key characteristics of `PrintStream` are:
- Byte-Oriented: It is an output stream that writes bytes. When you pass it characters or strings, it converts them to bytes using the default platform encoding. This can lead to unexpected behavior on different platforms if the default encodings do not match.
- Formatted Output: Its main advantage is providing convenient methods like `print()`, `println()`, and `printf()` that convert various primitive data types and objects into a readable text format.
- Never Throws `IOException`: `PrintStream` is designed for convenience. It does not throw an `IOException` from any of its public methods. Instead, if an I/O error occurs, it sets an internal error flag. You can check the status of this flag by calling the `checkError()` method. This is convenient for console output where an I/O error is unlikely, but makes it unsuitable for reliable file or network writing.
- Auto-flushing: A `PrintStream` can be created with a `boolean` flag that enables auto-flushing. If `true`, the buffer will be flushed automatically whenever a newline (`\n`) character is written or one of the `println()` methods is called.
Comparison with `PrintWriter`:
`PrintWriter` is the character-oriented equivalent. It is a subclass of `Writer` and provides the same formatted output methods as `PrintStream`. For writing text files, `PrintWriter` is preferred over `PrintStream` because it handles character encodings correctly and is platform-independent.
Q5. (a) Write a Java program to display the following : (i) Buttons with Label ‘Yes’ and ‘No’. (ii) Text field to enter name with Label ‘Name’. (iii) Submit button with text ‘Submit’ on it. (b) Explain the concept of TCP/IP programming in Java with the methods of java.net package.
Ans. (a) Java Swing GUI Program This Java program uses the Swing framework to create a Graphical User Interface (GUI). It will display a window (`JFrame`) containing the specified components: two labeled buttons, a text field with a label, and a submit button. The code demonstrates the creation and arrangement of Swing components.
import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JTextField;import java.awt.FlowLayout; // For the layout managerpublic class SimpleGUI {
public static void main(String[] args) { // Create a new frame (window) JFrame frame = new JFrame("Simple GUI Example");
// Set the operation to terminate the program when the window is closed frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set the size of the frame frame.setSize(400, 150);
// Set a layout manager. FlowLayout arranges components in a line, left to right. frame.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 20));
// (i) Buttons with Label 'Yes' and 'No' JButton yesButton = new JButton("Yes"); JButton noButton = new JButton("No");
// (ii) Text field to enter name with Label 'Name' JLabel nameLabel = new JLabel("Name:"); JTextField nameTextField = new JTextField(15); // 15 columns wide
// (iii) Submit button with text 'Submit' on it JButton submitButton = new JButton("Submit"); // Add the components to the frame frame.add(yesButton); frame.add(noButton); frame.add(nameLabel); frame.add(nameTextField); frame.add(submitButton);
// Make the frame visible frame.setVisible(true); }}
Explanation of the Code:
- `JFrame` : This is the main window in which all other GUI components are placed.
- `setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)` : This ensures that the application closes when the user clicks the window’s close button.
- `setLayout(new FlowLayout(…))` : This sets the `FlowLayout` manager to arrange the components in the frame. Components are placed in a row, and they wrap to the next row if the current one is full.
- `JButton` : Creates a standard clickable button.
- `JLabel` : Creates a static display area for text or images.
- `JTextField` : Allows the user to enter and edit a single line of text.
- `frame.add(…)` : Adds the specified component to the window.
- `frame.setVisible(true)` : Displays the window and its components on the screen.
This program only creates the visual part of the GUI; to handle button clicks or text entry, you would need to add event listeners.
(b) TCP/IP Programming in Java TCP/IP (Transmission Control Protocol/Internet Protocol) is the fundamental protocol suite for communication over the Internet. Java provides robust support for TCP/IP network programming through the `java.net` package. TCP is a reliable, connection-oriented protocol, which means a connection is established between two applications before data is sent, and it guarantees that data will be delivered in order and without errors. TCP/IP programming in Java typically follows a client-server model . Server Side: The server listens for client connections on a specific port.
- Create a `ServerSocket`: The server starts by creating a `ServerSocket` object, which is bound to a specific port number. This allows the server to listen for incoming connection requests on that port. Method: `ServerSocket serverSocket = new ServerSocket(portNumber);`
- Accept a Connection: The server then calls the `accept()` method. This is a blocking call, meaning the program’s execution pauses until a client connects to that port. Method: `Socket clientSocket = serverSocket.accept();`
- Receive a `Socket`: When a client connects, the `accept()` method returns a `Socket` object. This new `Socket` object is dedicated to communication with that specific client. The server is now free to call `accept()` on its `ServerSocket` again (often in a new thread) to accept connections from other clients.
- Communicate: From the `Socket` object, the server can get input and output streams using `getInputStream()` and `getOutputStream()` to read data from and send data to the client.
Client Side:
The client initiates a connection to a server.
- Create a `Socket`: The client creates a `Socket` object, specifying the server’s IP address and the port number it wants to connect to. Method: `Socket socket = new Socket(“server_ip_address”, portNumber);`
- Communicate: If the connection is successfully established, the client can also get streams using `getInputStream()` and `getOutputStream()` to exchange data with the server.
Key Methods and Classes of `java.net` package:
- `java.net.Socket` : This class represents a communication endpoint. A client creates a `Socket` and connects to a server. A server receives a `Socket` for each client connection.
- `getInputStream()`: Returns an `InputStream` for this socket.
- `getOutputStream()`: Returns an `OutputStream` for this socket.
- `close()`: Closes the socket connection.
- `java.net.ServerSocket` : This class is for server-side sockets. It listens for connections from clients.
- `ServerSocket(int port)`: Creates a server socket bound to the specified port.
- `accept()`: Listens for and accepts a connection.
- `close()`: Closes the server socket.
- `java.net.InetAddress` : This class represents an IP address. It can be used to resolve hostnames into IP addresses.
This client-server architecture makes Java a powerful language for creating robust network applications like web servers, chat applications, and other network services.
Download IGNOU previous Year Question paper download PDFs for MCS-024 to improve your preparation. These ignou solved question paper IGNOU Previous Year Question paper solved PDF in Hindi and English help you understand the exam pattern and score better.
Thanks!
Leave a Reply