Java ইন্টারভিউতে কিছু সাধারণ প্রশ্ন থাকে যা প্রার্থীর জ্ঞান, সমস্যা সমাধানের দক্ষতা, এবং বাস্তব পরিস্থিতিতে Java প্রযুক্তির ব্যবহার বোঝার ওপর ভিত্তি করে থাকে। এখানে কিছু Java Interview Scenarios সম্পর্কিত প্রশ্ন দেওয়া হলো, যেগুলোর মাধ্যমে আপনি আপনার Java দক্ষতা আরও ভালোভাবে প্রমাণ করতে পারবেন:
1. Scenario: আপনি একটি মাল্টিথ্রেডেড অ্যাপ্লিকেশন লিখছেন, যেখানে দুটি থ্রেড একই রিসোর্স অ্যাক্সেস করছে। আপনি কিভাবে সমস্যা সমাধান করবেন?
উত্তর: এ ধরনের সমস্যা সিঙ্ক্রনাইজেশন (synchronization) ব্যবহার করে সমাধান করা যেতে পারে। দুটি থ্রেড যখন একই রিসোর্সে অ্যাক্সেস পেতে চায়, তখন এটি রেস কন্ডিশন (race condition) সৃষ্টি করতে পারে। থ্রেডগুলোর মধ্যে সঠিকভাবে সিঙ্ক্রোনাইজেশন ব্যবহারের মাধ্যমে ডেটার সঠিকতা নিশ্চিত করা যায়।
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
এখানে synchronized কিওয়ার্ড ব্যবহৃত হয়েছে যাতে এক সময় একটিমাত্র থ্রেড increment() মেথডটি কল করতে পারে।
2. Scenario: আপনার অ্যাপ্লিকেশনকে দ্রুত ডেটা প্রসেসিং করতে হবে, আপনি কি ধরনের ডেটা স্ট্রাকচার বা অ্যালগরিদম ব্যবহার করবেন?
উত্তর: ডেটা প্রসেসিংয়ের জন্য, আমাকে নিশ্চিত করতে হবে যে ডেটা দ্রুত অ্যাক্সেসযোগ্য এবং প্রক্রিয়াকরণের জন্য উপযুক্ত স্ট্রাকচার ব্যবহার করা হয়েছে। এখানে কিছু সাধারণ সমাধান হতে পারে:
- HashMap: দ্রুত লুকআপ এবং আপডেট অপারেশনের জন্য।
- ArrayList: দ্রুত সিকোয়েন্সাল অ্যাক্সেসের জন্য।
- PriorityQueue: যখন ডেটা প্রক্রিয়াকরণে নির্দিষ্ট অর্ডার (যেমন মিন/ম্যাক্স) প্রয়োজন হয়।
আপনার প্রয়োজনে স্ট্রাকচার নির্বাচন করা উচিত। উদাহরণস্বরূপ, যদি আপনার দ্রুত অনুসন্ধান প্রয়োজন হয়, তবে HashMap ব্যবহার করা যেতে পারে, এবং যদি ডেটা একে অপরের তুলনায় অর্ডারিং প্রয়োজন হয়, তবে PriorityQueue ব্যবহার করা যেতে পারে।
3. Scenario: আপনি একটি ফাইল থেকে ডেটা পড়ছেন এবং এটি প্রক্রিয়া করতে হবে, কিন্তু কিছু নির্দিষ্ট ডেটা ফরম্যাটে সমস্যা হচ্ছে। আপনি কিভাবে তা ঠিক করবেন?
উত্তর: ফাইল থেকে ডেটা পড়ার সময় ডেটার ফরম্যাট বা কনভার্সন সমস্যা আসতে পারে। এই ধরনের পরিস্থিতিতে আপনি:
- Exception Handling: প্রপারভাবে
try-catchব্লক ব্যবহার করুন যাতে ভুল ফরম্যাটে ডেটা এন্ট্রি হলে অ্যাপ্লিকেশন ক্র্যাশ না করে। - Custom Formatter: ডেটা ফরম্যাট চেক করার জন্য এবং প্রক্রিয়া করার জন্য কাস্টম পদ্ধতি তৈরি করতে পারেন।
এখানে একটি উদাহরণ দেওয়া হলো:
try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
try {
String[] values = line.split(",");
int num = Integer.parseInt(values[0]); // If format is incorrect
// Further processing
} catch (NumberFormatException e) {
System.out.println("Invalid format in line: " + line);
}
}
} catch (IOException e) {
System.out.println("File reading error: " + e.getMessage());
}
এখানে ফাইল থেকে ডেটা পড়ার সময় ফরম্যাটের ভুল থাকলে তা ধরা পড়ে এবং প্রক্রিয়াটি অব্যাহত থাকে।
4. Scenario: আপনার অ্যাপ্লিকেশনটি মাল্টি-থ্রেডেড এবং আপনি ডেডলক (Deadlock) সমস্যার সম্মুখীন হচ্ছেন, আপনি কিভাবে এটি প্রতিরোধ করবেন?
উত্তর: ডেডলক তখন ঘটে যখন দুটি বা ততোধিক থ্রেড একে অপরকে অপেক্ষা করে এবং কখনও শেষ হয় না। ডেডলক প্রতিরোধে কিছু সাধারণ কৌশল:
- Lock Ordering: একই সময়ে একাধিক লক প্রয়োজন হলে, প্রতিটি থ্রেড একটি নির্দিষ্ট লক অর্ডার অনুসরণ করবে।
- Timeout: থ্রেড যদি দীর্ঘ সময় ধরে লক না পায়, তবে কিছু সময় পর থ্রেডটি বাতিল করা যাবে।
এখানে একটি সহজ লক অর্ডার কৌশল উদাহরণ:
class A {
synchronized void methodA(B b) {
b.last();
}
synchronized void last() {}
}
class B {
synchronized void methodB(A a) {
a.last();
}
synchronized void last() {}
}
এখানে A এবং B এর মেথডগুলির মধ্যে সঠিক অর্ডারে লক নিলে ডেডলক এড়ানো যায়।
5. Scenario: আপনি একটি খুব বড় অ্যাপ্লিকেশন তৈরি করছেন যা ডেটাবেসের সাথে সংযুক্ত এবং প্রায়ই উচ্চ লোডের মুখোমুখি হয়, আপনি কি ধরণের সমাধান ব্যবহার করবেন?
উত্তর: উচ্চ লোড ম্যানেজ করার জন্য কিছু সুপারিশকৃত সমাধান:
- Connection Pooling: ডেটাবেস কানেকশনগুলি পুনঃব্যবহার করার জন্য connection pooling ব্যবহার করতে হবে, যাতে সিস্টেমের উপর চাপ কমে।
- Caching: Frequently accessed ডেটা ক্যাশে রাখতে হবে, যেমন Redis বা Memcached ব্যবহার করতে পারেন।
- Load Balancing: সার্ভার লোড ব্যালেন্স করার জন্য লোড ব্যালান্সার ব্যবহার করা যেতে পারে।
- Asynchronous Processing: কিছু ডেটাবেস অপারেশন বা ব্যাকগ্রাউন্ড কাজ অ্যাসিঙ্ক্রোনাসভাবে করতে হবে যাতে মূল থ্রেডের উপর চাপ না আসে।
6. Scenario: আপনি একটি লার্জ-স্কেল ওয়েব অ্যাপ্লিকেশন ডেভেলপ করছেন যেখানে একাধিক ব্যবহারকারী একে অপরের সাথে ইন্টারঅ্যাক্ট করে, কোন প্রযুক্তি বা প্যাটার্ন আপনি ব্যবহার করবেন?
উত্তর: এ ধরনের সিস্টেমের জন্য আপনি নিম্নলিখিত প্যাটার্ন এবং প্রযুক্তি ব্যবহার করতে পারেন:
- MVC Pattern: অ্যাপ্লিকেশন লজিককে ভিউ, কন্ট্রোলার, এবং মডেল অংশে ভাগ করা।
- WebSockets: রিয়েল-টাইম ইন্টারঅ্যাকশন ব্যবস্থাপনা।
- RESTful APIs: ক্লায়েন্ট ও সার্ভারের মধ্যে ডেটা এক্সচেঞ্জের জন্য RESTful সার্ভিস।
- JWT Authentication: ব্যবহারকারীদের নিরাপদ অথেন্টিকেশন এবং অথোরাইজেশন ব্যবস্থাপনা।
7. Scenario: আপনি একটি Java অ্যাপ্লিকেশনে ডেটা স্টোরেজ হিসেবে RDBMS ব্যবহার করছেন, কিন্তু প্যার্থাল কনসিস্টেন্সি এবং পারফরম্যান্সের সমস্যা হচ্ছে। আপনি কি সমাধান গ্রহণ করবেন?
উত্তর:
- Caching: Redis বা Memcached এর মতো ইন-মেমরি ক্যাশে ব্যবহার করতে পারেন, যাতে দ্রুত অ্যাক্সেসযোগ্য ডেটা দ্রুত পাওয়ার জন্য।
- Database Sharding: ডেটাবেসের মধ্যে ডেটা ভাগ (shard) করা, যাতে একক ডেটাবেসে চাপ না পড়ে।
- NoSQL Database: যদি আপনার ডেটা প্রকার RDBMS-এর জন্য উপযুক্ত না হয়, তবে আপনি NoSQL ডেটাবেস (যেমন MongoDB, Cassandra) ব্যবহার করতে পারেন।
এই ধরনের Java Interview Scenarios প্রশ্ন আপনার সমস্যার সমাধান করার ক্ষমতা, প্রযুক্তির গভীর জ্ঞান এবং বাস্তবিক পরিস্থিতিতে দক্ষতার মূল্যায়ন করতে ব্যবহৃত হয়। এগুলোতে সঠিক সমাধান প্রদান করতে পারলে আপনার দক্ষতা প্রমাণিত হবে এবং আপনি কোনো প্রকল্পে বা উন্নত কার্যক্রমে ভালো পারফর্ম করতে পারবেন।
Java-তে multithreading একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা একাধিক থ্রেডের মাধ্যমে একযোগে কাজ করতে সক্ষম করে। প্রতিটি থ্রেড আলাদাভাবে কোডের একটি অংশ চালাতে পারে, এবং একাধিক থ্রেড একে অপরের কাজের সাথে সমান্তরালভাবে কাজ করে।
এখানে, আমরা একটি সাধারণ উদাহরণ দেখবো যেখানে দুটি থ্রেড সমান্তরালভাবে কাজ করবে।
Multithreaded প্রোগ্রাম তৈরি করার ধাপ:
- Thread Class অথবা Runnable Interface ব্যবহার: Java-তে একটি নতুন থ্রেড তৈরি করার দুটি প্রধান উপায় রয়েছে:
- Thread Class এক্সটেন্ড করে।
- Runnable Interface ইমপ্লিমেন্ট করে।
- Thread Start করা:
start()মেথড ব্যবহার করে থ্রেডটি চালু করা হয়। এই মেথড থ্রেডেরrun()মেথডকে কল করে এবং নতুন থ্রেডে কোড চালাতে শুরু করে। - Multithreading Example: নিচে একটি উদাহরণ দেওয়া হয়েছে, যেখানে দুটি থ্রেড আলাদাভাবে কাজ করবে।
উদাহরণ: Thread Class এক্সটেন্ড করে দুইটি থ্রেড চালানো
class Thread1 extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - Count: " + i);
try {
Thread.sleep(500); // 500 মিলিসেকেন্ড বিরতি
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
class Thread2 extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2 - Count: " + i);
try {
Thread.sleep(500); // 500 মিলিসেকেন্ড বিরতি
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
public class MultiThreadExample {
public static void main(String[] args) {
Thread1 t1 = new Thread1(); // Thread 1 ইনস্ট্যান্স
Thread2 t2 = new Thread2(); // Thread 2 ইনস্ট্যান্স
t1.start(); // Thread 1 চালু করা
t2.start(); // Thread 2 চালু করা
}
}
ব্যাখ্যা:
- Thread1 এবং Thread2 দুটি ক্লাস তৈরি করা হয়েছে, যেগুলি Thread ক্লাস থেকে এক্সটেন্ড করে।
- প্রতিটি থ্রেডের
run()মেথডে একটি লুপ চলছে যা প্রতি ৫ বার কাউন্ট করবে এবং ৫০০ মিলিসেকেন্ড বিরতি নিয়ে চলবে। Thread.sleep(500)থ্রেডটিকে ৫০০ মিলিসেকেন্ড সময় বিরতি দিতে ব্যবহৃত হয়, যাতে থ্রেডগুলি সমান্তরালভাবে কাজ করার জন্য পর্যাপ্ত সময় পায়।start()মেথড ব্যবহৃত হয়েছে থ্রেডগুলো চালু করতে।
Runnable Interface ব্যবহার করে Multithreading:
অন্য একটি পদ্ধতি হল Runnable Interface ব্যবহার করে থ্রেড তৈরি করা। এখানে, আমরা Thread ক্লাসের পরিবর্তে Runnable ইন্টারফেস ব্যবহার করবো।
class MyRunnable1 implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - Count: " + i);
try {
Thread.sleep(500); // 500 মিলিসেকেন্ড বিরতি
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
class MyRunnable2 implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2 - Count: " + i);
try {
Thread.sleep(500); // 500 মিলিসেকেন্ড বিরতি
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
public class MultiThreadUsingRunnable {
public static void main(String[] args) {
// Runnable ইন্টারফেস ইমপ্লিমেন্টেশন
MyRunnable1 r1 = new MyRunnable1();
MyRunnable2 r2 = new MyRunnable2();
Thread t1 = new Thread(r1); // Thread 1 তৈরি
Thread t2 = new Thread(r2); // Thread 2 তৈরি
t1.start(); // Thread 1 চালু করা
t2.start(); // Thread 2 চালু করা
}
}
ব্যাখ্যা:
- এখানে, আমরা
Runnableইন্টারফেস ইমপ্লিমেন্ট করেছি এবংrun()মেথডে কাজ নির্ধারণ করেছি। Threadক্লাসের কনস্ট্রাক্টরকেRunnableঅবজেক্ট পাস করা হয়েছে।start()মেথড ব্যবহার করে থ্রেড চালু করা হয়েছে।
Multithreading এর প্রক্রিয়া:
- Thread তৈরি করা:
- Thread Class এক্সটেন্ড করে অথবা Runnable Interface ইমপ্লিমেন্ট করে থ্রেড তৈরি করা যায়।
- Thread Start করা:
start()মেথড ব্যবহার করা হয়, যা থ্রেডেরrun()মেথডকে কল করে।
- Thread Scheduling:
- JVM বা অপারেটিং সিস্টেম থ্রেডের জন্য একটি সিডিউল তৈরি করে এবং নির্দিষ্ট সময়ের মধ্যে থ্রেড চালায়। তবে Java নিজেই থ্রেড সিডিউলিং কন্ট্রোল করে না, এটি OS-এ নির্ভর করে।
- Thread Execution:
- একাধিক থ্রেড সমান্তরালভাবে কাজ করে। তারা CPU কোর বা থ্রেড সিডিউলার দ্বারা টাস্কগুলো একসাথে বা পালাক্রমে কার্যকরী হয়।
- Thread Synchronization:
- যখন একাধিক থ্রেড একে অপরের সাথে সংযুক্ত অবস্থায় কাজ করে, তখন synchronization প্রয়োজন হয়।
synchronizedকিওয়ার্ড ব্যবহারের মাধ্যমে আপনি একটি ব্লক বা মেথডকে সিঙ্ক্রোনাইজড করতে পারেন, যাতে একসাথে একাধিক থ্রেড কাজ না করে।
- যখন একাধিক থ্রেড একে অপরের সাথে সংযুক্ত অবস্থায় কাজ করে, তখন synchronization প্রয়োজন হয়।
Thread Synchronization উদাহরণ:
class Counter {
private int count = 0;
public synchronized void increment() { // সিঙ্ক্রোনাইজড মেথড
count++;
}
public int getCount() {
return count;
}
}
public class ThreadSynchronizationExample {
public static void main(String[] args) {
Counter counter = new Counter();
// Thread 1
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// Thread 2
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
t1.start(); // Thread 1 চালু করা
t2.start(); // Thread 2 চালু করা
try {
t1.join(); // থ্রেড 1 শেষ হওয়ার অপেক্ষা
t2.join(); // থ্রেড 2 শেষ হওয়ার অপেক্ষা
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final count: " + counter.getCount()); // Output: 2000
}
}
Java-তে multithreading ব্যবহার করে আপনি একাধিক কাজ সমান্তরালভাবে করতে পারেন, যা সফটওয়্যারের পারফরম্যান্স এবং রেসপন্সিভনেস বাড়াতে সাহায্য করে। আপনি Thread Class অথবা Runnable Interface ব্যবহার করে থ্রেড তৈরি করতে পারেন এবং তাদের start() মেথড দ্বারা চালু করতে পারেন। যদি একাধিক থ্রেড একই রিসোর্স অ্যাক্সেস করে, তবে সিঙ্ক্রোনাইজেশন প্রয়োজন হতে পারে।
Custom Exception হল একটি এক্সসেপশন ক্লাস যা আপনি নিজে তৈরি করেন। এটি সাধারণত তখন ব্যবহৃত হয় যখন standard Java exceptions আপনার প্রয়োজন পূরণ করতে সক্ষম হয় না। Custom exception তৈরি করতে হলে আপনাকে Exception বা RuntimeException ক্লাসের একটি সাবক্লাস তৈরি করতে হবে।
নিচে একটি Custom Exception তৈরি এবং এটি ব্যবহার করার উদাহরণ দেওয়া হলো:
1. Custom Exception ক্লাস তৈরি করা
// Custom exception class
public class InvalidAgeException extends Exception {
// Constructor with custom message
public InvalidAgeException(String message) {
super(message); // Pass the message to the parent (Exception) class
}
}
এখানে InvalidAgeException হল একটি custom checked exception যেটি Exception ক্লাস থেকে ইনহেরিট করা হয়েছে। এটি একটি কাস্টম মেসেজ গ্রহণ করে, যা এক্সসেপশন ঘটানোর সময় ব্যবহার করা হবে।
2. Custom Exception ব্যবহার করা
এখন আমরা একটি ক্লাস তৈরি করব যেখানে আমরা আমাদের custom exception ব্যবহার করব। উদাহরণস্বরূপ, আমরা একটি বয়স যাচাই করার প্রোগ্রাম তৈরি করব যেখানে একটি নির্দিষ্ট বয়সের নিচে হলে custom exception ছোড়া হবে।
public class AgeValidator {
// Method to validate age
public static void validateAge(int age) throws InvalidAgeException {
if (age < 18) {
// Throwing the custom exception if age is less than 18
throw new InvalidAgeException("Age must be 18 or older to register.");
} else {
System.out.println("Age is valid.");
}
}
public static void main(String[] args) {
try {
// Test case: Age less than 18, which will throw the custom exception
validateAge(16); // This will throw InvalidAgeException
} catch (InvalidAgeException e) {
// Handling the custom exception
System.out.println("Error: " + e.getMessage());
}
try {
// Test case: Valid age
validateAge(20); // This will not throw an exception
} catch (InvalidAgeException e) {
// This block will not be executed
System.out.println("Error: " + e.getMessage());
}
}
}
উদাহরণ ব্যাখ্যা:
InvalidAgeExceptionএকটি কাস্টম এক্সসেপশন ক্লাস, যাExceptionক্লাস থেকে ইনহেরিট করে। এতে একটি কনস্ট্রাক্টর রয়েছে যা একটি মেসেজ নেয়।validateAge()মেথডটি বয়স যাচাই করে। যদি বয়স ১৮ এর নিচে হয়, তাহলেInvalidAgeExceptionছুড়ে দেওয়া হয়। অন্যথায়, এটি একটি "Age is valid" বার্তা প্রিন্ট করে।main()মেথডে, দুটি বয়স যাচাই করা হয়েছে। প্রথমে ১৬ বছর বয়স দিয়ে মেথডটি কল করলে কাস্টম এক্সসেপশন ছোড়া হবে এবং মেসেজ প্রিন্ট হবে। পরবর্তী ২০ বছর বয়স দিয়ে কল করলে, "Age is valid." প্রিন্ট হবে।
Output:
Error: Age must be 18 or older to register.
Age is valid.
- Custom exceptions Java তে তৈরি করা খুবই সহজ। আপনি যখন চাইবেন, তখন নিজের প্রয়োজন অনুযায়ী কাস্টম এক্সসেপশন তৈরি করতে পারেন।
- কাস্টম এক্সসেপশন ক্লাসগুলি checked exception হতে পারে (যেমন এখানে আমরা
Exceptionথেকে ইনহেরিট করেছি), অথবা unchecked exception (যেমনRuntimeExceptionথেকে ইনহেরিট করা) হতে পারে। - কাস্টম এক্সসেপশন তৈরি এবং ব্যবহার করলে আপনার প্রোগ্রামটি আরও readable এবং maintainable হয়ে ওঠে, কারণ আপনি স্পষ্টভাবে নির্দিষ্ট ধরনের ভুলগুলি চিহ্নিত করতে পারবেন।
Java-তে ফাইল হ্যান্ডলিং করার জন্য মূলত java.io প্যাকেজ ব্যবহার করা হয়। এখানে FileReader এবং FileWriter ক্লাস ব্যবহার করা যেতে পারে ফাইল থেকে ডেটা পড়া এবং অন্য ফাইলে লেখার জন্য।
উদাহরণ:
ধরা যাক, আমাদের কাছে একটি ফাইল রয়েছে যার নাম source.txt, এবং আমরা সেটি থেকে ডেটা পড়ে একটি নতুন ফাইলে destination.txt লিখতে চাই।
কোড উদাহরণ:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileCopyExample {
public static void main(String[] args) {
// ফাইলের নাম
String sourceFile = "source.txt";
String destinationFile = "destination.txt";
// FileReader এবং FileWriter তৈরি করা
try (FileReader fr = new FileReader(sourceFile); // ফাইল থেকে ডেটা পড়ার জন্য
FileWriter fw = new FileWriter(destinationFile)) { // নতুন ফাইলে ডেটা লেখার জন্য
int character;
// ফাইল থেকে একটি করে অক্ষর পড়া এবং destination ফাইলে লেখার জন্য
while ((character = fr.read()) != -1) {
fw.write(character); // একে একে অক্ষর destination ফাইলে লিখে যাবে
}
System.out.println("ডেটা সফলভাবে source.txt থেকে destination.txt তে কপি করা হয়েছে।");
} catch (IOException e) {
e.printStackTrace(); // যদি কোন IOException ঘটে
}
}
}
কোড ব্যাখ্যা:
- FileReader: এই ক্লাসটি একটি ফাইল থেকে অক্ষর (characters) পড়তে ব্যবহৃত হয়। এটি ফাইলের মধ্যে থেকে ডেটা রিড করে।
- FileWriter: এই ক্লাসটি একটি ফাইলে অক্ষর (characters) লেখার জন্য ব্যবহৃত হয়।
try-with-resources: এখানেFileReaderএবংFileWriterক্লাসগুলোকেtry-with-resourcesব্লকে ব্যবহার করা হয়েছে, যা নিশ্চিত করে যে ফাইল রিসোর্সগুলো কোড ব্লক থেকে বের হওয়ার পর স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে।read():read()মেথডটি ফাইল থেকে একটি করে অক্ষর পড়তে ব্যবহৃত হয়। এটি-1রিটার্ন করবে যখন ফাইলের শেষে পৌঁছে যাবে।write():write()মেথডটি একটি করে অক্ষর ফাইলের মধ্যে লেখার জন্য ব্যবহৃত হয়।
ফাইল source.txt এর উদাহরণ (প্রথমে ফাইলটি তৈরি করুন):
Hello, this is a test file.
We are copying its contents to another file.
আউটপুট:
ডেটা সফলভাবে source.txt থেকে destination.txt তে কপি করা হয়েছে।
এটি যখন রান করবেন, তখন source.txt এর সমস্ত কন্টেন্ট destination.txt ফাইলে কপি হয়ে যাবে।
Factory Design Pattern হল একটি Creational Design Pattern যা একটি অবজেক্ট তৈরি করার জন্য একটি ইন্টারফেস প্রদান করে, কিন্তু অবজেক্টের নির্দিষ্ট শ্রেণী (class) নির্বাচনের কাজটি সাবক্লাসের উপর নির্ভর করে। এর প্রধান লক্ষ্য হল কোডের নমনীয়তা এবং পরিবর্তনযোগ্যতা বৃদ্ধি করা, কারণ এটি ক্লাসের সৃষ্টির প্রক্রিয়া client থেকে আড়াল করে রাখে এবং client কে নির্দিষ্ট শ্রেণীর (class) ব্যাপারে চিন্তা না করতে দেয়।
Factory Design Pattern ব্যবহার করার সুবিধা:
- Encapsulation: অবজেক্ট নির্মাণের জটিলতা লুকিয়ে রাখা হয়।
- Loose Coupling: ক্লায়েন্ট কোড প্রযোজ্য অবজেক্টের বাস্তবায়ন থেকে আলাদা থাকে।
- Flexibility: নতুন ক্লাস যোগ করা সহজ হয়, কারণ
Factoryঅবজেক্ট নির্মাণের জন্য নির্দিষ্ট ক্লাসগুলির উপর নির্ভরশীল নয়।
Factory Design Pattern Example:
ধরা যাক, আমরা একটি Shape ফ্যাক্টরি তৈরি করতে চাই যা বিভিন্ন ধরনের Shape (যেমন Circle, Rectangle, Square) তৈরি করতে পারে। আমাদের ফ্যাক্টরি ক্লাস একটি নির্দিষ্ট ধরনের অবজেক্ট তৈরি করবে যেটি Shape ইন্টারফেস অনুসরণ করবে।
1. Shape Interface:
public interface Shape {
void draw();
}
2. Concrete Classes:
Circle, Rectangle, এবং Square ক্লাসগুলি Shape ইন্টারফেস ইমপ্লিমেন্ট করবে এবং তাদের নিজস্ব draw() মেথড রূপান্তর করবে।
// Circle class
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
// Rectangle class
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
// Square class
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
3. ShapeFactory Class:
এটি একটি ফ্যাক্টরি ক্লাস যা Shape অবজেক্ট তৈরি করবে।
public class ShapeFactory {
// Use getShape method to get object of type shape
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
4. Factory Pattern Test Class:
এটি ShapeFactory ক্লাসের মাধ্যমে বিভিন্ন ধরনের Shape অবজেক্ট তৈরি করবে।
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
// Get an object of Circle and call its draw method
Shape shape1 = shapeFactory.getShape("CIRCLE");
shape1.draw();
// Get an object of Rectangle and call its draw method
Shape shape2 = shapeFactory.getShape("RECTANGLE");
shape2.draw();
// Get an object of Square and call its draw method
Shape shape3 = shapeFactory.getShape("SQUARE");
shape3.draw();
}
}
Output:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
ব্যাখ্যা:
- Shape ইন্টারফেসটি সাধারণভাবে
draw()মেথড ঘোষণা করেছে। - Circle, Rectangle, এবং Square ক্লাসগুলি
Shapeইন্টারফেসকে ইমপ্লিমেন্ট করে তাদের নিজস্বdraw()মেথডে বিভিন্ন আউটপুট প্রদর্শন করেছে। - ShapeFactory ক্লাসটি
getShape()মেথডে একটি নির্দিষ্ট শ্রেণী (এখানেCircle,Rectangle,Square) রিটার্ন করছে। - FactoryPatternDemo ক্লাসটি ফ্যাক্টরি প্যাটার্নের মাধ্যমে অবজেক্ট তৈরি করে এবং সেই অবজেক্টের
draw()মেথড কল করছে।
Factory Design Pattern হল একটি শক্তিশালী প্যাটার্ন যা অ্যাপ্লিকেশনগুলোতে ফ্যাক্টরি ক্লাসের মাধ্যমে অবজেক্ট নির্মাণের সুবিধা প্রদান করে। এটি কোডের নমনীয়তা এবং সম্প্রসারণযোগ্যতা বাড়াতে সহায়তা করে।
Read more