C++ Ինտերվյուներում

Տարբեր հայկական կազմակերպություններում տրված հարցեր C++ լեզվից: Կարմիր գույնով նշված են իմ կարծիքով անհաջող հարցերը՝ ելնելով նրանից, թե իրական աշխարհում ինչ հաճախությամբ կարելի է հանդիպել դրանց կիրառությունը: Կանաչ գույնով նշել եմ լավ հարցերը (ելնելով նույն սկզբունքից): Մնացած հարցերը քիչ թե շատ չեզոք են: Ցուցակը երբեմն թարմացվում է: Սկզբնական տարբերակը վերցված է 2017 թվականին այստեղից, ինչից հետո թե այս ցուցակը, թե սկզբնականը մի քիչ փոփոխվել են, տարբեր են նաև հարցերի համարները։

Կարևոր նշում շրջանավարտների և սկսնակ ծրագրավորողների համար՝

Մի փորձեք գտնել ու հիշել ամեն հարցի «ճիշտ» պատասխանը: Աշխատեք այս ցուցակը գտագործել որպես գործիք՝ խորանալու ու ամեն մեկի շուրջ ձեր համար փոքր հետազոտական աշխատանքներ կազմակերպելու համար: Այս հարցերից ցանկացածի շուրջ հանգիստ կարող եք մի ամբողջ օր, կամ նույնիսկ մի քանի օր, ծախսել հասկանալու համար տարբեր տեսանկյուններից՝ ո՞վ է սահմանում, թե որ պատասխանն է «ճիշտ», StackOverflow-ում ի՞նչ պատասխաններ կան ամեն հարցի շուրջ, այդ պատասխաններից որո՞նք են հին ու նոր, ու՞մ պատասխանն է ընդունված / ավելի շատ ձայն ստացել / տրվել ավելի մեծ հեղինակություն ունեցողի կողմից և որ դեպքում որն է ավելի կարևոր, ո՞րտեղ կան հակասություններ, և այլն:

Ամեն հարցի շուրջ նման փոքր հետազոտական աշխատանքի արդյունքում դուք կհանդիպեք մի հազար այլ հարակից փոքր հարցեր-վերլուծությունների, որոնցից ամեն մեկը կարող է հանդիպել հարցազրույցի ժամանակ, այսինքն՝ հարցազրույցը լավ անցնելու ձեր շանսերը կմեծանան: Բայց, ինչը ամենակարևորն է՝ դուք կսովորեք խնդրին ճիշտ մոտենալ՝ ճիշտ վերլուծել, խնդիրներն ու հարցերը հասկնաալ ամբողջությամբ՝ բոլոր տեսանկյուններից, ու նույնը կանեք նաև աշխատելուց՝ դրա բոլոր լավ հետևանքներով:


Հարց 64։ Գրել այնպիսի Matrix կլաս, որի թե տողերը, թե սյուները հնարավոր լինի ստանալ հղումով և հաստատուն ժամանակում:

Հարց 63։ Գրել երկու սորտավորված հավաքածուների merge-ը, որն արդյունքում կտա միավորված սորտավորված հաջորդականություն:

Հարց 62։ Եթե new արած հիշողությունը delete չանենք, ի՞նչ կլինի ծրագրի աշխատանքի ավարտից հետո:

Հարց 61։ Ինչպե՞ս արգելել օբյեկտին ստեղծվել կույտի (heap) վրա: Նույնը՝ ստեկի (stack) վրա:

Հարց 60։ Կլասի անդամներից որո՞նք կարող են լինել վիրտուալ:

Հարց 59։ Ինչի՞ համար է std::move_if_noexcept-ը: [Պատասխանը (անգլերեն)՝ Ս. Մեյերսի ելույթի այս կետում, մոտ 4 րոպե տևողությամբ]:

Հարց 58։ Ինչու՞ հետևյալ կոդը կոմպիլյացիա չի լինի և ի՞նչ անել, որպեսզի աշխատի.
int f(std::unique_ptr p);
std::unique_ptr up(new int);
f(up);

Հարց 57։ Ունենք
#define SQR(x) x*x
SQR(3+5)
Արդյունքը կլինի՞ 64:

Հարց 56։ Ռեկուրսիայի լավ ու վատ կողմերը: Ֆիբոնաչիի հաջորդականության իրականացում (ռեկուրսիվ և իտերատիվ):

Հարց 55։ Ի՞նչ է սինգլտոնը:

Հարց 54։ Կատարման ժամանակ որոշել, թե տվյալ կլասը (օբյեկտը) ունի՞ արդյոք վիրտուալ ֆունկցիաներ:

Հարց 53։ Ի՞նչ է պոլիմորֆիզմը: [Մանրամասն բացատրութունը կա այս տեսանյութում]:

Հարց 52։ C լեզվով սահմանել ամբողջ թվերի հաստատունների զանգվածի հաստատուն ցուցիչ (define a constant pointer to array of constant integers)։

const int (*const arr)[];

Հարց 51։ Ունենք void f(int& x); ֆունկցիա։ Ի՞նչ է կատարվում երբ կանչվում է f(5);
Նույն հարցը՝ հետևյալ կանչերի համար.
int a = 0;
const int b = 10;
f(a);
f(b);
f(a+b);
f(++a);
f(a++);
f(a+=b);

Հարց 50։ Ունենք կլասների հետևյալ հիերարխիան՝

class Base {
public:
int m_x;
Base(int x) : m_x(x) {};
~Base() {};
};

class Derived : public Base
{
int m_y;
// գրել կոնստրուկտոր Derived կլասի համար
};

Պատասխանի օրինակ՝  Derived(int y) : Base(0), m_y(y) {};

Հարց՝ ի՞նչ տարբերություն initialization list֊ի ու body֊ում գրելու միջև։

Հարց՝ Ո՞ր դեպքերում է, որ կարելի է միայն initialization list֊ով սկզբնարժեքավորել դաշտերը, իսկ body-ում չի կարելի գրել։

Հարց 49։ Ունենք
class A {
// ...
void f() { std::cout << “A\n”; }
};

int main()
{
A* p = nullptr;
p->f();
// ...
}

Ի՞նչ կկատարվի։

Հարց 48։ Շնջել տրված տողը՝ “abcd” => “dcba”
void reverse(char* str)
{
...
}

Հարց 47։ Ի՞նչ է memory leak֊ը (հիշողության արտահոսք)։

Հարց 46։ Ի՞նչ արդյունքի է բերում malloc(0)֊ն։

Հարց 45։ Ի՞նչ արդյունքի է բերում malloc(NULL)-ը։

Հարց 44։ Ի՞նչ արդյունքի կբերի հետևյալ կոդը՝
int* p = malloc(10);
p++;
free(p);

Հարց 43։ Ինչի՞ համար է const_cast-ը։ Կարելի՞ է գրել հետևյալ կոդը՝
const int a = 5;
int b = const_cast<int>(a);

Հետաքրքիր է, որ հետևյալ կոդն արտածում է «5 7»։ Ինչո՞ւ։

const int a = 5;
int* b = const_cast<int*>(&a);
*b = 7;
std::cout << a << " " << (*b) << std::endl;

Հարց 42։ Ի՞նչ է նշանակում mutable keyword-ը։

Հարց 41։ Ի՞նչ կտպի հետևյալ կոդը՝
int x = 5;
cout << x++;
cout << ++x;
Վերասահմանել operator++()-ը:

Հարց 40։ Ի՞նչ կտպի հետևյալ կոդը՝
const int a = 5;
const int* c = &a;
int* p = const_cast<int*>(c);
(*p)++;
cout << a << ", " << (*c) <<  ", " << (*p);

Հարց 39։ Ի՞նչ տիպի կոնստրուկտորներ կան։
Default constructor
Copy constructor
User defined constructor
Move constructor (C++11)

Հարց 38։ Ո՞ր դեպքերում է կանչվում copy-constructor-ը։
  1. A a;
A b = a;
  1. Ֆունկցիային արգումենտ փոխանցելիս
  2. Ֆունկցիայից արժեք վերադարձնելիս
  3. Երբ կոմպիլյատորը ստեղծում է temporary փոփոխականներ
Գրել copy-constructor-ի prototype-ը՝
A(const A& a);
Ինչո՞ւ է պարամետրը & տիպի։
Հարց 37։ Ինչի՞ համար են virtual ֆունկցիաները (vtable, vptr):
class A {
public:
virtual void f();
};
class B : public A {
public:
void f();
};
B b;
A a = b;
a.f();
Ինչու՞ ցուցիչների և հղումների դեպքում (օրինակ՝ A* a = &b;) կկանչվի B::f() ֆունկցիան, իսկ այս դեպքում կանչվում է A::f() ֆունկցիան։

Հարց 36։ Ինչի՞ համար է virtual destructor-ը: [Մանրամասն պատասխանը կա այս տեսանյությում]:

Հարց 35։ Կարելի՞ է հայտարարել virtual constructor՝ ոչ։ Իսկ ինչպե՞ս ստանալ այդպիսի վարք, եթե պետք է ստեղծել օբյեկտ, որի կոնկրետ տիպը նախօրոք հայտնի չէ (նկարագրված է Stroustrup-ի գրքում)։

Հարց 34։ Ի՞նչ կլինի, եթե 2 անգամ delete կանչվի նույն հիշողության համար՝ undefined behaviour: Բայց ծրագրում հնարավոր են այդպիսի դեպքեր, օրինակ՝ f-ը կարող է մի քանի անգամ կանչվել նույն ցուցչի համար
void f(int* p)
{
delete p;
}
Ի՞նչ անել, որպեսզի վատ բան տեղի չունենա:

Հարց 33։ Ո՞րն է ցուցչի և հղման տարբերությունը։ [Մանրամասն պատասխանը կա այս և այս տեսանյութերում]:

Հարց 32։ Ո՞րն է struct-ի և class-ի տարբերությունը։

Հարց 31։ Կարո՞ղ է արդյոք մաքուր վիրտուալ ֆունկցիան մարմին ունենալ։

Հարց 30։ Կարելի՞ է արդյոք delete գործողությունը կիրառել this ցուցիչի նկատմամբ։

Հարց 29։ Ինչի՞ կբերի դեստրուկտորում բացառություն (exception) գեներացնելը։

Հարց 28: Ի՞նչն է վատ հետևյալ ծրագրում։
     int f()
     {
          try {
             throw E;
          }
          catch(E e) {
             // ...
          }
     }

Հարց 27։ Ի՞նչ է RAII֊ն (resource allocation is initialization)։

Հարց 26։
     class Boo
     {
     public:
           Boo(int i) {};
     };

     void f(Boo b);

     f(10); // կարելի՞ է f-ը կանչել 10֊ով


Այո, քանի որ Boo-ն ունի int պարամետրով կոնստրուկտոր (որը կոչվում է conversion constructor): Ի՞նչ անել, որպեսզի հնարավոր չլինի կանչել f(10):

Հարց 25։ Ի՞նչ արժեք կստանա s֊ը․
char a[] = {0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
short s = *((short*)a + 1);

Հարց 24։ Հետևյալ կոդում ինչն է «վատ» և ինչպես կարելի է լավացնել․

     void f()
     {
          int* p = new int[N];
          // …
          throw E;
          // …
          delete[] p;
     }



Հարց 23։ Կոնտեյներներ, կառուցվածքը, նրանց հետ գործողությունների բարդությունները։

Հարց 22։ Սորտավորման ալգորիթմներ (merge sort, quick sort, radix sort), բարդությունները։

Հարց 21։ Գրաֆի անցման ալգորիթմներ (BFS, DFS):

Հարց 20։ Մինիմալ կմախքային ծառը գտնելու ալգորիթմ (Prim, Kruskal):

Հարց 19։ Ինչպե՞ս պարզել միակապ ցուցակում ցիկլ կա, թե ոչ։

Հարց 18։ Շրջել միակապ ցուցակը։

Հարց 17։ n տարրեր պարունակող զանգվածը պտտել (rotate) k տարրերով (դեպի աջ կամ ձախ)։

Հարց 16։ Ի՞նչ է անում std::move() գործողությունը։

Հարց 15։ Ի՞նչ նշանակություն ունի noexcept բառը։ Ո՞րն է noexcept֊ի և throw()-ի տարբերությունը (կամ նմանությունը)։

Հարց 14։ Ի՞նչ է «Continuous Integration»֊ը։

Հարց 13։ Ի՞նչ է unit testing֊ը։ Թեսթավորման տեսակները (unit, regression, integration և այլն)։

Հարց 12։ Ինչպես std::set s; բազմությունից ջնջել կենտ անդամները։

Հարց 11։ STL֊ի իտերատորների տիպերը։
Input
Output
Forward
Bidirectional
Random access

Հարց 10։ abort()-ի ու exit()-ի տարբերությունը:

Հարց 9։ Գրել բինար ծառի ինտերֆեյսը:

Հարց 8։ Multi-threading-ի և multi-processing-ի տարբերությունը, առավելություններն ու թերությունները: [Multi-threading-ի մասին մանրամասն բացատրությունը կա այս տեսանյութում]:

Հարց 7։ Smart pointer-ների տեսակները:

Հարց 6։ Ի՞նչ չափի է դատարկ կլասի` class B {}; օբյեկտը: Ի՞նչ չափի կլինի դրանից ածանցյալ, օրինակ, հետևյալ կլասի օբյեկտի չափը.

class D : public B {
int m;
};
Հարց 5։ Ունենք A կլասը, որը ունի “name” անունով անդամ std::string տիպի։
Գրել “Create” անունով ֆունկցիա այնպես, որ հետևյալ ծրագիրը ճիշտ լինի․

A* p = 0;
if (create(p)) {
std::cout << "A created" << p->name << std::endl;
} else {
std::cout << "A not created" << std::endl;
}
Հարց 4։ Ի՞նչ կկատարվի delete p-ի ժամանակ

struct A { int a; };
struct B : A { int b; };

A* p = new B;
delete p;
Հարց Վերասահմանել վերագրման օպերատորը՝ operator=()

Հարց 2։ Վերասահմանել "++" օպերատորը՝ իր post- և preincrement տարբերակներով:

Հարց 1։ Ինչու՞ եք ուզում դուրս գալ Ձեր գործից: