ডিবাগিং ফাইল আপলোড ত্রুটি: একটি বিকাশকারীর যাত্রা৷
ফাইল আপলোড করার সময় ত্রুটির সম্মুখীন হওয়া অনেক ডেভেলপারদের জন্য উত্তরণের রীতি। সম্প্রতি, একটি Node.js API তৈরি করার সময় যা Multer এবং Cloudinaryকে একীভূত করে, আমি একটি হতাশাজনক রোডব্লকের শিকার হয়েছি। আমার API একগুঁয়েভাবে ভয়ঙ্কর "অনির্ধারিত ('পথ' পড়া)" ত্রুটির বৈশিষ্ট্যগুলি পড়তে পারে না। 😩
এই ত্রুটিটি প্রতিবার পপ আপ হয় যখন আমি একটি চিত্র ফাইল সহ একটি POST অনুরোধ পাঠাই, আমার অগ্রগতি বন্ধ করে দেয়। একটি ভাল-রেটেড ইউটিউব টিউটোরিয়াল অনুসরণ করা এবং আমার বাস্তবায়নকে দুবার পরীক্ষা করা সত্ত্বেও, আমি মূল কারণটি চিহ্নিত করতে পারিনি। এটি একটি ক্লাসিক কেস ছিল "এটি ইউটিউবে কাজ করে কিন্তু আমার মেশিনে নয়।"
সমস্যা সমাধানে নিজেকে গর্বিত ব্যক্তি হিসাবে, আমি আমার কোডের প্রতিটি দিক তদন্ত শুরু করেছি। মাল্টার কনফিগারেশন পর্যালোচনা করা থেকে শুরু করে ফাইল আপলোড লজিকটি বিচ্ছিন্নভাবে পরীক্ষা করা পর্যন্ত, আমি একটি সমাধান খুঁজে পেতে দৃঢ়প্রতিজ্ঞ ছিলাম। তবুও, সমস্যাটি অব্যাহত ছিল, আমার আত্মবিশ্বাসকে নাড়া দিয়েছিল।
এই নিবন্ধে, আমি আমার ডিবাগিং যাত্রা ভাগ করব, সঠিক সমস্যাটি হাইলাইট করে এবং কীভাবে আমি শেষ পর্যন্ত এটি সমাধান করেছি। মাল্টার এবং ক্লাউডিনারির সাথে কাজ করার সময় আপনি যদি একই ধরণের ত্রুটির সাথে কুস্তি করছেন, তবে চারপাশে লেগে থাকুন! একসাথে, আমরা সমস্যা সমাধান করব এবং এই চ্যালেঞ্জটি কাটিয়ে উঠব। 🛠️
| আদেশ | ব্যবহারের উদাহরণ |
|---|---|
| multer.diskStorage | Multer-এর জন্য স্টোরেজ ইঞ্জিন কনফিগার করতে ব্যবহৃত হয়, যা গন্তব্যস্থল এবং ফাইলের নামকরণের প্রথার উপর নিয়ন্ত্রণের অনুমতি দেয়।
উদাহরণ: const স্টোরেজ = multer.diskStorage({ গন্তব্য, ফাইলের নাম }); |
| path.resolve | একটি পরম পাথে পাথ বিভাগগুলির একটি ক্রম সমাধান করে৷ নিশ্চিত করে যে ফাইল স্টোরেজ ডিরেক্টরিটি সঠিকভাবে অবস্থিত।
উদাহরণ: path.resolve('./uploads'); |
| cloudinary.uploader.upload | রিসোর্স টাইপ এবং অন্যান্য কনফিগারেশনের বিকল্প সহ ক্লাউডিনারির ক্লাউড স্টোরেজে একটি ফাইল আপলোড করে।
উদাহরণ: cloudinary.uploader.upload(file.path, { resource_type: 'image' }); |
| dotenv.config | একটি .env ফাইল থেকে এনভায়রনমেন্ট ভেরিয়েবল লোড করে process.env, API কীগুলির মতো সংবেদনশীল ডেটার সুরক্ষিত সঞ্চয়স্থান সক্ষম করে৷
উদাহরণ: dotenv.config(); |
| new Date().toISOString().replace(/:/g, '-') | আইএসও ফরম্যাটে একটি টাইমস্ট্যাম্প তৈরি করে এবং ফাইলের নামকরণের প্রথার সাথে সামঞ্জস্য নিশ্চিত করতে হাইফেন দিয়ে কোলন প্রতিস্থাপন করে।
উদাহরণ: নতুন তারিখ().toISOSstring().replace(/:/g, '-'); |
| req.file | সাথে Multer ব্যবহার করার সময় আপলোড করা ফাইলের প্রতিনিধিত্ব করে upload.single মিডলওয়্যার অ্যাক্সেস বৈশিষ্ট্য মত পথ এবং মাইমেটাইপ.
উদাহরণ: const imageFile = req.file; |
| JSON.parse | একটি JSON স্ট্রিংকে জাভাস্ক্রিপ্ট অবজেক্টে রূপান্তর করে। একটি নেস্টেড ঠিকানা বস্তুর মতো জটিল ইনপুট ডেটা পরিচালনার জন্য অপরিহার্য।
উদাহরণ: JSON.parse(req.body.address); |
| supertest | API পরীক্ষা করার জন্য HTTP দাবির জন্য ব্যবহৃত একটি লাইব্রেরি। ইউনিট পরীক্ষার সময় অনুরোধ পাঠানো এবং প্রতিক্রিয়া পরীক্ষা করা সহজ করে।
উদাহরণ: অনুরোধ(অ্যাপ)।পোস্ট('/রুট')।অ্যাটাচ('ফাইল', './test-file.jpg'); |
| bcrypt.hash | স্টোরেজের জন্য নিরাপদে একটি পাসওয়ার্ড হ্যাশ করে। পাসওয়ার্ডের মতো সংবেদনশীল ব্যবহারকারীর ডেটা এনক্রিপ্ট করার জন্য গুরুত্বপূর্ণ।
উদাহরণ: const hashedPassword = await bcrypt.hash(পাসওয়ার্ড, 10); |
| multer.fileFilter | আপলোড করার আগে ফাইলগুলিকে তাদের MIME প্রকারের উপর ভিত্তি করে ফিল্টার করে, শুধুমাত্র ছবি বা নির্দিষ্ট ফাইলের ধরন গ্রহণ করা হয় তা নিশ্চিত করে৷
উদাহরণ: যদি (file.mimetype.startsWith('image/')) কলব্যাক (নাল, সত্য); |
মাল্টার এবং ক্লাউডিনারির সাথে ফাইল আপলোড ওয়ার্কফ্লো বোঝা
উপরে প্রদত্ত স্ক্রিপ্টগুলি একটি Node.js অ্যাপ্লিকেশনে ফাইল আপলোডগুলি পরিচালনা করতে একসাথে কাজ করে৷ এই সেটআপ কেন্দ্রে হয় , মাল্টিপার্ট/ফর্ম-ডেটা পরিচালনার জন্য একটি মিডলওয়্যার, ফাইল আপলোডের জন্য অপরিহার্য। কনফিগারেশন একটি স্টোরেজ ইঞ্জিন ব্যবহার করে সেট আপ দিয়ে শুরু হয় . এটি নিশ্চিত করে যে আপলোড করা ফাইলগুলি একটি মনোনীত ডিরেক্টরিতে সংরক্ষণ করা হয়েছে এবং একটি অনন্য ফাইলের নাম দেওয়া হয়েছে৷ উদাহরণস্বরূপ, একজন ব্যবহারকারী একটি প্রোফাইল ছবি আপলোড করতে পারে, এবং স্ক্রিপ্ট নিশ্চিত করে যে এটি ফাইলের নাম সংঘর্ষ এড়াতে সঠিক অবস্থানে সংরক্ষণ করা হয়েছে। এই পদক্ষেপটি ব্যাকএন্ড সিস্টেমের জন্য অত্যাবশ্যক যার জন্য কাঠামোগত স্টোরেজ প্রয়োজন, যেমন একটি অনলাইন অ্যাপয়েন্টমেন্ট সিস্টেম। 📁
পরবর্তী উপাদান হল একীকরণ , একটি ক্লাউড-ভিত্তিক ছবি এবং ভিডিও ব্যবস্থাপনা পরিষেবা। ফাইলটি সার্ভারে আপলোড হয়ে গেলে, এটি অপ্টিমাইজ করা স্টোরেজ এবং পুনরুদ্ধারের জন্য ক্লাউডিনারিতে স্থানান্তরিত হয়। এই পদ্ধতিটি স্কেলেবল অ্যাপ্লিকেশনগুলিতে বিশেষভাবে কার্যকর, যেখানে স্থানীয় স্টোরেজ একটি বাধা হয়ে উঠতে পারে। উদাহরণস্বরূপ, হাজার হাজার ডাক্তারের প্রোফাইল ছবি সংরক্ষণ করে একটি মেডিকেল পোর্টাল এই দায়িত্বটি ক্লাউডিনারিকে অফলোড করতে পারে, যাতে ছবিগুলি বিশ্বব্যাপী উচ্চ কর্মক্ষমতা সহ পাওয়া যায় তা নিশ্চিত করে৷ এই প্রক্রিয়া বিরামহীন, যেমন দেখা যায় ফাংশন, যা পর্দার পিছনে ভারী উত্তোলন পরিচালনা করে। 🌐
দ মিডলওয়্যারে আপলোড লজিক আলাদা করে এবং কন্ট্রোলারদের কাছে ডেটা হ্যান্ডলিং অর্পণ করে স্ক্রিপ্ট মডুলারিটি এবং স্পষ্টতা নিশ্চিত করে। উদাহরণস্বরূপ, রুট আহ্বান করে আপলোড করা চিত্র প্রক্রিয়াকরণের পরে ফাংশন। উদ্বেগের এই বিচ্ছেদ কোডটিকে পরীক্ষা করা এবং বজায় রাখা সহজ করে তোলে। একটি সমস্যা ডিবাগ করার কল্পনা করুন যেখানে শুধুমাত্র কিছু ক্ষেত্র প্রক্রিয়া করা হচ্ছে; এই কাঠামোর সাথে, সমস্যাটি চিহ্নিত করা এবং সমাধান করা আরও সহজ হয়ে যায়। এই ধরনের নকশা শুধুমাত্র সর্বোত্তম অনুশীলন নয় বরং মাপযোগ্য অ্যাপ্লিকেশনগুলির জন্য একটি প্রয়োজনীয়তা। 🛠️
অবশেষে, কন্ট্রোলার স্ক্রিপ্ট ইনকামিং ডেটা যাচাই করে, নিশ্চিত করে যে ইমেল এবং পাসওয়ার্ডের মতো ক্ষেত্রগুলি নির্দিষ্ট মানদণ্ড পূরণ করে। উদাহরণস্বরূপ, শুধুমাত্র বৈধ ইমেল গ্রহণ করা হয়, এবং পাসওয়ার্ড ব্যবহার করে হ্যাশ করা হয় ডাটাবেসে সংরক্ষণ করার আগে। এটি ব্যবহারকারীর অভিজ্ঞতা এবং নিরাপত্তা উভয়ই উন্নত করে। তাছাড়া, স্ক্রিপ্ট জাভাস্ক্রিপ্ট অবজেক্টে JSON স্ট্রিং পার্স করে ঠিকানার মতো জটিল ক্ষেত্র পরিচালনা করে। এই নমনীয়তা গতিশীল ইনপুট পরিচালনার জন্য অনুমতি দেয়, যেমন বহু-লাইন ঠিকানা বা কাঠামোগত ডেটা গ্রহণ করা। এই সমস্ত উপাদানগুলি একত্রিত করে একটি শক্তিশালী, পুনঃব্যবহারযোগ্য এবং দক্ষ ফাইল আপলোড সিস্টেম তৈরি করে যা বাস্তব-বিশ্বের অ্যাপ্লিকেশনের জন্য তৈরি করা হয়েছে। 🚀
"অনির্ধারিত বৈশিষ্ট্যগুলি পড়তে পারে না" ত্রুটি বোঝা এবং সমাধান করা
এই সমাধানটি এক্সপ্রেস, মাল্টার এবং ক্লাউডিনারির সাথে Node.js ব্যবহার করে একটি মডুলার ব্যাকএন্ড পদ্ধতি প্রদর্শন করে। আমরা সমস্যাটি সমাধান করতে ফাইল আপলোড এবং ত্রুটি পরিচালনা করি৷
// cloudinaryConfig.jsimport { v2 as cloudinary } from 'cloudinary';import dotenv from 'dotenv';dotenv.config();const connectCloudinary = async () => {cloudinary.config({cloud_name: process.env.CLOUDINARY_NAME,api_key: process.env.CLOUDINARY_API_KEY,api_secret: process.env.CLOUDINARY_SECRET_KEY,});};export default connectCloudinary;// Ensures Cloudinary setup is initialized before uploads
ফাইল আপলোডের জন্য মডুলার মাল্টার কনফিগারেশন
এখানে, আমরা ক্লাউডিনারির সাথে প্রক্রিয়া করার আগে ফাইল আপলোডগুলিকে সুরক্ষিতভাবে পরিচালনা করতে এবং স্থানীয়ভাবে সংরক্ষণ করার জন্য মাল্টারকে কনফিগার করি।
// multerConfig.jsimport multer from 'multer';import path from 'path';const storage = multer.diskStorage({destination: function (req, file, callback) {callback(null, path.resolve('./uploads'));},filename: function (req, file, callback) {callback(null, new Date().toISOString().replace(/:/g, '-') + '-' + file.originalname);},});const fileFilter = (req, file, callback) => {if (file.mimetype.startsWith('image/')) {callback(null, true);} else {callback(new Error('Only image files are allowed!'), false);}};const upload = multer({ storage, fileFilter });export default upload;// Ensures uploaded files meet specific conditions
ফাইল আপলোডগুলি পরিচালনা করার জন্য API রুট৷
এই স্ক্রিপ্টটি ফর্ম বৈধতা এবং ক্লাউডিনারি ফাইল আপলোড সহ ডাক্তার তৈরি পরিচালনার জন্য API রুট সেট আপ করে।
// adminRoute.jsimport express from 'express';import { addDoctor } from '../controllers/adminController.js';import upload from '../middlewares/multerConfig.js';const adminRouter = express.Router();// Endpoint for adding doctorsadminRouter.post('/add-doctor', upload.single('image'), addDoctor);export default adminRouter;// Routes the request to the appropriate controller function
ক্লাউডিনারির সাথে অনুরোধ প্রক্রিয়া এবং ইন্টারঅ্যাক্ট করার জন্য কন্ট্রোলার ফাংশন
এই স্ক্রিপ্টটি ইনপুট যাচাইকরণ, পাসওয়ার্ড হ্যাশ করা এবং ক্লাউডিনারিতে ছবি আপলোড করার জন্য সার্ভার-সাইড লজিক চিত্রিত করে।
// adminController.jsimport bcrypt from 'bcrypt';import { v2 as cloudinary } from 'cloudinary';import doctorModel from '../models/doctorModel.js';const addDoctor = async (req, res) => {try {const { name, email, password, speciality, degree, experience, about, fees, address } = req.body;const imageFile = req.file;if (!imageFile) throw new Error('Image file is required');const hashedPassword = await bcrypt.hash(password, 10);const imageUpload = await cloudinary.uploader.upload(imageFile.path, { resource_type: 'image' });const doctorData = { name, email, password: hashedPassword, speciality, degree,experience, about, fees, address: JSON.parse(address), image: imageUpload.secure_url, date: Date.now() };const newDoctor = new doctorModel(doctorData);await newDoctor.save();res.json({ success: true, message: 'Doctor added successfully' });} catch (error) {res.json({ success: false, message: error.message });}};export { addDoctor };// Manages API logic and ensures proper data validation
পরীক্ষা এবং বৈধতা
এই ইউনিট পরীক্ষা একাধিক পরিস্থিতিতে সঠিকভাবে শেষ পয়েন্ট ফাংশন নিশ্চিত করে।
// adminRoute.test.jsimport request from 'supertest';import app from '../app.js';describe('Add Doctor API', () => {it('should successfully add a doctor', async () => {const response = await request(app).post('/admin/add-doctor').field('name', 'Dr. Smith').field('email', 'drsmith@example.com').field('password', 'strongpassword123').attach('image', './test-assets/doctor.jpg');expect(response.body.success).toBe(true);});});// Validates success scenarios and API response structure
উন্নত মাল্টার এবং ক্লাউডিনারি টেকনিকের সাহায্যে ফাইল আপলোড উন্নত করা
একটি ফাইল আপলোড পরিচালনা করার সময় অ্যাপ্লিকেশন, ত্রুটি পরিচালনা এবং কনফিগারেশন অপ্টিমাইজ করা নির্ভরযোগ্য API তৈরির জন্য অত্যন্ত গুরুত্বপূর্ণ। একটি সাধারণ চ্যালেঞ্জ দেখা দেয় যখন ভুল কনফিগারেশন ত্রুটির দিকে নিয়ে যায় যেমন "অনির্ধারিত বৈশিষ্ট্যগুলি পড়তে পারে না।" ক্লায়েন্ট অনুরোধে ফাইল আপলোড কী এবং মিডলওয়্যার কনফিগারেশনের মধ্যে অমিলের কারণে এটি প্রায়শই ঘটে। উদাহরণস্বরূপ, থান্ডার ক্লায়েন্টে, ফাইল ইনপুট কী এর সাথে মেলে তা নিশ্চিত করা পরামিতি একটি ঘন তত্ত্বাবধান. এই ছোট বিস্তারিত সংশোধন অনেক সমস্যা সমাধান করতে পারেন. ⚙️
আরেকটি উন্নত বিবেচনা রানটাইম বৈধতা যোগ করা হয়. মাল্টারের ফাংশনটি ফাইলগুলিকে প্রত্যাখ্যান করার জন্য কনফিগার করা যেতে পারে যা নির্দিষ্ট মানদণ্ড পূরণ করে না, যেমন ফাইলের ধরন বা আকার। উদাহরণস্বরূপ, শুধুমাত্র ছবি দিয়ে অনুমতি দেওয়া শুধু নিরাপত্তাই বাড়ায় না কিন্তু অবৈধ আপলোড রোধ করে ব্যবহারকারীর অভিজ্ঞতাও উন্নত করে। এটি ডাক্তার প্রোফাইল পরিচালনার মতো পরিস্থিতিতে বিশেষভাবে কার্যকর, যেখানে শুধুমাত্র বৈধ চিত্র বিন্যাস সংরক্ষণ করা উচিত। ক্লাউডিনারির রূপান্তরগুলির সাথে মিলিত, এটি নিশ্চিত করে যে আপলোড করা ফাইলগুলি দক্ষতার সাথে সংরক্ষণ করা হয়েছে। 📸
সবশেষে, আপলোডের সময় শক্তিশালী লগিং মেকানিজম একীভূত করা ডিবাগিংয়ে সাহায্য করতে পারে। উদাহরণস্বরূপ, যেমন লাইব্রেরি সুবিধা বা প্রতিটি আপলোড প্রচেষ্টার বিশদ বিবরণ লগ করার জন্য নিদর্শনগুলি সনাক্ত করতে সহায়তা করতে পারে যা ত্রুটির দিকে পরিচালিত করে। বিকাশকারীরা তাদের ইনপুট সংশোধন করার জন্য ব্যবহারকারীদের গাইড করতে কাঠামোগত ত্রুটি প্রতিক্রিয়াগুলির সাথে এই লগগুলিকে একত্রিত করতে পারে। এই উন্নত দিকগুলির উপর ফোকাস করে, বিকাশকারীরা আধুনিক অ্যাপ্লিকেশনগুলির জন্য অপ্টিমাইজ করা স্কেলযোগ্য, ব্যবহারকারী-বান্ধব API তৈরি করতে পারে। 🚀
- মাল্টারে "অনির্ধারিত বৈশিষ্ট্যগুলি পড়তে পারে না" এর কারণ কী?
- এটি প্রায়শই ঘটে যখন ক্লায়েন্ট অনুরোধের কীটি উল্লেখ করা কীটির সাথে মেলে না . তারা সারিবদ্ধ নিশ্চিত করুন.
- মাল্টারে টাইপের উপর ভিত্তি করে আমি কীভাবে ফাইলগুলি ফিল্টার করতে পারি?
- ব্যবহার করুন মাল্টারে বিকল্প। উদাহরণস্বরূপ, এর সাথে ফাইলের মাইমেটাইপ পরীক্ষা করুন .
- আমি কিভাবে ক্লাউডিনারি দিয়ে নিরাপদ আপলোড নিশ্চিত করব?
- বিকল্প যোগ করে আপলোডের সময় আকার পরিবর্তন করার মতো নিরাপদ রূপান্তর ব্যবহার করুন .
- সংবেদনশীল API কীগুলি সংরক্ষণ করার সর্বোত্তম উপায় কী?
- এপিআই কী সংরক্ষণ করুন a ফাইল করুন এবং তাদের সাথে লোড করুন .
- কেন আমার আপলোড করা ফাইল ক্লাউডিনারিতে দেখা যাচ্ছে না?
- ফাইল পাথ ইন কিনা পরীক্ষা করুন সঠিকভাবে পাস করা হয় এবং ফাইলটি স্থানীয়ভাবে বিদ্যমান।
- আমি কিভাবে ফাইলের নাম ওভাররাইট করা প্রতিরোধ করব?
- একটি কাস্টম ফাইলের নাম ফাংশন ব্যবহার করুন প্রতিটি ফাইলের নামের সাথে একটি অনন্য টাইমস্ট্যাম্প বা UUID যুক্ত করতে।
- আমি কি মাল্টার দিয়ে একাধিক ফাইল আপলোড পরিচালনা করতে পারি?
- হ্যাঁ, ব্যবহার করুন বা একাধিক ফাইলের জন্য আপনার প্রয়োজনীয়তার উপর নির্ভর করে।
- এর ভূমিকা কি মাল্টারে?
- এটি নিশ্চিত করে যে গন্তব্য ডিরেক্টরি সঠিকভাবে একটি পরম পথে সমাধান করা হয়েছে, স্টোরেজ ত্রুটিগুলি এড়িয়ে।
- আমি কিভাবে আপলোড বিবরণ লগ করব?
- লাইব্রেরি ব্যবহার করুন বা ফাইলের নাম, আকার এবং টাইমস্ট্যাম্পের মতো বিবরণ লগ করতে।
- ক্লাউডিনারিতে আপলোড করার আগে চিত্রগুলিকে পুনরায় আকার দেওয়া কি সম্ভব?
- হ্যাঁ, সরাসরি রূপান্তর প্রয়োগ করুন , যেমন প্রস্থ এবং উচ্চতা সমন্বয়।
"অনির্ধারিত বৈশিষ্ট্যগুলি পড়তে পারে না" এর মতো ত্রুটিগুলির সম্মুখীন হওয়া হতাশাজনক হতে পারে, তবে একটি পদ্ধতিগত পদ্ধতির সাথে, এই চ্যালেঞ্জগুলি পরিচালনাযোগ্য হয়ে ওঠে। এর মতো টুল ব্যবহার করা ফাইল পরিচালনার জন্য এবং স্টোরেজ ওয়েব ডেভেলপমেন্টের জন্য একটি শক্তিশালী, মাপযোগ্য সমাধান তৈরি করে।
ব্যবহারিক ডিবাগিং, যেমন কী অমিল চেক করা এবং মিডলওয়্যার সঠিকভাবে কনফিগার করা, মসৃণ বিকাশ নিশ্চিত করে। এই কৌশলগুলি, ত্রুটি লগিং এবং যাচাইকরণের সাথে যুক্ত, সময় এবং শ্রম সাশ্রয় করে। অধ্যবসায় এবং সঠিক পদ্ধতির সাহায্যে, বিকাশকারীরা নির্বিঘ্ন ফাইল আপলোড কার্যকারিতা তৈরি করতে পারে। 🚀
- Node.js-এ মাল্টিপার্ট/ফর্ম-ডেটা পরিচালনার জন্য অফিসিয়াল মাল্টার ডকুমেন্টেশন থেকে শিখেছি। মাল্টার গিটহাব রিপোজিটরি
- ক্লাউড-ভিত্তিক চিত্র আপলোডগুলিকে একীভূত করার জন্য Cloudinary API ডকুমেন্টেশন ব্যবহার করা হয়েছে৷ মেঘলা ডকুমেন্টেশন
- ইমেল ঠিকানার মত ইনপুট ক্ষেত্র যাচাই করার জন্য validator.js থেকে উল্লেখিত উদাহরণ। Validator.js GitHub সংগ্রহস্থল
- Node.js অ্যাপ্লিকেশনে পাসওয়ার্ড সুরক্ষিত করার জন্য bcrypt ডকুমেন্টেশন পর্যালোচনা করা হয়েছে। bcrypt GitHub সংগ্রহস্থল
- স্ট্যাক ওভারফ্লো আলোচনা থেকে ডিবাগিং পদ্ধতি এবং উদাহরণ পরীক্ষা করা হয়েছে। স্ট্যাক ওভারফ্লো