JavaRush /Java блогы /Random-KK /Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жа...
Константин
Деңгей

Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау. 7-бөлім

Топта жарияланған
Бәріңе сәлем! Бағдарламалау қателіктерге толы. Сіз сүрінбейтін және төбелесетін тақырып іс жүзінде жоқ. Бұл әсіресе жаңадан бастаушыларға қатысты. Мұны азайтудың жалғыз жолы - оқу. Атап айтқанда, бұл ең негізгі тақырыптардың егжей-тегжейлі талдауларына қатысты. Бүгін мен негізгі тақырыптарды жақсы қамтитын Java әзірлеушілерінің сұхбаттарынан 250+ сұрақты талдауды жалғастырамын . Тізімде жалпы тақырыптарды басқа қырынан қарауға мүмкіндік беретін кейбір стандартты емес сұрақтар да бар екенін атап өткім келеді.Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  7 - 1 бөлім

62. Жолдық пул дегеніміз не және ол не үшін қажет?

Java жадында (үйме, ол туралы кейінірек айтатын боламыз) аймақ бар - String pool немесе string pool. Ол жол мәндерін сақтауға арналған. Басқаша айтқанда, белгілі бір жолды жасағанда, мысалы, қос тырнақшалар арқылы:
String str = "Hello world";
жол пулында берілген мән бар-жоғын тексеру үшін тексеру жүргізіледі. Олай болса, str айнымалысына пулдағы сол мәнге сілтеме тағайындалады. Олай болмаса, пулда жаңа мән жасалады және оған сілтеме str айнымалысына тағайындалады . Мысал қарастырайық:
String firstStr = "Hello world";
String secondStr = "Hello world";
System.out.println(firstStr == secondStr);
экранда true көрсетіледі . == сілтемелерді салыстыратыны есімізде , яғни бұл екі сілтеме жол пулындағы бірдей мәнге сілтеме жасайды. Бұл жадта String типті көптеген бірдей an objectілерді шығармау үшін жасалады , өйткені біз есімізде, String өзгермейтін класс, ал егер бізде бірдей мәнге көптеген сілтемелер болса, онда ешқандай қателік жоқ. Бір жерде мәнді өзгерту бірден бірнеше басқа сілтемелер үшін өзгерістерге әкелетін жағдай үшін енді мүмкін емес. Дегенмен, егер біз new арқылы жолды жасасақ :
String str = new String("Hello world");
жадта осы жолдың мәнін сақтайтын жеке нысан жасалады (және жол пулында мұндай мән бар-жоғы маңызды емес). Растау ретінде:
String firstStr = new String("Hello world");
String secondStr = "Hello world";
String thirdStr = new String("Hello world");
System.out.println(firstStr == secondStr);
System.out.println(firstStr == thirdStr);
Біз екі жалған мән аламыз , яғни бұл жерде сілтеме жасалып жатқан үш түрлі мән бар. Шын мәнінде, сондықтан қос тырнақшаларды пайдаланып жолдарды жасау ұсынылады. Дегенмен, new көмегімен нысанды жасау кезінде жол пулына мәндерді қосуға (немесе сілтеме алуға) болады . Ол үшін біз string класс әдісін қолданамыз - intern() . Бұл әдіс жол пулында мәнді мәжбүрлеп жасайды немесе егер ол сонда сақталған болса, оған сілтеме алады. Міне, мысал:
String firstStr = new String("Hello world").intern();
String secondStr = "Hello world";
String thirdStr = new String("Hello world").intern();
System.out.println(firstStr == secondStr);
System.out.println(firstStr == thirdStr);
System.out.println(secondStr == thirdStr);
Нәтижесінде біз консольде үш шынайы мән аламыз , бұл барлық үш айнымалы мән бір жолға сілтеме жасайды.Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  7 - 2 бөлім

63. Жолдық пулда қандай GOF үлгілері қолданылады?

GOF үлгісі жол пулында анық көрінеді - flyweight , әйтпесе тұндырғыш деп аталады. Мұнда басқа үлгіні көрсеңіз, оны түсініктемелерде бөлісіңіз. Ал, жеңіл үлгі туралы сөйлесейік. Жеңіл салмақ - бұл бағдарламаның әртүрлі орындарында өзін бірегей данасы ретінде көрсететін нысан, шын мәнінде, олай емес құрылымдық дизайн үлгісі. Жеңіл әр нысанда бірдей деректерді сақтаудың орнына нысандардың ортақ күйін бөлісу арқылы жадты үнемдейді. Мәнін түсіну үшін ең қарапайым мысалды қарастырайық. Бізде қызметкер интерфейсі бар делік:
public interface Employee {
   void work();
}
Кейбір іске асырулар бар, мысалы, заңгер:
public class Lawyer implements Employee {

   public Lawyer() {
       System.out.println("Юрист взят в штат.");
   }

   @Override
   public void work() {
       System.out.println("Решение юридических вопросов...");
   }
}
Ал есепші:
public class Accountant implements Employee{

   public Accountant() {
       System.out.println("Бухгалтер взят в штат.");
   }

   @Override
   public void work() {
       System.out.println("Ведение бухгалтерского отчёта....");
   }
}
Әдістер өте шартты: біз олардың орындалғанын көруіміз керек. Дәл осындай жағдай конструкторға да қатысты. Консоль шығысының арқасында біз жаңа нысандардың қашан жасалғанын көреміз. Сондай-ақ бізде қызметкерлер бөлімі бар, оның міндеті сұралған қызметкерді шығару болып табылады, егер ол жоқ болса, оны жұмысқа алып, сұранысқа жауап береді:
public class StaffDepartment {
   private Map<String, Employee> currentEmployees = new HashMap<>();

   public Employee receiveEmployee(String type) throws Exception {
       Employee result;
       if (currentEmployees.containsKey(type)) {
           result = currentEmployees.get(type);
       } else {
           switch (type) {
               case "Бухгалтер":
                   result = new Accountant();
                   currentEmployees.put(type, result);
                   break;
               case "Юрист":
                   result = new Lawyer();
                   currentEmployees.put(type, result);
                   break;
               default:
                   throw new Exception("Данный сотрудник в штате не предусмотрен!");
           }
       }
       return result;
   }
}
Яғни, логика қарапайым: егер берілген бірлік болса, оны қайтарыңыз, егер жоқ болса, оны жасаңыз, оны қоймаға орналастырыңыз (кэш сияқты нәрсе) және оны қайтарыңыз. Енді бәрі қалай жұмыс істейтінін көрейік:
public static void main(String[] args) throws Exception {
   StaffDepartment staffDepartment = new StaffDepartment();
   Employee empl1  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl2  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl3  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl4  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl5  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl6  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl7  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl8  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl9  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl10  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
}
Ал консольде сәйкесінше шығыс болады:
Заңгер жұмысқа қабылданды. Құқықтық мәселелерді шешу... Есепші жұмысқа алынды. Бухгалтерлік есеп жүргізу.... Құқықтық мәселелерді шешу... Бухгалтерлік есеп жүргізу.... Заңды мәселелерді шешу... Бухгалтерлік есепті жүргізу.... Заңды мәселелерді шешу... Бухгалтерлік есеп жүргізу.... Құқықтық мәселелерді шешу ... Бухгалтерлік есептерді жүргізу...
Көріп отырғаныңыздай, бірнеше рет қайта пайдаланылған екі ғана нысан жасалды. Мысал өте қарапайым, бірақ бұл үлгіні пайдалану ресурстарымызды қалай үнемдейтінін анық көрсетеді. Байқағаныңыздай, бұл үлгінің логикасы сақтандыру пулының логикасына өте ұқсас. GOF үлгілерінің түрлері туралы толығырақ осы мақалада оқи аласыз .Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  7 - 3 бөлім

64. Жолды бөліктерге қалай бөлуге болады? Сәйкес codeтың мысалын келтіріңіз

Бұл сұрақ бөлу әдісі туралы екені анық . String класында бұл әдістің екі нұсқасы бар:
String split(String regex);
Және
String split(String regex);
regex - жолды бөлгіш - жолды жолдар массивіне бөлетін кейбір тұрақты өрнек, мысалы:
String str = "Hello, world it's Amigo!";
String[] arr = str.split("\\s");
for (String s : arr) {
  System.out.println(s);
}
Консольге келесілер шығарылады:
Сәлем, әлем бұл Амиго!
Яғни, біздің жолдың мәні жолдар массивіне бөлінген және бөлгіш бос орын болды (бөлу үшін біз бос орынсыз «\\s» тұрақты өрнегін және жай « " жол өрнегін пайдалана аламыз ). Екінші, шамадан тыс жүктелген әдісте қосымша аргумент бар - limit . шек — алынған массивтің максималды рұқсат етілген мәні. Яғни, жол ішкі жолдардың ең көп рұқсат етілген санына бөлінген кезде, одан әрі бөлу болмайды және соңғы элементте мүмкін бөлінбеген жолдың «қалғаны» болады. Мысалы:
String str = "Hello, world it's Amigo!";
String[] arr = str.split(" ", 2);
for (String s : arr) {
  System.out.println(s);
}
Консоль шығысы:
Сәлем, әлем бұл Амиго!
Көріп отырғанымыздай, егер ол limit = 2 шектеуі болмаса , массивтің соңғы элементін үш ішкі жолға бөлуге болады.Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  7 - 4 бөлім

65. Неліктен таңбалар массиві құпия сөзді сақтауға арналған жолға қарағанда жақсы?

Құпия сөзді сақтау кезінде массивті жолға артықшылық берудің бірнеше себептері бар: 1. Жол пулы және жолдың өзгермейтіндігі. Массивті ( char[] ) пайдаланған кезде біз онымен жұмыс істегеннен кейін деректерді анық өшіре аламыз. Сондай-ақ, біз массивті қалағанымызша қайта жаза аламыз және жарамды құпия сөз тіпті қоқыс жинамас бұрын жүйеде еш жерде болмайды (бірнеше ұяшықты жарамсыз мәндерге өзгерту жеткілікті). Сонымен қатар, String өзгермейтін класс болып табылады. Яғни, егер оның мәнін өзгерткіміз келсе, біз жаңасын аламыз, ал ескісі жолдық пулда қалады. Құпия сөздің String мәнін жойғымыз келсе , бұл өте қиын тапсырма болуы мүмкін, себебі String пулынан мәнді жою үшін бізге қоқыс жинағыш қажет және бұл Жол мәнінің сол жерде қалу ықтималдығы жоғары . ұзақ уақыт. Яғни, бұл жағдайда String деректерді сақтау қауіпсіздігі бойынша char массивінен төмен. 2. Жолдың мәні консольге (немесе журналдарға) кездейсоқ шығарылса, мәннің өзі көрсетіледі:
String password = "password";
System.out.println("Пароль - " + password);
Консоль шығысы:
Құпия сөз
Сонымен қатар, егер сіз кездейсоқ массивді консольге шығарсаңыз:
char[] arr = new char[]{'p','a','s','s','w','o','r','d'};
System.out.println("Пароль - " + arr);
Консольде түсініксіз gobbledygook болады:
Құпия сөз - [C@7f31245a
Іс жүзінде gobbledygook емес, бірақ: [C - сынып атауы - таңба массиві , @ - бөлгіш, одан кейін 7f31245a - он алтылық хэшcode. 3. Ресми құжат Java Cryptography Architecture Guide, құпия сөздерді String орнына char[] түрінде сақтау туралы анық айтылған : « Java.lang.String түріндегі нысанда құпия сөзді жинау және сақтау қисынды болып көрінеді . Дегенмен, мұнда ескерту бар: Жол нысандары өзгермейді, яғни String нысанының мазмұнын пайдаланудан кейін өзгертуге (қайта жазуға) немесе нөлге келтіруге мүмкіндік беретін әдістер анықталмаған . Бұл мүмкіндік String нысандарын пайдаланушы құпия сөздері сияқты құпия ақпаратты сақтау үшін жарамсыз етеді. Оның орнына сіз әрқашан таңбалар массивінде құпия қауіпсіздік ақпаратын жинап, сақтауыңыз керек».Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  7 - 5 бөлім

Enum

66. Java тіліндегі Enum бағдарламасына қысқаша сипаттама беріңіз

Enum - санау, жалпы типпен біріктірілген жолдық тұрақтылар жиыны. - enum түйінді сөзі арқылы жарияланады . Міне , белгілі бір мектептегі жарамды рөлдер саны бар мысал :
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD
}
Бас әріппен жазылған сөздер жаңа операторды қолданбай, жеңілдетілген түрде жарияланған бірдей санау тұрақтылары болып табылады . Санақтарды пайдалану өмірді айтарлықтай жеңілдетеді, өйткені олар атау кезінде қателер мен шатасуларды болдырмауға көмектеседі (өйткені мәндердің белгілі бір тізімі ғана болуы мүмкін). Мен оларды Switch логикалық дизайнында қолданғанда өте ыңғайлы деп санаймын .

67. Enum интерфейстерді жүзеге асыра алады ма?

Иә. Ақыр соңында, тізімдер жай ғана пассивті жинақтарды емес (мысалы, рөлдерді) көрсетуі керек. Java тілінде олар кейбір функционалдығы бар күрделі нысандарды көрсете алады, сондықтан оларға қосымша функционалдылықты қосу қажет болуы мүмкін. Бұл сонымен қатар іске асырылған интерфейс түрі қажет жерлерде enum мәнін ауыстыру арқылы полиморфизм мүмкіндіктерін пайдалануға мүмкіндік береді .

68. Enum класты кеңейте алады ма?

Жоқ, ол мүмкін емес, себебі enum жалпы класс Enum <T> әдепкі қосалқы сыныбы болып табылады , мұнда T жалпы сан түрін білдіреді. Бұл Java тілінің барлық enum түрлері үшін ортақ базалық сыныптан басқа ештеңе емес. Enum сыныпқа түрлендіруді Java компиляторы компиляция уақытында жасайды. Бұл кеңейтім codeта нақты көрсетілмеген, бірақ әрқашан көрінбейтін түрде болады.

69. Объекті даналары жоқ Enum құру мүмкін бе?

Маған келетін болсақ, сұрақ біртүрлі болды, немесе мен оны толық түсінбедім. Менде екі түсіндірме бар: 1. Мәнсіз санау болуы мүмкін бе - иә, әрине, бұл бос сынып сияқты нәрсе болар еді - мағынасыз:
public enum Role {
}
Және қоңырау шалып:
var s = Role.values();
System.out.println(s);
Біз консольде аламыз:
[Lflyweight.Role;@9f70c54
( Рөл мәндерінің бос массиві ) 2. Жаңа операторсыз нөмір құру мүмкін бе - иә, әрине. Жоғарыда айтқанымдай, нөмір мәндері (санаулар) үшін жаңа операторды пайдаланудың қажеті жоқ , өйткені бұл статикалық мәндер.

70. Enum үшін toString() әдісін қайта анықтай аламыз ба?

Иә, әрине, toString әдісін шақыру кезінде нөмірді көрсетудің арнайы әдісін анықтау үшін toString() әдісін қайта анықтауға болады ( енумді кәдімгі жолға аудару кезінде , мысалы, консольге немесе журналдарға шығару үшін).
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;

   @Override
   public String toString() {
       return "Выбрана роль - " + super.toString();
   }
}
Бұл бүгінге, келесі бөлімге дейін!Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  7 - 6 бөлім
Сериядағы басқа материалдар:
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION