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

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

Հարց 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։ Ինչու՞ եք ուզում դուրս գալ Ձեր գործից: