組込みソフトウェアエンジニアの面接の質問の概要

プリプロセッサ(プリプロセッサ)

 

1.の#define文は、1年を持っている(無視して閏年問題を)の秒数を示すために、一定の命令で前処理しました

#define SECONDS_PER_YEAR(60 * 60 * 24 * 365)UL

 

私はいくつかのことを見てみたいです:

 

1)文法の#defineの基礎(例えば:それはセミコロン、括弧の使用など)で終了することができません。

 

2)。あなたはプリプロセッサ定数式の値を計算する方法を知っているので、直接書き込む代わりに実際の値を計算するあなたは年に何秒を計算するにはどうすればよい、より明確かつコストなしです。

 

3)この式はオーバーフロー機械整数16ビットになるだろうことを認識 - 長整数Lを署名するために使用するように、これは長い整数定数であることをコンパイラに指示します。

 

4)あなたが表現UL(unsigned long型整数)を使用する場合は、良い開始点を持っています。第一印象が重要であることを覚えておいてください。

 

2.書く「標準」マクロMIN、マクロ入力二つのパラメータと戻り小さい方

 

#define MIN(A、B)((A)<=(B)(A)))

C / C ++ C / C ++開発のテストこのテストは、以下の目的のために提供されています。

マクロアプリケーション1)識別の#define基本的な知識。埋め込み(インライン)演算子は、標準Cの一部になるまで、マクロが生成されたコードを埋め込むだけ便利で、組込みシステムのために、必要とされる性能を達成するために、埋め込まれたコードがしばしば必要であるので、これは重要です方法。

三重項条件演算子の2)知識。なぜなら、それはこの使用方法の詳細最適化されたコードは、非常に重要である場合-THEN-ELSEより生成するコンパイラを許可することを、この演算子の存在のC。

3)。慎重に括弧内のマクロパラメータを知ります

次のコードはどうなるの書き込み時に何が起こった:4)私はまたのような、マクロの副作用でこの問題を議論し始めましたか?

最低= MIN(* P ++、B)。

 

3.ある#エラー目的プリプロセッサ識別は何ですか?

 

あなたは答えがわからない場合は、参考1を参照してください。正常な人とオタクを区別するこの問題は便利です。唯一のオタクは次のように見つけるためには、付録C言語の教科書を読んでます

質問に答えます。あなたがオタクを探していない場合はもちろん、候補者は、より良い彼女が答えを知らない願っています。

 

無限ループ(無限ループ)

 

4.組込みシステムは、多くの場合、無限ループを使用して、どのように無限ループにそれを書くためにCを使用することができますか?

 

いくつかの解決策に伴う問題。私の好ましい解決策は以下のとおりです。

一方、(1){}

いくつかのプログラマは、以下のプログラムを好みます:

にとって(;;) { }

構文はそれがあったか、最後に正確にしないため、この構築体は私を困惑します。候補者が解決策としてこれを与えた場合、私はそうするためにそれらを探求する機会としてこれを使用します

基本原理。彼らの基本的な答えがある場合:「私はそうするように教えられましたが、理由について考えていませんでした。」これは私が悪い印象を残す与えるだろう。

第三の選択肢は、使用することです後藤

ループ:

...

後藤ループ;

上記のシナリオを与えられている候補者は、これは(おそらく良いことです)アセンブリ言語のプログラマされているか、彼はBASIC / FORTRANは、新たな分野をプログラマ入りたいです。

 

DATA文(データ宣言)

 

5.以下の定義は、変数Aです

 

a)は整数(整数)

b)は、整数へのポインタ(A整数へのポインタ)

C)その点ポインタの整数(整数へのポインタへのポインタ)へのポインタへのポインタを

10の整数のd)のアレイ(10の整数のアレイ)

10のポインタのE)配列、整数へのポインタの数(整数の10個のポインタの配列)

F)の整数のアレイ(10個の整数の配列へのポインタ)にポインタ10を有し、ポインティング

g)を関数ポインタは、関数は、整数(引数及び戻り整数)のように整数を取る関数へのポインタを整数の引数を有し、返し

H)10個のポインタの配列、整数の引数を取り、整数の引数を取り、整数を返す関数の整数(10ポインタの配列を返す関数へのポインタ)

 

答えは次のとおりです。

 

a)はint型。//アン整数

b)はint型*; 整数へ// Aポインタ

C)のint **。整数へのポインタへ// Aポインタ

D)INT [10]。// 10個の整数の配列

E)、INT * [10]。//整数に10個のポインタの配列

F)INT(*)[10]。10個の整数の配列に// Aポインタ

グラム)INT(*)(int型); 整数の引数を取り、整数を返す関数Aへのポインタ//

H)INT(* [10])(INT)。//整数の引数を取り、整数を返す関数への10個のポインタの配列

 

それは多くの場合、本の種類は、質問に答えることができているで簡単に見てすべきいくつかの問題があることを主張している、私は同意するものとします。私がこれを書いている時点で、文法の正しさを決定するために、私は実際に本をチェックします。

私は面接れたときしかし、私はこの質問をした(または類似)することを期待しています。インタビューのこの時間の間に、私はこの質問への答えを知っていることを確認しますので。知らない候補者

すべての答え(または少なくともほとんどの回答の)面接は面接の準備をしていない場合は、このインタビューのための準備がない、彼らは何を準備するのでしょうか?

 

静的

 

6.キーワード静的である役割とは何ですか?

 

この簡単な質問はほとんど完全に答えはありません。Cでは、staticキーワードは、3つの異なる役割を持っています:

 

1)関数の本体で、定数は、関数内の静的変数はプロセスと呼ばれているように、その値を維持するように宣言されます。

静的関数によってモジュール内でアクセスすることができるが、他の機能は、外部モジュールのアクセスできないように2)モジュール(ただし、in vitroでの機能)に、変数が宣言されます。これは、ローカル、グローバル変数です。

3)モジュール内の、静的関数のみモジュール内の他の関数によって呼び出されることができるように宣言されます。つまり、この関数は、その宣言モジュールローカルスコープでの使用に限定されています。

非常に少数の人々は三分の一を理解してほとんどの候補者が正しく、最初の部分、答えは正しい部品の後半部分に答えます。彼は明らかにローカライズされたデータとコード範囲の利点と重要性を理解していないので、これは、候補者に深刻な弱点です。

 

CONST

 

7。constキーワードは、どのような意味ですか?

 

「constの手段定数」と私はアマチュアを扱った知っていた:私はちょうどインタビューが言っ聞きました。すべての読者ができることとできないことをconstのために非常に精通している必要があります:昨年、ダンサックスはとてもESP(組込みシステムは、プログラミング翻訳)、彼の記事のアウトラインのconstのすべての使用に完全になっています。

 

あなたがその記事を読んでいない場合は、constの手段はそれに「読み取り専用」と言って、それを十分。この答えは完全にお答えしていませんが、私は正しい答えとしてそれを受け入れます。(あなたはより詳細な答えを知りたい場合は、慎重にサックスの記事を読んで、右)候補が正しくこの質問に答えることができれば、私は彼に、追加の質問をします:次の文の意味は何ですか?

constがint型。

int型のconst A;

const int型*;

int型* CONST。

int型のconst * constの。

 

最初の二つは整数定数であり、同じです。第三の手段CONST整数(すなわち、整数が変更されず、ポインタ)へのポインタです。第4の手段は、整数定数のポインタへのポインタである(ある整数のポインタを変更することができるが、ポインタは変更されません)。最後には、一定のポインタ(ポインタが変更されていない間、整数ポインタは、変更することができない場合)番号整数定数へのポインタである暗示します。候補者が正しくこれらの質問に答えることができれば、彼は私に良い印象を残しました。ちなみに、おそらくあなたもconstキーワードなくて、それはまだ簡単に書き込みプログラムはなぜ、私はconstキーワードに非常に親愛行う必要があり、正常に機能することができる、求めることができますか?私はまた、いくつかの理由を次のようしています:

 

1)constはの役割は、あなたのコードはいくつかの非常に有用な情報を伝える読むことです、実際には、パラメータのconstは、このパラメータのユーザ・アプリケーションの目的を伝えます宣言。あなたが他の人が残したゴミを掃除に多くの時間を費やしていた場合、あなたはすぐにこの追加情報を理解することを学びます。(もちろん、他の誰かが稀にゴミを残さない、使用のconstをクリーンアップできるようにする方法を知っています。)

 

2)オプティマイザにより、いくつかの追加情報、キーワードCONSTは、よりコンパクトなコードを生成することができます。

 

3)constキーワードの合理的な使用は、自然にこれらのパラメータを保護するために、コンパイラがコードを防ぐために、変更することはしたくないことができます、それは意図的でないにして説明します。要するに、これバグを減らすことが発生します。

 

揮発性

 

8.どのような意味がvolatileキーワードであり、三つの異なる例を与えます

 

揮発性変数は、コンパイラは、この変数の値を想定する必要はないので、この変数は、予期せず変更されることがあると定義。オプティマイザは慎重でなければならないたびに、この変数が使用され、この変数の値を再読み込みの代わりにレジスタに格納されたバックアップを使用して、正確、こと。ここでは揮発性の変数のいくつかの例は以下のとおりです。

 

1)ハードウェア・レジスタ・デバイス(例:ステータスレジスタ)

2)非自動変数への割り込みサービスルーチンへのアクセス(非自動変数)

3)マルチスレッドアプリケーションでの変数が複数のタスクで共有します

 

私は質問の人々が雇用されていないことを答えることはできません。私は、これは根本的な問題のCプログラマや組み込みシステムのプログラマの区別だと思います。多くの場合に対処するなど、ハードウェア割り込み、RTOS、と組み込みシステムのプログラマは、これらの使用は、揮発性の変数を必要とします。災害につながるどのように揮発分を知ってはいけません。

 

インタビューが正しくこの質問(このケースになるかどうか、ああ、疑いを)答えていることを前提に、私はこの男を見て、本当に揮発性の完全な意義を理解し、下に少しを取得します。

 

1)パラメータは、いずれかのconstも揮発性であることが可能になることができますか?理由を説明します。

2)ポインタは、揮発性であることができますか?理由を説明します。

3)次の関数と間違っては何です:

int型の広場(揮発性のint * PTR)

{

リターン* ptrは* ptrは、

}

 

ここで答えは:

 

1)はい。例では、読み取り専用のステータス・レジスタです。それが予期せず変更される可能性があるのでそれは揮発性です。プログラムはそれを変更しようとするべきではありませんので、それはconstのです。

 

2)はい。これは非常に一般的ではありませんが。割り込みサービスルーチンの一つは、バッファへのポインタを変更する場合の例です。

 

3)このコードのいたずらがあります。このコードの目的は、値の二乗にポインタPTR *ポイントを返すことであるが、揮発性の* PTRパラメータ点から、コンパイラは次のようなコードが生成されます。

int型の広場(揮発性のint * PTR)

{

int型のA、B;

= * PTR;

B = * PTR;

* bを返します。

}

以来* PTRの値が突然変更され、従って、bは異なっていてもよいしてもよいです。その結果、このコードは、あなたが乗値を期待するよりも、返すことができます!次のように正しいコードは次のとおりです。

長い広場(揮発性のint * PTR)

{

int型;

= * PTR;

* Aを返します。

}

 

ビット演算(ビット操作)

 

9.組み込みシステムは、常に登録するユーザーまたは可変ビット演算を必要とします。2つのコード、ビット3の第1のセットを書き込むために、整数変数aを与えられ、第二のビット3をクリアします。上記の二つの操作で、他のビットは変化せず維持します。

 

この質問には3個の基本的な応答があります。

 

1)。私が開始するのか分かりません。組み込みシステムのための任意の仕事をしたことがなかったインタビュー。

2)ビットフィールド。ビットフィールドは、C言語で死んだ事に投げ込まれている、それは異なるコンパイラ間、あなたのコードがポータブルではないことを保証し、また、あなたのコードが再利用可能でないことを確認します。私のコンパイラ他の方法は、ビットフィールドを達成するため残念ながら、私は最近、ビットフィールドと私にはそれゆえ完全に役に立たないを使用し、より複雑な通信チップ、インフィニオンのドライバを見ました。道徳的:ハードウェアの男本当の一片の非埋め込み側を聞かせてはいけません。

3)。#defineを操作し、ビットマスク。これは、移植性の高い方法が使用されるべき方法です。次のように最善の解決策は以下のとおりです。

 

#define BIT3(0x1の<< 3)

静的な値int;

空set_bit3(無効)

{

| = BIT3。

}

空clear_bit3(無効)

{

&=〜BIT3。

}

いくつかの定数の説明を定義しながら、セットとクリアな値にのような一部の人々は、これは許容され、マスクを定義します。演算子〜=と&= |、説明定数:私はいくつかの重要なポイントを見たいのですが。

 

C / C ++開発を(固定メモリロケーションへのアクセス)、固定メモリロケーションへのアクセス

 

10.組み込みシステムは、多くの場合、特定の要件は、メモリ位置の特性にアクセスするプログラマました。プロジェクトには、可変0x67a9値0xaa66整数絶対アドレスを設定する必要があります。コンパイラは、純粋なANSIコンパイラです。このタスクを達成するために記述したコード。

 

あなたは、整数キャスト(型キャスト)への絶対アドレスにアクセスするためにポインタが合法であることを知っているかどうかをこの質問をテストします。異なる個体や異なるスタイルの問題の実装と。次のような一般的なコード:

 

int型* ptrは、

PTR =(int型*)0x67a9。

*のPtr = 0xaa55。

一つの方法は、よりあいまいです。

*(int型* constの)(0x67a9)= 0xaa55。

あなたの好みは、複数の第二の選択肢に動作しますが、私が提案している場合でも、あなたはインタビューの中で最初のオプションを使用します。

 

割り込み(割り込み)

 

サポート割り込みに標準Cを聞かせて - 11.中断は、コンパイラベンダーの多くにリードが拡張を提供する組み込みシステムの重要な部分です。代表の事実と新しいキーワード__interruptを生産、です。次のコードは、割り込みサービスルーチン(ISR)を定義するために__interruptキーワードを使用して、このコードには、してくださいコメント。

 

__interruptダブルcompute_area(二重半径)

{

二重の面積= PI *半径*半径;

printf( "面積=%のF" 領域)

エリアを返します。

}

この関数は、あまりにも多くのミスがあり、どこを開始するために理解するにも難しいです。

 

1)。ISRは、値を返すことはできません。あなたがこれを理解していない場合は、雇われることはありません。

 

2)。ISRは通過しないことができます。あなたがこれを表示されない場合は、のあなたのチャンスは、最初の項目に相当雇われています。

 

3)多くのプロセッサ/コンパイラでは、浮動小数点演算は、リエントラントではありません。一部のプロセッサ/コンパイラは、いくつかのプロセッサ/コンパイラはISRで浮動小数点演算を行うことを許可されているスタックの量、で登録する必要があります。また、ISRはISRで浮動小数点演算を実行することは賢明であり、短く、効率的であるべきです。

 

4)と同じ系統の第三の点、のprintf()は、多くの場合、再入および性能の問題があります。あなたは、第3および第4のポイントを失った場合、私はあなたにあまりにも難しいことではないでしょう。あなたは2点を得ることができる場合言うまでもなく、その後、あなたの雇用の見通しは良く見ています。

 

コードの例(コード例)

 

12.なぜ、次のコードの出力は何ですか?

 

ボイドのfoo(無効)

{

unsigned int型、A = 6;

INT B = -20。

(+ B> 6)プット( "> 6"):プット( "<= 6")。

}

 

この質問はあなたが自動変換の原則整数C言語を知っているかどうかのテスト、私はいくつかの開発者は非常によくわかっていないことがわかりました。質問に、この符号なし整数の答えは出力が何であるか、どんなに「> 6」であります その理由は、オペランドのすべてのタイプの式の符号付きと符号なしのタイプは自動的にunsigned型に変換されているということです。従って-20非常に大きい正の整数となり、6より大きいに発現評価します。これは、組み込みシステムの符号なしのデータ型のために頻繁に使用されなければならない非常に重要なの豊富です。あなたはこの1つ間違っを取得した場合は、エッジに仕事を得ることはありません。

 

コードフラグメントを、以下の13の評価:

 

unsigned int型のゼロ= 0。

unsigned int型compzero = 0xFFFFの。

/ *ゼロの1の補数* /

intはない場合、16ビットプロセッサは、上記のコードが正しくない、と言うことです。これは次のように記述する必要があります。

unsigned int型compzero =〜0;

 

この質問は本当に候補がワード長の重要性を理解しているかどうかを取得します。私の経験では、良い組込みプログラマは、しかし、批判的なハードウェアとその限界についての詳細を知っている必要が迷惑としてPCのハードウェアをプログラミングする傾向があります。

 

この段階では、候補者または完全には落胆や信頼を獲得することに決定しました。候補者は非常に良いではない場合、テストはここで終了します。候補がよくやっている場合しかし、その後、私はより困難である、私は非常に最良の候補がうまくやるだろうと思い、次の追加の問題を投げます。これらの質問をして、私は問題ではなく、答えに対処するための複数の候補の方法を見てみたいと思います。ノー時にあなたがエンターテイメントが何であるか、問題では...

 

動的なメモリ割り当て(動的メモリ割り当て)

 

14.されない一般的な非組み込みコンピュータ、組込みシステム又はプロセスはヒープ(ヒープ)ダイナミックからメモリを割り当てられているが。だから、組み込みシステムでは、動的なメモリ割り当ての問題は、どのような発生する可能性がありますか?

 

ここでは、私が言及メモリの断片化、ようにガベージコレクション、変数の実行時間、およびに問題に候補者を期待します。このトピックでは、広くESP誌で議論されている(主にPJ Plauger、彼の説明は、はるかに私はここで言及することができます任意の説明より)、戻ってすべてのこれらの問題を見て!誤った安心感に候補者を許可した後、私はこのちらほらを思い付く:次のコードの出力は何ですか、なぜ?

 

シャア* PTR。

IF((PTR =(CHAR *)のmalloc(0))== NULL)

プット(「NULLポインタを得ました」)。

そうしないと

プット(「有効なポインタを手に入れました」);

 

これは興味深い質問です。最近、不注意malloc関数に0の関数値に渡された私の同僚の1の後に、有効なポインタを取得し、私はこれについて考えました。これは上記のコードで、出力コードは「有効なポインタを手に入れた」です。私は、このような質問は面接ライブラリルーチンは右のそれを行うことを考えるかどうかを確認することです議論を始めるためにこれを使用します。正しい答えを得ることが重要ですが、問題を解決し、あなたには、いくつかの基本的な原則に意思決定がより重要になります。

 

typedef

 

15. C言語のデータ型でtypedefの使用頻度の高い同義語既存のステートメント。プリプロセッサにも似た何かを使用することができます。たとえば、次の例を考えてみます。

 

#define DPSのstruct S *

typedefは構造体S * TPS。

どちらの場合も、その意図は、構造体sへのポインタにDPSやTPSを定義します。どちらの方法が良いですか?(もしあれば)なぜ?

これは、この質問(正当な理由)が祝福されるように、非常にデリケートな問題で、誰の答えです。答えは次のとおりです。typedefをより良いです。次の例を考えてみます。

DPS P1、P2;

TPS P3、P4;

最初の拡張

構造体S * P1、P2;

構造体へのポインタであるP1、上記のコードの定義、p2はあなたが望むものはおそらくないが、実際の構造です。第二の例は、正しく2つのポインタP3およびP4を定義します。

あいまいな構文

 

16. Cは、次のような構造が合法であり、それは何をやっているそうだとすれば、いくつかのぞっとするような構造を可能に?

 

INT A = 5、B = 7、C。

C = A +++ B。

この問題は、このクイズにハッピーエンドとして使用されます。あなたがそれを信じるかどうかは、上記の例では完全に合法的な構文です。質問は、コンパイラがそれを処理する方法ですか?レベルが高いコンパイラの作家が実際に最高の原則に従って、問題を議論されていない、コンパイラは可能なすべての法的な使用を扱うことができるはずです。従って、上記のコードは次のように扱われます。

C = A + B ++。

したがって、ライン・コードを保持した後= 6、B = 7、C = 12。

あなたは答えを知っている、または正しく推測した場合は、よくやりました。あなたは答えがわからない場合、私は問題としてこれを考慮していないでしょう。私は、問題を発見した最大の利点です:これは、コードの文章のスタイル、良い話題の読みやすさ、コードの修正可能です。

 

- 終わり -

オリジナルの記事は、0公表 ウォンの賞賛2 ビュー2241を

おすすめ

転載: blog.csdn.net/lyh290188/article/details/104362778
おすすめ