concurrency
জাভা শুরু থেকেই সংক্ষিপ্ত বিবেচনার সাথে সংজ্ঞায়িত হয়েছিল। হিসাবে প্রায়ই উল্লেখ করা হয়েছে ভাগ করা মিউটবেল সমস্যাযুক্ত। থ্রেডটি সচেতন না হয়েই একটি জিনিস অন্য থ্রেডের পিছনে আরেকটি পরিবর্তন করতে পারে।
অনেকগুলি মাল্টিথ্রেডেড সি ++ বাগ রয়েছে যা একটি ভাগ করা স্ট্রিংয়ের কারণে ক্রপ হয়ে গেছে - যেখানে একটি মডিউল মনে করেছিল যে এটি পরিবর্তন করা নিরাপদ যখন কোডের অন্য একটি মডিউল এটিতে একটি পয়েন্টার সংরক্ষণ করেছিল এবং আশা করে যে এটি একই থাকবে।
এর 'সমাধান' হ'ল প্রতিটি বর্গ এটি পরিবর্তনযোগ্য অবজেক্টগুলির প্রতিরক্ষামূলক অনুলিপি তৈরি করে। পরিবর্তনীয় স্ট্রিংয়ের জন্য, অনুলিপিটি তৈরি করা ও (এন)। অপরিবর্তনীয় স্ট্রিংয়ের জন্য, অনুলিপি তৈরি করা ও (1) কারণ এটি অনুলিপি নয়, এটি একই জিনিস যা পরিবর্তন করতে পারে না।
বহুবিবাহিত পরিবেশে, অপরিবর্তনীয় জিনিসগুলি সর্বদা নিরাপদে একে অপরের মধ্যে ভাগ করা যায়। এটি মেমরির ব্যবহারের সামগ্রিক হ্রাস বাড়ে এবং মেমরি ক্যাশে উন্নত করে।
নিরাপত্তা
কনস্ট্রাক্টরদের পক্ষে যুক্তি হিসাবে প্রায়শই বার স্ট্রিংগুলি পাস করা হয় - নেটওয়ার্ক সংযোগ এবং প্রোটোকল দুটি যা সবচেয়ে সহজে মনে আসে। মৃত্যুদন্ড কার্যকর করার পরে একটি নির্ধারিত সময়ে এটিকে পরিবর্তন করতে সক্ষম হওয়ায় সুরক্ষা সমস্যা দেখা দিতে পারে (ফাংশনটি ভেবেছিল যে এটি একটি মেশিনের সাথে সংযোগ স্থাপন করছে, তবে অন্যটিতে ডাইভার্ট করা হয়েছিল, তবে অবজেক্টের সমস্ত কিছুই দেখে মনে হচ্ছে এটি প্রথমটির সাথে সংযুক্ত ... এটি এমনকি একই স্ট্রিং)।
জাভা একটিকে প্রতিবিম্বিত করতে দেয় - এবং এর জন্য পরামিতিগুলি স্ট্রিং। একের স্ট্রিং দিয়ে যাওয়ার বিপদ যা প্রতিফলিত করে এমন অন্য পদ্ধতির পথে সংশোধন করতে পারে। এটা খুব খারাপ.
হ্যাশ কী
হ্যাশ টেবিল সর্বাধিক ব্যবহৃত ডেটা স্ট্রাকচার। ডেটা স্ট্রাকচারের কীগুলি প্রায়শই স্ট্রিং থাকে। অপরিবর্তনীয় স্ট্রিং থাকার অর্থ হ'ল (উপরে হিসাবে) হ্যাশ টেবিলের প্রতিবার হ্যাশ কীটির অনুলিপি তৈরি করার দরকার নেই। যদি স্ট্রিংগুলি পরিবর্তনযোগ্য হয় এবং হ্যাশ টেবিলটি এটি তৈরি না করে, তবে দূরত্বের কিছুতে হ্যাশ কীটি পরিবর্তন করা সম্ভব হবে।
জাভাতে অবজেক্টটি যেভাবে কাজ করে, তা হ'ল সবকিছুতে হ্যাশ কী থাকে (হ্যাশকোড () পদ্ধতি দ্বারা অ্যাক্সেস করা হয়)। অপরিবর্তনীয় স্ট্রিং থাকার অর্থ হ্যাশকোড ক্যাশে করা যায়। স্ট্রিংগুলি প্রায়শই হ্যাশগুলির কী হিসাবে ব্যবহৃত হয় তা বিবেচনা করে, এটি একটি গুরুত্বপূর্ণ পারফরম্যান্স বুস্ট সরবরাহ করে (প্রতিবার হ্যাশ কোডটি পুনরায় গণনা করার চেয়ে)।
সাবস্ট্রিং
স্ট্রিং অপরিবর্তনীয় হতে পারে, তথ্য কাঠামোর পিছনে থাকা অন্তর্নিহিত অক্ষর অ্যারেও অপরিবর্তনীয়। এটি করার substring
পদ্ধতিটিতে নির্দিষ্ট অপ্টিমাইজেশনের অনুমতি দেয় (এগুলি অগত্যা করা হয় না - এটি কিছু মেমরি ফাঁসের সম্ভাবনাও প্রবর্তন করে)।
যদি তুমি করো:
String foo = "smiles";
String bar = foo.substring(1,5);
এর মান bar
'মাইল'। যাইহোক, উভয় foo
এবং bar
একই অক্ষর অ্যারে দ্বারা সমর্থন করা যেতে পারে, আরও অক্ষর অ্যারের ইনস্ট্যান্টেশন কমিয়ে আনা বা এটি অনুলিপি করা - স্ট্রিংয়ের মধ্যে বিভিন্ন স্টার্ট এবং শেষ পয়েন্টগুলি ব্যবহার করে।
foo | | (0, 6)
VV
হাসি
^ ^
বার | | (1, 5)
এখন, এর (মেমরি ফুটো) এর নেতিবাচক দিকটি হ'ল যদি কারও কাছে 1k লম্বা স্ট্রিং থাকে এবং প্রথম এবং দ্বিতীয় চরিত্রের সাবস্ট্রিং গ্রহণ করে, এটিও 1k দীর্ঘ অক্ষরের অ্যারে দ্বারা সমর্থনযুক্ত হবে। এই অক্ষর মেমরিতে থাকবে এমনকি যদি মূল চরিত্রের পুরো অক্ষরের অ্যারের মান থাকে তবে আবর্জনা সংগ্রহ করা হত।
এটি স্ট্রিং-এ জেডিকে 6 বি 14 থেকে দেখতে পাবেন (নিম্নলিখিত কোডটি জিপিএল ভি 2 উত্স থেকে প্রাপ্ত এবং উদাহরণ হিসাবে ব্যবহৃত হয়)
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.offset = 0;
this.count = count;
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
স্ট্রিং কীভাবে প্যাকেজ স্তরের স্ট্রিং কনস্ট্রাক্টরকে ব্যবহার করে যা অ্যারের কোনও অনুলিপি জড়িত না এবং এটি আরও দ্রুত হবে (সম্ভবত কিছু বড় অ্যারে প্রায় রাখার ব্যয়ে - যদিও বড় অ্যারেগুলি নকল না করে)।
উল্লেখ্য যে উপরের কোডটি জাভা ১.6 এর জন্য। জাভা ১.7.০.০66 এ স্ট্রিংয়ের অভ্যন্তরীণ উপস্থাপনায় পরিবর্তনগুলিতে নথিভুক্ত হিসাবে স্ট্রিংং কনস্ট্রাক্টর বাস্তবায়নের উপায়টি জাভা ১.7 দিয়ে পরিবর্তিত হয়েছিল - যা আমি উপরে উল্লিখিত মেমরি ফাঁসকে বিঙ্গিত করে তোলে
। জাভা সম্ভবত প্রচুর স্ট্রিং ম্যানিপুলেশন সহ একটি ভাষা হিসাবে দেখা যায় নি এবং তাই একটি স্ট্রিংয়ের জন্য পারফরম্যান্স বাড়ানো ভাল জিনিস ছিল। এখন, স্ট্রিংগুলিতে বিশাল আকারের এক্সএমএল নথি সংরক্ষণ করা হয় যা কখনই সংগ্রহ করা হয় না, এটি একটি ইস্যুতে পরিণত হয় ... এবং সুতরাং String
স্ট্রাস্টিং সহ একই অন্তর্নিহিত অ্যারেটি ব্যবহার না করার পরিবর্তনে , যাতে আরও বড় অক্ষরের অ্যারে আরও দ্রুত সংগ্রহ করা যায়।
স্ট্যাক অপব্যবহার করবেন না
এক পারে পরিবর্তে প্রায় অপরিবর্তনীয় স্ট্রিং রেফারেন্স পরিবর্তনশীলতা সঙ্গে সমস্যা এড়ানোর জন্য স্ট্রিং এর মান পাস। তবে, বড় স্ট্রিং সহ, স্ট্যাকটিতে এটি পাস করা ... সিস্টেমের কাছে আপত্তিজনক হবে (পুরো xML ডকুমেন্টকে স্ট্যাকের স্ট্রিং হিসাবে রাখা এবং তারপরে সেগুলি বন্ধ করে দেওয়া বা তাদের সাথে চালিয়ে যাওয়া ...)।
ছাড়ের সম্ভাবনা
মঞ্জুর, স্ট্রিংগুলি কেন অপরিবর্তনীয় হওয়া উচিত তার প্রাথমিক প্রেরণা ছিল না, তবে যখন কেউ অপরিবর্তনীয় স্ট্রিংস একটি ভাল জিনিস এর যুক্তি দেখছেন, এটি অবশ্যই বিবেচনা করার মতো বিষয়।
যে কেউ স্ট্রিংসের সাথে কিছুটা কাজ করেছেন জানেন যে তারা স্মৃতি চুষতে পারেন। এটি বিশেষভাবে সত্য যখন আপনি কিছু সময়ের জন্য স্থায়ীভাবে থাকা ডাটাবেসগুলি থেকে ডেটা টানার মতো কাজ করেন। এই স্টিংগুলির সাথে অনেক সময়, তারা বারবার একই স্ট্রিং হয় (প্রতিটি সারির জন্য একবার)।
অনেক বড় আকারের জাভা অ্যাপ্লিকেশন বর্তমানে স্মৃতিতে বাধা রয়েছে। পরিমাপ থেকে প্রমাণিত হয়েছে যে জাভা হিপ লাইভ ডেটা এই ধরণের অ্যাপ্লিকেশনগুলিতে সেট করা প্রায় 25% স্ট্রিং অবজেক্ট দ্বারা গ্রাস করা হয়। আরও, স্ট্রিং অবজেক্টগুলির প্রায় অর্ধেকটি নকল, যেখানে সদৃশ মানে স্ট্রিং 1.equals (স্ট্রিং 2) সত্য। স্তূপে নকল স্ট্রিং অবজেক্টগুলি থাকা, মূলত, কেবল স্মৃতির অপচয়। ...
জাভা 8 আপডেট 20 দিয়ে, JEP 192 (উপরে উত্সাহিত অনুপ্রেরণা) এটি সমাধানের জন্য প্রয়োগ করা হচ্ছে। স্ট্রিং ডুপ্লিকেশন কীভাবে কাজ করে তার বিশদ না জেনে স্ট্রিংগুলি নিজেরাই অপরিবর্তনীয়। আপনি স্ট্রিংবিল্ডারদের সদৃশ করতে পারবেন না কারণ তারা পরিবর্তন করতে পারে এবং আপনি চান না যে কেউ আপনার অধীনে থেকে কিছু পরিবর্তন করবে। অপরিবর্তনীয় স্ট্রিংস (সেই স্ট্রিং পুলের সাথে সম্পর্কিত) এর অর্থ হল আপনি যেতে পারেন এবং যদি আপনি দুটি স্ট্রিং একইরকম দেখতে পান তবে আপনি অন্যটির সাথে একটি স্ট্রিং রেফারেন্স নির্দেশ করতে পারেন এবং আবর্জনা সংগ্রহকারীকে সদ্য ব্যবহৃত না হওয়াটিকে গ্রাস করতে দিন।
অন্যান্য ভাষাসমূহ
উদ্দেশ্য সি (যা জাভা পূর্বাভাস দেয়) আছে NSString
এবং NSMutableString
।
সি # এবং .NET ডিফল্ট স্ট্রিংয়ের একই নকশার পছন্দগুলি অপরিবর্তনীয়।
লুয়া স্ট্রিংগুলিও অপরিবর্তনীয়।
পাইথন পাশাপাশি।
.তিহাসিকভাবে, লিস্প, স্কিম, স্মলটাক সমস্ত স্ট্রিংকে অন্তর্ভুক্ত করে এবং তাই এটি অপরিবর্তনীয় হতে পারে। আরও আধুনিক গতিশীল ভাষাগুলি প্রায়শই কিছু উপায়ে স্ট্রিং ব্যবহার করে যার প্রয়োজন হয় সেগুলি অপরিবর্তনীয় (এটি স্ট্রিং নাও হতে পারে , তবে এটি অপরিবর্তনীয়)।
উপসংহার
এই ডিজাইনের বিবেচনাগুলি বহুবার ভাষাতে তৈরি করা হয়েছে। এটি সাধারণ sensক্যমত্য যে অপরিবর্তনীয় স্ট্রিংগুলি তাদের সমস্ত বিশ্রীতার জন্য বিকল্পগুলির চেয়ে ভাল এবং সামগ্রিকভাবে আরও ভাল কোড (কম বাগ) এবং দ্রুত এক্সিকিউটেবলের দিকে নিয়ে যায়।