第一题
class A {
String i = "op";
void func(String s) {
s = "" + 9;
}
static void test() {
A a = new A();
a.func(a.i);
}
}
问: 1,变量i,s,a在堆还是栈中? 2,第8行执行完后a.i的值是什么?
点击查看答案
1,i, s, a都在栈中,new出来的对象A在堆上。(考察js堆与栈:栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null以及对象变量的指针,堆主要存储object,所以字符串变量i,s以及对象指针a都存在栈中,new出来的对象开辟内存存在堆上,对应地址是指针a存的内容) 2,执行完成后a.i的值还是字符串op。(考察参数传递按值传递:a是A类的实例,所以a.i='op',a.func(a.i)这句执行函数,把a.i作为参数传递,该函数会复制一个变量,两个变量完全独立,所以在函数体里只是把复制的那个变量(一个新的局部变量)改变为'op9’,在函数体外的a.i并没有被改变)
第二题
请按顺序写出打印结果,并说明原因。
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-foo2-global
var bar = new obj.foo(); // 由于new绑定的优先级大于bind绑定,所以函数内部this还是obj{} console.log(bar.name); // foo// 此时执行顺序是var bar3,bar2=bar,bar3=bar2, 所以bar3/bar2/bar都是指向同一个对象 var bar3 = bar2 = bar; bar2.name = 'foo2'; // 所以bar2修改属性,bar3的也改变了,此时输出为'foo2' console.log(bar3.name);
// 定时器任务,在最后放入任务队列,window对象没有被改变,所以输出 'global' setTimeout(function() { console.log(window.name); }, 0);
第三题
请写出如下代码运行后产生的结果,并给出解释,说明结果是如何得出的。
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))
点击查看答案
b->f->c->a->d
// 定时器任务属于宏任务,并且需要先在任务队列等待,等到同步任务执行完,执行栈清空,才会在任务队列中按顺序选任务进去 setTimeout(() => console.log('a'));//4. 打印a//Promise 属于异步微任务,在本轮同步任务结束之前执行 Promise.resolve().then( // 1. 打印 b () => console.log('b') // 单引号要改为',然后去掉;号 ).then( // 箭头函数的resolve传递的参数作为下一个then的参数 () => Promise.resolve('c').then( // 执行箭头函数 (data) => { // 把定时器任务也放入任务队列中等待,在第一个定时器之后 setTimeout(() => console.log('d')); //5. 打印d // 2.打印 f console.log('f'); // 此时返回的 数据作为下一个then的参数 return data; } ) ).then(data => console.log(data)); // 3.打印 c
第四题
请写出下面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);
}
}
点击查看答案
var Person = (function () {
function Person (name) {
this._name = name;
}
Person.prototype.greet = function () {
console.log(“Hi, my name is “ + this._name);
}
Person.prototype.greetDelay = function (time) {
var _this = this;
setTimeout(function () {
console.log(“Hi, my name is “ + _this.name);
}, time);
}
})();
第五题
形如1, 1, 2, 3, 5, 8, 13, 21, 34, 55的数列,后一位是前面两位相加(斐波那契数列),写出函数要求找到第 N 位是多少,如:fib(3) => 3 , fib(5) => 8, 要求时间复杂度为O(n)。
输入描述:输入一个正整数N(0<=N<=50)
输出描述:输出第n项的数值
点击查看答案
var fib = function(N) {
if(N==0)return 0;
if(N==2||N==1)return 1;
var prev=1,curr=1;
for(var i=3;i<=N;i++){
var sum=prev+curr;
prev=curr;
curr=sum;
}
return curr;
};
第六题
近期某商场由于周年庆,开启了“0元购”活动。活动中,消费者可以通过组合手中的代金券,实现0元购买指定商品。
聪明的小团想要用算法来帮助他快速计算:对于指定价格的商品,使用代金券凑出其价格即可,但所使用的代金券总面额不可超过商品价格。由于代金券数量有限,使用较少的代金券张数则可以实现价值最大化,即最佳优惠。
假设现有100元的商品,而代金券有50元、30元、20元、5元四种,则最佳优惠是两张50元面额的代金券;而如果现有65元的商品,则最佳优惠是两张30元代金券以及一张5元代金券。
请你帮助小团使用一段代码来实现代金券计算。
点击查看答案
var coinChange = function(coins, amount) {
coins.sort((a, b) => b - a);
let res = amount + 1;
let dfs = function(index, cur, cnt) {
let coins_i = coins[index];
if (cnt + Math.ceil(cur / coins_i) >= res) return;
if (cur % coins_i == 0) {
res = cnt + Math.floor(cur / coins_i);
return ;
}
if (index == coins.length - 1) return ;
for (let i = Math.floor(cur / coins_i); i >= 0; i--)
dfs(index + 1, cur - coins_i * i, cnt + i);
}
dfs(0, amount, 0);
return res > amount ? -1 : res;
}
第七题
给定一个包含非负整数的 M x N 迷宫,请找出一条从左上角到右下角的路径,使得路径上的数字总和最小。每次只能向下或者向右移动一步。
点击查看答案
var minPathSum = function (grid) {
// 时间复杂度和空间复杂度都是 O (m * n);
if (grid.length === 0) return 0;
const dp = [];
const rows = grid.length;
const cols = grid[0].length;
// 实际上你也可以无差别全部填充为MAX_VALUE,对结果没影响,代码还会更少
// 只是有点不专业而已
for (let i = 0; i < rows + 1; i++) {
dp[i] = [];
// 初始化第一列
dp[i][0] = Number.MAX_VALUE;
for (let j = 0; j < cols + 1; j++) {
// 初始化第一行
if (i === 0) {
dp[i][j] = Number.MAX_VALUE;
}
}
}
// tricky
dp[0][1] = 0;
for (let i = 1; i < rows + 1; i++) {
for (let j = 1; j < cols + 1; j++) {
// state transition
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[rows][cols];
};
第八题
小团在一次星际旅行中,耗尽了飞船的能量,迷失在了空间魔方中,空间魔方中有NNN个能量粒子。美团云AI迅速帮小团分析出了空间魔方的能量分布图。
已知小团的飞船被困在能量值最高的点,能量值最高点有且只有一个。飞船每到达一个能量粒子就会吸收对应粒子的能量,该粒子会坍缩成小黑洞,飞船不可到达。小团驾驶的飞船只能从高能粒子驶向低能粒子,且每次只能从6个方向中选择一个前进。(±x,±y,±z)。
请帮助帮小团吸收最高的能量值。