50 پرسش و پاسخ اصلی مصاحبه اصلی جاوا. قسمت 1 50 پرسش و پاسخ اصلی مصاحبه اصلی جاوا. قسمت 2
چند رشته ای
37. چگونه یک رشته (جریان) جدید در جاوا ایجاد کنیم؟
به هر شکلی، ایجاد از طریق استفاده از کلاس Thread اتفاق می افتد. اما ممکن است گزینه هایی در اینجا وجود داشته باشد ...- ما ارث می بریم از
java.lang.Thread
- ما رابطی را پیاده سازی می کنیم که شیء آن کلاس
java.lang.Runnable
سازنده را می پذیردThread
ما از کلاس Thread ارث می بریم
برای ساخت این کار، در کلاس ما ازjava.lang.Thread
. این حاوی متد است run()
که دقیقاً همان چیزی است که ما به آن نیاز داریم. تمام عمر و منطق تاپیک جدید در این روش خواهد بود. این یک نوع main
روش برای یک موضوع جدید است. پس از این، تنها چیزی که باقی می ماند این است که یک شی از کلاس خود ایجاد کنیم و متد را اجرا کنیم start()
، که یک رشته جدید ایجاد می کند و منطق نوشته شده در آن را اجرا می کند. بیایید نگاه بیندازیم:
/**
* Пример того, How создавать треды путем наследования {@link Thread} класса.
*/
class ThreadInheritance extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadInheritance threadInheritance1 = new ThreadInheritance();
ThreadInheritance threadInheritance2 = new ThreadInheritance();
ThreadInheritance threadInheritance3 = new ThreadInheritance();
threadInheritance1.start();
threadInheritance2.start();
threadInheritance3.start();
}
}
خروجی کنسول به صورت زیر خواهد بود:
Thread-1
Thread-0
Thread-2
یعنی حتی در اینجا می بینیم که نخ ها به نوبه خود اجرا نمی شوند، بلکه همانطور که JVM تصمیم گرفت)
پیاده سازی رابط Runnable
اگر مخالف وراثت هستید و/یا قبلاً یکی از کلاسهای دیگر را به ارث بردهاید، میتوانید ازjava.lang.Runnable
. در اینجا در کلاس خود، این رابط را پیاده سازی می کنیم و متد را اجرا می کنیم run()
، همانطور که در آن مثال بود. شما فقط باید اشیاء بیشتری ایجاد کنید Thread
. به نظر می رسد که خطوط بیشتر بدتر هستند. اما می دانیم که ارث چقدر مضر است و بهتر است به هر طریقی از آن اجتناب کنیم ;) بیایید نگاه کنیم:
/**
* Пример того, How создавать треды из интерфейса {@link Runnable}.
* Здесь проще простого - реализуем этот интерфейс и потом передаем в конструктор
* экземпляр реализуемого an object.
*/
class ThreadInheritance implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadInheritance runnable1 = new ThreadInheritance();
ThreadInheritance runnable2 = new ThreadInheritance();
ThreadInheritance runnable3 = new ThreadInheritance();
Thread threadRunnable1 = new Thread(runnable1);
Thread threadRunnable2 = new Thread(runnable2);
Thread threadRunnable3 = new Thread(runnable3);
threadRunnable1.start();
threadRunnable2.start();
threadRunnable3.start();
}
}
و نتیجه اجرا:
Thread-0
Thread-1
Thread-2
38. تفاوت بین یک فرآیند و یک نخ چیست؟
تفاوت های زیر بین یک فرآیند و یک نخ وجود دارد:- یک برنامه در حال اجرا یک فرآیند نامیده می شود، در حالی که یک Thread زیر مجموعه ای از یک فرآیند است.
- فرآیندها مستقل هستند، در حالی که نخ ها زیرمجموعه ای از یک فرآیند هستند.
- فرآیندها فضای آدرس متفاوتی در حافظه دارند، در حالی که رشتهها دارای یک فضای آدرس مشترک هستند.
- تعویض متن در مقایسه با فرآیندها بین رشته ها سریعتر است.
- ارتباط بین فرآیندی کندتر و گرانتر از ارتباطات بین رشته ای است.
- هر گونه تغییر در فرآیند والد بر روند فرزند تأثیر نمی گذارد، در حالی که تغییرات در رشته والد می تواند بر روی رشته فرزند تأثیر بگذارد.
39- مزایای چند رشته ای چیست؟
- Multithreading به یک برنامه/برنامه اجازه می دهد که همیشه به ورودی پاسخ دهد حتی اگر قبلاً برخی از وظایف پس زمینه را اجرا می کند.
- Multithreading به شما این امکان را می دهد که وظایف را سریعتر انجام دهید زیرا رشته ها به طور مستقل اجرا می شوند.
- Multithreading استفاده بهتری از حافظه پنهان را فراهم می کند، زیرا رشته ها منابع حافظه مشترکی دارند.
- Multithreading مقدار سرور مورد نیاز را کاهش می دهد زیرا یک سرور می تواند چندین رشته را به طور همزمان اجرا کند.
40. در چرخه حیات نخ چه حالاتی وجود دارد؟
- New: در این حالت یک شی کلاس
Thread
با استفاده از عملگر new ایجاد می شود، اما رشته وجود ندارد. تا زمانی که ما را صدا نکنیم موضوع شروع نمی شودstart()
. - Runnable: در این حالت، پس از فراخوانی متد، thread آماده اجرا است
start(). با این حال، هنوز توسط زمانبندی رشته انتخاب نشده است. - در حال اجرا: در این حالت، زمانبندی رشته نخی را از حالت آماده انتخاب می کند و اجرا می شود.
- Waiting/Blocked: در این حالت، موضوع در حال اجرا نیست، اما هنوز زنده است یا منتظر است تا رشته دیگری تکمیل شود.
- Dead/Terminated: هنگامی که متد خارج می شود،
run()
نخ در حالت پایان یا مرده است.
41. آیا می توان یک تاپیک را دو بار راه اندازی کرد؟
نه، ما نمیتوانیم thread را مجددا راهاندازی کنیم، زیرا زمانی که thread شروع و اجرا شد، به حالت Dead میرود. بنابراین اگر سعی کنیم رشته را دو بار اجرا کنیم، یک RuntimeException " java.lang.IllegalThreadStateException " ایجاد می کند. بیایید نگاه بیندازیم:class DoubleStartThreadExample extends Thread {
/**
* Имитируем работу треда
*/
public void run() {
// что-то происходит. Для нас не существенно на этом этапе
}
/**
* Запускаем тред дважды
*/
public static void main(String[] args) {
DoubleStartThreadExample doubleStartThreadExample = new DoubleStartThreadExample();
doubleStartThreadExample.start();
doubleStartThreadExample.start();
}
}
به محض اینکه کار به شروع دوم همان تاپیک برسد، یک استثنا وجود خواهد داشت. خودتان امتحان کنید؛) یک بار دیدن بهتر از صد بار شنیدن است.
42. اگر متد run() را مستقیماً بدون فراخوانی متد start() فراخوانی کنید چه؟
بله،run()
مطمئناً می توانید یک متد را فراخوانی کنید، اما با این کار یک رشته جدید ایجاد نمی شود و آن را به عنوان یک موضوع جداگانه اجرا نمی کنید. در این مورد، یک شی ساده است که یک متد ساده را فراخوانی می کند. اگر در مورد روش صحبت می کنیم start()
، آنگاه موضوع متفاوت است. با راهاندازی این روش، runtime
روش جدیدی را راهاندازی میکند و به نوبه خود، روش ما را اجرا میکند؛) اگر به من باور ندارید، آن را امتحان کنید:
class ThreadCallRunExample extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.print(i);
}
}
public static void main(String args[]) {
ThreadCallRunExample runExample1 = new ThreadCallRunExample();
ThreadCallRunExample runExample2 = new ThreadCallRunExample();
// просто будут вызваны в потоке main два метода, один за другим.
runExample1.run();
runExample2.run();
}
}
و خروجی کنسول به این صورت خواهد بود:
0123401234
مشاهده می شود که هیچ موضوعی ایجاد نشده است. همه چیز مثل یک کلاس معمولی کار می کرد. ابتدا روش کلاس اول کار کرد، سپس روش دوم.
43. نخ دیمون چیست؟
رشته دیمون (که از این پس به عنوان نخ شبح نامیده میشود) رشتهای است که وظایفی را در پسزمینه در رابطه با رشتهای دیگر انجام میدهد. یعنی وظیفه آن انجام کارهای کمکی است که فقط باید در ارتباط با رشته (اصلی) دیگری انجام شوند. بسیاری از موضوعات شبح وجود دارند که به طور خودکار کار می کنند، مانند Garbage Collector، finalizer و غیره.چرا جاوا موضوع دیمون را می بندد؟
تنها هدف یک رشته شبح این است که خدماتی را برای کار پشتیبانی پسزمینه به نخ کاربر ارائه میکند. بنابراین، اگر thread اصلی کامل شده باشد، زمان اجرا به طور خودکار تمام رشته های شبح آن را می بندد.روش های کار در کلاس Thread
کلاسjava.lang.Thread
دو روش برای کار با شبح thread ارائه می دهد:
public void setDaemon(boolean status)
- نشان می دهد که این یک رشته شبح خواهد بود. پیشفرض این استfalse
، به این معنی که رشتههای غیر دیمون ایجاد میشوند مگر اینکه به طور جداگانه مشخص شوند.public boolean isDaemon()
- اساساً این یک گیرنده برای متغیری استdaemon
که با استفاده از روش قبلی تنظیم کردیم.
class DaemonThreadExample extends Thread {
public void run() {
// Проверяет, демон ли этот поток or нет
if (Thread.currentThread().isDaemon()) {
System.out.println("daemon thread");
} else {
System.out.println("user thread");
}
}
public static void main(String[] args) {
DaemonThreadExample thread1 = new DaemonThreadExample();
DaemonThreadExample thread2 = new DaemonThreadExample();
DaemonThreadExample thread3 = new DaemonThreadExample();
// теперь thread1 - поток-демон.
thread1.setDaemon(true);
System.out.println("демон?.. " + thread1.isDaemon());
System.out.println("демон?.. " + thread2.isDaemon());
System.out.println("демон?.. " + thread3.isDaemon());
thread1.start();
thread2.start();
thread3.start();
}
}
خروجی کنسول:
демон?.. true
демон?.. false
демон?.. false
daemon thread
user thread
user thread
از خروجی می بینیم که در داخل خود thread با استفاده از currentThread()
روش ایستا می توانیم بفهمیم که از یک طرف کدام نخ است، از طرف دیگر اگر به موضوع این thread ارجاع داشته باشیم می توانیم بفهمیم. مستقیما از آن این انعطاف پذیری لازم را در پیکربندی می دهد.
44. آیا می توان نخ را بعد از ایجاد شبح ساخت؟
خیر اگر این کار را انجام دهید یک استثنا ایجاد می کندIllegalThreadStateException
. بنابراین، ما فقط می توانیم قبل از شروع یک نخ شبح ایجاد کنیم. مثال:
class SetDaemonAfterStartExample extends Thread {
public void run() {
System.out.println("Working...");
}
public static void main(String[] args) {
SetDaemonAfterStartExample afterStartExample = new SetDaemonAfterStartExample();
afterStartExample.start();
// здесь будет выброшено исключение
afterStartExample.setDaemon(true);
}
}
خروجی کنسول:
Working...
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.setDaemon(Thread.java:1359)
at SetDaemonAfterStartExample.main(SetDaemonAfterStartExample.java:14)
45. shutdownhook چیست؟
Shutdownhook یک رشته است که به طور ضمنی قبل از خاموش شدن JVM (ماشین مجازی جاوا) فراخوانی می شود. بنابراین وقتی ماشین مجازی جاوا به طور عادی یا ناگهانی خاموش می شود، می توانیم از آن برای پاکسازی یک منبع یا ذخیره وضعیت استفاده کنیم. می توانیمshutdown hook
با استفاده از روش زیر اضافه کنیم:
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
همانطور که در مثال نشان داده شده است:
/**
* Программа, которая показывает How запустить shutdown hook тред,
* который выполнится аккурат до окончания работы JVM
*/
class ShutdownHookThreadExample extends Thread {
public void run() {
System.out.println("shutdown hook задачу выполнил");
}
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
System.out.println("Теперь программа засыпает, нажмите ctrl+c чтоб завершить ее.");
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
خروجی کنسول:
Теперь программа засыпает, нажмите ctrl+c чтоб завершить ее.
shutdown hook задачу выполнил
46. همگام سازی چیست؟
همگام سازی در جاوا توانایی کنترل دسترسی چندین رشته به هر منبع مشترک است. هنگامی که چندین رشته سعی می کنند یک کار مشابه را انجام دهند، احتمال نتیجه اشتباه وجود دارد، بنابراین برای غلبه بر این مشکل، جاوا از همگام سازی استفاده می کند که به دلیل آن تنها یک رشته می تواند در یک زمان کار کند. همگام سازی را می توان به سه طریق به دست آورد:- روش همگام سازی
- با همگام سازی یک بلوک خاص
- همگام سازی استاتیک
همگام سازی روش
روش همگام سازی شده برای قفل کردن یک شی برای هر منبع مشترک استفاده می شود. هنگامی که یک رشته یک متد هماهنگ شده را فراخوانی می کند، به طور خودکار روی آن شی قفل می گیرد و زمانی که رشته کار خود را کامل می کند، آن را آزاد می کند. برای اینکه کار کند، باید کلمه کلیدی همگام شده را اضافه کنید . بیایید ببینیم که چگونه با یک مثال کار می کند:/**
* Пример, где мы синхронизируем метод. То есть добавляем ему слово synchronized.
* Есть два писателя, которые хотят использовать один принтер. Они подготовor свои поэмы
* И конечно же не хотят, чтоб их поэмы перемешались, а хотят, чтоб работа была сделана по * * * очереди для каждого из них
*/
class Printer {
synchronized void print(List<String> wordsToPrint) {
wordsToPrint.forEach(System.out::print);
System.out.println();
}
public static void main(String args[]) {
// один an object для двух тредов
Printer printer = new Printer();
// создаем два треда
Writer1 writer1 = new Writer1(printer);
Writer2 writer2 = new Writer2(printer);
// запускаем их
writer1.start();
writer2.start();
}
}
/**
* Писатель номер 1, который пишет свою поэму.
*/
class Writer1 extends Thread {
Printer printer;
Writer1(Printer printer) {
this.printer = printer;
}
public void run() {
List<string> poem = Arrays.asList("Я ", this.getName(), " Пишу", " Письмо");
printer.print(poem);
}
}
/**
* Писатель номер 2, который пишет свою поэму.
*/
class Writer2 extends Thread {
Printer printer;
Writer2(Printer printer) {
this.printer = printer;
}
public void run() {
List<String> poem = Arrays.asList("Не Я ", this.getName(), " Не пишу", " Не Письмо");
printer.print(poem);
}
}
و خروجی کنسول:
Я Thread-0 Пишу Письмо
Не Я Thread-1 Не пишу Не Письмо
بلوک همگام سازی
یک بلوک همگامسازی شده میتواند برای انجام همگامسازی بر روی هر منبع روش خاصی استفاده شود. بیایید بگوییم که در یک روش بزرگ (بله، بله، شما نمی توانید چنین چیزهایی را بنویسید، اما گاهی اوقات این اتفاق می افتد) به دلایلی فقط باید یک قسمت کوچک را همگام کنید. اگر تمام کدهای یک متد را در یک بلوک همگامسازی شده قرار دهید، مانند روش همگامسازی شده عمل میکند. نحو به این شکل است:synchronized (“an object для блокировки”) {
// сам code, который нужно защитить
}
برای اینکه مثال قبلی را تکرار نکنیم، رشته هایی را از طریق کلاس های ناشناس ایجاد می کنیم - یعنی بلافاصله رابط Runnable را پیاده سازی می کنیم.
/**
* Вот How добавляется блок синхронизации.
* Внутри нужно указать у кого будет взят мьютекс для блокировки.
*/
class Printer {
void print(List<String> wordsToPrint) {
synchronized (this) {
wordsToPrint.forEach(System.out::print);
}
System.out.println();
}
public static void main(String args[]) {
// один an object для двух тредов
Printer printer = new Printer();
// создаем два треда
Thread writer1 = new Thread(new Runnable() {
@Override
public void run() {
List<String> poem = Arrays.asList("Я ", "Writer1", " Пишу", " Письмо");
printer.print(poem);
}
});
Thread writer2 = new Thread(new Runnable() {
@Override
public void run() {
List<String> poem = Arrays.asList("Не Я ", "Writer2", " Не пишу", " Не Письмо");
printer.print(poem);
}
});
// запускаем их
writer1.start();
writer2.start();
}
}
}
و خروجی به کنسول
Я Writer1 Пишу Письмо
Не Я Writer2 Не пишу Не Письмо
همگام سازی استاتیک
اگر یک روش استاتیک را همگام سازی کنید، قفل روی کلاس خواهد بود، نه روی شی. در این مثال، کلمه کلیدی همگامسازی شده را به یک روش ثابت برای انجام همگامسازی استاتیک اعمال میکنیم:/**
* Вот How добавляется блок синхронизации.
* Внутри нужно указать у кого будет взят мьютекс для блокировки.
*/
class Printer {
static synchronized void print(List<String> wordsToPrint) {
wordsToPrint.forEach(System.out::print);
System.out.println();
}
public static void main(String args[]) {
// создаем два треда
Thread writer1 = new Thread(new Runnable() {
@Override
public void run() {
List<String> poem = Arrays.asList("Я ", "Writer1", " Пишу", " Письмо");
Printer.print(poem);
}
});
Thread writer2 = new Thread(new Runnable() {
@Override
public void run() {
List<String> poem = Arrays.asList("Не Я ", "Writer2", " Не пишу", " Не Письмо");
Printer.print(poem);
}
});
// запускаем их
writer1.start();
writer2.start();
}
}
و خروجی کنسول:
Не Я Writer2 Не пишу Не Письмо
Я Writer1 Пишу Письмо
47- متغیر فرار چیست؟
این کلمه کلیدیvolatile
در برنامه نویسی چند رشته ای برای تامین ایمنی رشته استفاده می شود زیرا تغییر یک متغیر قابل تغییر برای همه رشته های دیگر قابل مشاهده است، بنابراین یک متغیر می تواند توسط یک رشته در یک زمان استفاده شود. با استفاده از کلمه کلیدی، volatile
می توانید تضمین کنید که متغیر از نظر رشته ای ایمن است و در حافظه مشترک ذخیره می شود و رشته ها آن را به حافظه پنهان خود نمی برند. چه شکلی است؟
private volatile AtomicInteger count;
ما فقط به متغیر اضافه می کنیم volatile
. اما این به معنای ایمنی کامل نخ نیست... از این گذشته، ممکن است عملیات روی یک متغیر اتمی نباشد. اما می توانید از Atomic
کلاس هایی استفاده کنید که عملیات را به صورت اتمی انجام می دهند، یعنی در یک اجرا توسط پردازنده. بسیاری از این کلاس ها را می توان در بسته پیدا کرد java.util.concurrent.atomic
.
48. بن بست چیست
بن بست در جاوا بخشی از multithreading است. بن بست می تواند در شرایطی اتفاق بیفتد که یک نخ در انتظار یک قفل شی که توسط نخ دیگری به دست آمده است، و یک نخ دوم در انتظار یک قفل شی که توسط نخ اول به دست آمده است، باشد. بنابراین، این دو رشته در انتظار یکدیگر می مانند و به اجرای کد خود ادامه نمی دهند. بیایید به مثالی نگاه کنیم که در آن کلاسی وجود دارد که Runnable را پیاده سازی می کند. دو منبع را در سازنده خود می پذیرد. در متد run()، قفل را یکی یکی برای آنها می گیرد، بنابراین اگر دو شی از این کلاس ایجاد کنید و منابع را به ترتیب مختلف منتقل کنید، به راحتی می توانید با یک قفل برخورد کنید:class DeadLock {
public static void main(String[] args) {
final Integer r1 = 10;
final Integer r2 = 15;
DeadlockThread threadR1R2 = new DeadlockThread(r1, r2);
DeadlockThread threadR2R1 = new DeadlockThread(r2, r1);
new Thread(threadR1R2).start();
new Thread(threadR2R1).start();
}
}
/**
* Класс, который принимает два ресурса.
*/
class DeadlockThread implements Runnable {
private final Integer r1;
private final Integer r2;
public DeadlockThread(Integer r1, Integer r2) {
this.r1 = r1;
this.r2 = r2;
}
@Override
public void run() {
synchronized (r1) {
System.out.println(Thread.currentThread().getName() + " захватил ресурс: " + r1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (r2) {
System.out.println(Thread.currentThread().getName() + " захватил ресурс: " + r2);
}
}
}
}
خروجی کنسول:
Первый тред захватил первый ресурс
Второй тред захватывает второй ресурс
49. چگونه از بن بست جلوگیری کنیم؟
بر اساس آنچه می دانیم بن بست چگونه اتفاق می افتد، می توانیم نتیجه گیری کنیم...- همانطور که در مثال بالا نشان داده شد، بن بست به دلیل تودرتو بودن قفل ها بود. یعنی داخل یک قفل دیگری یا بیشتر وجود دارد. شما می توانید به روش زیر از این امر جلوگیری کنید - به جای تودرتو، باید یک انتزاع جدید در بالا اضافه کنید و قفل را به سطح بالاتری ببرید و قفل های تودرتو را بردارید.
- هرچه انسداد بیشتر باشد، احتمال اینکه بن بست وجود داشته باشد بیشتر می شود. بنابراین، هر بار که یک قفل اضافه می کنید، باید به این فکر کنید که آیا واقعاً به آن نیاز است و آیا می توان از اضافه کردن قفل جدید جلوگیری کرد.
- استفاده می کند
Thread.join()
. بن بست همچنین می تواند زمانی انجام شود که یک رشته در انتظار موضوع دیگری باشد. برای جلوگیری از این مشکل، ممکن است محدودیت زمانی برایjoin()
روش تعیین کنید. - اگر یک تاپیک داشته باشیم، بن بست وجود نخواهد داشت ;)
50. شرط مسابقه چیست؟
اگر در مسابقات واقعی اتومبیل ها اجرا می کنند، در اصطلاح مسابقه ای چند رشته ای، نخ ها در مسابقات اجرا می شوند. اما چرا؟ دو رشته در حال اجرا هستند و می توانند به یک شی دسترسی داشته باشند. و می توانند همزمان سعی کنند وضعیت را به روز کنند. تا اینجا همه چیز روشن است، درست است؟ بنابراین رشته ها یا به صورت موازی واقعی (اگر بیش از یک هسته در پردازنده وجود دارد) یا به صورت مشروط به صورت موازی کار می کنند، زمانی که پردازنده مدت زمان کوتاهی را اختصاص می دهد. و ما نمیتوانیم این فرآیندها را کنترل کنیم، بنابراین نمیتوانیم تضمین کنیم که وقتی یک رشته دادهها را از یک شی میخواند، قبل از اینکه رشتهای دیگر این کار را انجام دهد، زمان لازم را برای تغییر آن خواهد داشت. مشکلاتی از این دست زمانی اتفاق میافتد که این ترکیب آزمایش و عمل انجام شود. چه مفهومی داره؟ مثلاًif
عبارتی داریم که در بدنه آن شرط خود تغییر می کند، یعنی:
int z = 0;
// проверь
if (z < 5) {
//действуй
z = z + 5;
}
بنابراین ممکن است شرایطی پیش بیاید که در زمانی که z هنوز برابر با صفر است، دو رشته به طور همزمان وارد این بلوک کد شوند و با هم این مقدار را تغییر دهند. و در پایان ما مقدار مورد انتظار 5 را بدست نمی آوریم، بلکه 10 را دریافت خواهیم کرد. چگونه از این امر جلوگیری کنیم؟ قبل و بعد از اجرا باید قفل کنید. یعنی برای اینکه اولین رشته وارد بلوک شود if
، تمام اقدامات را انجام دهید، آن را تغییر دهید z
و تنها پس از آن به رشته بعدی فرصت دهید تا این کار را انجام دهد. اما موضوع بعدی وارد بلوک نمی شود if
، زیرا z
قبلاً برابر با 5 خواهد بود:
// получить блокировку для z
if (z < 5) {
z = z + 5;
}
// выпустить из блокировки z
===================================================
به جای خروجی
می خواهم از همه کسانی که تا آخر خواندند تشکر کنم. سفر طولانی بود و تو موفق شدی! ممکن است همه چیز روشن نباشد. این خوبه. به محض اینکه شروع به یادگیری جاوا کردم، نمیتوانستم ذهنم را در مورد متغیر ثابت بپیچم. ولی هیچی، با این فکر خوابیدم، چند منبع دیگه خوندم و بالاخره فهمیدم. آماده شدن برای مصاحبه بیشتر یک موضوع آکادمیک است تا عملی. بنابراین، قبل از هر مصاحبه، باید مواردی را که ممکن است زیاد استفاده نکنید، تکرار کرده و حافظه خود را تجدید کنید.و مثل همیشه لینک های مفید:
- استثنا در جاوا
- روش های پیش فرض در جاوا
- تجزیه و تحلیل دقیق کلاس ArrayList
- در حساب GitHub من مشترک شوید . من هر کاری که انجام می دهم را آنجا می گذارم. هر چیزی که من آموزش می دهم. به عنوان مثال، من اخیراً با Drools RuleEngine سروکار داشتم .
- علامت زده شد استثنائات بدون علامت
- تلاش با منابع
- کلمه کلیدی نهایی
- در حالی که داشتم مطالب را آماده می کردم، از سایت https://www.geeksforgeeks.org بسیار خوشم آمد . واقعاً اطلاعات جالب زیادی در آنجا وجود دارد.
GO TO FULL VERSION