美団インタビューの質問の分析
簡潔な答え
1.質問:次の変数i、s、aはヒープ上にありますか、それともスタック上にありますか?最後に実行されたaiの値は何ですか?
class A {
String i = "op";
void func(String s) {
s = ""+9;
}
static void test() {
A a = new A();
a.func(a.i);
}
}
-
調査ポイント
スタックメモリ
スタックメモリは主に、ブール、数値、文字列、未定義、Null、オブジェクト変数へのポインタなど、さまざまな基本タイプの変数を格納するために使用されます。ヒープメモリ
ヒープメモリは主にオブジェクトオブジェクトを格納します
注:Aはヒープメモリに格納された新しいオブジェクトであり、対応するアドレスはポインタaの内容であるため、aはスタックメモリに残ります。
パラメータの受け渡し(値による受け渡しを検討)
ECMAScriptのすべての関数のパラメーターは値で渡されます
-
問題分析
i、s、aは依然として基本的なタイプの変数であるため、スタックメモリに格納されます。a是A的一个实例,所以a.i='op',执行a.func(a.i)函数,相当于传入'op'参数,该函数会赋值一个变量,两个变量是完全独立的,s=''+9只是在复制的变量上执行的,函数体外的a.i并没有改变
2.印刷結果を順番に書き留め、理由を説明してください。
var name = 'global';
var obj = {
name: 'local',
foo: function(){
this.name = 'foo';
}.bind(window)
};
var bar = new obj.foo();
setTimeout(function() {
console.log(window.name);
}, 0);
console.log(bar.name);
var bar3 = bar2 = bar;
bar2.name = 'foo2';
console.log(bar3.name);
-
検査ポイント
イベントループ同期および非同期のさまざまな状況、およびタイマーの使用
練る
異なる結合優先順位の問題
参照型の割り当て
複合型の値の割り当ては参照割り当てであり、すべて同じオブジェクトを指します
-
問題分析
'foo' // bindは関数を返し、この関数はウィンドウにバインドされ、関数はnewによって構築され、新しいオブジェクトが返されます。これは関数本体でオブジェクトを指し、bindはハードバインディングです。新しいバインディングはハードバインディングよりも優先度が高いため、これは引き続き禁止にバインドされます。bar.name= this.name = '
foo''foo2' // var bar3 = bar2 = bar;複合型値の割り当ては割り当てを参照します、bar3、bar2、barはすべて同じオブジェクトを指しているため、bar2が変更されると、bar3とbarの内容も変更されるため、bar3.name = bar2.name = 'foo2''global
' // setTimeout setsタイマー。すべてのイベントの最後にコールバックの実行を配置し、キューにジャンプできないため、console.log(window.name)の出力はグローバルの下のname = 'global'になります。
3.質問:次のコードを実行した後に生成された結果を書き留めて、結果がどのように取得されるかを説明してください。
setTimeout(() => console.log('a'));
Promise.resolve().then(
() => console.log('b’);
).then(
() => Promise.resolve('c').then(
(data) => {
setTimeout(() => console.log('d'));
console.log('f');
return data;
}
)
).then(data => console.log(data));
-
検査ポイント
promise(マクロタスク)とsetTimeout(マイクロタスク)の実行順序
-
トピック分析
実行順序:約束->次の(b)->同期(f)
.resolve异步的(c) .JS执行原理从上到下的(a) .then()——>setTimeout异步的(d)
4.次のES6コードコンパイルによって生成されたES5コードを記述してください
class Person {
constructor (name) {
this.name = name;
}
greet () {
console.log(`Hi, my name is ${this.name}`);
}
greetDelay (time) {
setTimeout(() => {
console.log(`Hi, my name is ${this.name}`);
}, time);
}
}
-
検査ポイント
ES6構文の理解、JSプロトタイプの理解、この点の理解
-
トピック分析
ES5は、出力にJSプロトタイプを使用し、ウィンドウの下でこれを定義します。これには、中間変数の転送が必要です。
2つの関数greet()とgreetDelay()は、実際にはPersonプロトタイプチェーンの下にある2つのインスタンス関数オブジェクトです。
5. 1、1、2、3、5、8、13、21、34、55のような数字のシーケンス、最後の桁は最初の2桁の加算です(フィボナッチ数列)、N番目を見つける関数を記述しますたとえば、fib(3)=> 3、fib(5)=> 8のように、ビット数はいくつですか。O(n)の時間計算量が必要です。
if(n == 0 || n == 1) cout << 1 << endl;
else{
long long a = 1, b = 1;
for(int i=2; i<=n; i++){
b = a + b;
a = b - a;
}
cout << b << endl;
fib(0)= fib(1)= 1;次の数値は、最初の2つの数値の合計であり、bは入力値の出力に相当し、aの値はn-1番目に変更できます。スワップによる結果出力へ。もう1つの重要なポイントは、これら2つの変数にどのタイプを指定するかです。オーバーフローの問題が発生しますか。
6.コードは通貨換算を実現します。現在100元の商品があり、50元、30元、20元、5元の4つのバウチャーがあるとすると、最良のオファーは50元の2つのバウチャーです。 65元の商品があり、最高の割引は2つの30元のバウチャーと5元のバウチャーです。
for(int p=0;p<size;++p){
for(int q=0;q<size-p-1;++q){
if(coins[q]>coins[q+1]){
swap(coins[q],coins[q+1]);
}
}
}
int *F=new int[cash+1];
for(int i=0;i<=cash;++i){
F[i]=cash+1;
}
F[0]=0;
for(int j=0;j<=cash;++j){
for(int k=0;k<size;++k){
if(j<coins[k]){
break;
}
else{
F[j]=min(F[j-coins[k]]+1,F[j]);
}
}
}
この質問のアイデアは、最大の額面から変数計算を設定し、次に小さい額面から少しずつ選択することです
7.非負の整数を含むMx Nの迷路がある場合、パス上の数字の合計が最小になるように、左上隅から右下隅へのパスを見つけてください。一度に1ステップ下または右にしか移動できません。
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
cin>>a[i][j];
}
}
for(int i=M-1;i>=0;i--){
for(int j=N-1;j>=0;j--){
if(i+1<M && j+1<N)
{
a[i][j] += min(a[i+1][j],a[i][j+1]);
}
else if(i + 1< M)
{
a[i][j] += a[i+1][j];
}else if(j + 1 < N)
{
a[i][j] += a[i][j+1];
}
}
}
この質問では、2次元配列を調べます。まず、指定された配列を2次元配列に保存してから、手順を実行しないかどうかを判断します。低い値が下がっていて、正しい部分です(ただし、To事前判断を行います)、各ステップの配列で移動した距離を格納し、配列の内容を追加して最短の出力距離を表示します。