后端

选择题 1:

Client 在使用 Https 协议访问网站进行通信的过程中,以下说法正确的是?
A. 只用到了对称加密技术
B. 只用到了非对称加密技术
C. 没有用到任何加密技术
D. 同时用到了对称加密和非对称加密技术

答:D 幼儿园常识。

选择题 2:

以下哪些是操作系统中堆和栈的区别?
A. 增长方向
B. 空间大小
C. 分配方式
D. 管理方式

答:A B C D os的知识点 具体转载一下别人写的 :

堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:
(1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;
(2)空间大小不同。每个进程拥有的栈大小要远远小于堆大小。理论上,进程可申请的堆大小为虚拟内存大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;
(3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。
(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有 2 种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca()函数分配,但是栈的动态分配和堆是不同的,它的动态分配是由操作系统进行释放,无需我们手工实现。
(5)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。显然,堆的效率比栈要低得多。
(6)存放内容不同。栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等。当主函数调用另外一个函数的时候,要对当前函数执行断点进行保存,需要使用栈来实现,首先入栈的是主函数下一条语句的地址,即扩展指针寄存器的内容(EIP),然后是当前栈帧的底部地址,即扩展基址指针寄存器内容(EBP),再然后是被调函数的实参等,一般情况下是按照从右向左的顺序入栈,之后是被调函数的局部变量,注意静态变量是存放在数据段或者BSS段,是不入栈的。出栈的顺序正好相反,最终栈顶指向主函数下一条语句的地址,主程序又从该地址开始执行。堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的
forward from: https://blog.csdn.net/K346K346/article/details/80849966/

编程题1:

题目
实现一个 36 进制的加法 0-9 a-z。
示例
输入:["abbbb","1"],输出:"abbbc"
限定语言:C、C++、Java、Python、JavaScript V8、Go

思路:

这里示例的36进制指的应该是:0-9里对应[0,9]、 a-z对应[10,35],直接将它转10进制再去计算

const list = [
  '0', '1', '2', '3', '4',
  '5', '6', '7', '8', '9',
  'a', 'b', 'c', 'd', 'e',
  'f', 'g', 'h', 'j', 'k',
  'l', 'm', 'n', 'o', 'p',
  'q', 'r', 's', 't', 'u',
  'v', 'w', 'x', 'y', 'z'
];
function add(value, addvalue) {
  //36->10->36:string
  k = dd(value) + addvalue;
  var d = ss(k);
  var s = '';
  for (i = 0; i < d.length; i++) {
    for (x = 0; x < list.length; x++) {
      if (parseInt(d[i]) === x) {
        s += list[x];
      }
    }
  }
  return s;
}
//36 -> 10
function dd(value) {
  var valueA = value.split('')
  var k = 0;
  for (i = 0; i < valueA.length; i++) {
    for (x = 0; x < list.length; x++) {
      if (valueA[i] == list[x]) {
        k += x * Math.pow(36, valueA.length - 1 - i);
      }
    }
  }
  return k;
}
//10 -> 36
function ss(value) {
  const list = [];
  var valueA = value;
  while (valueA % 36 != 0) {
    list.push('' + valueA % 36);
    valueA = parseInt(valueA / 36);
  }
  return list.reverse();
}
alert(add('abbbb', 1));

编程题2:

抖音电影票业务支持电影院选座,需要在用户买票时自动推荐座位,如果一个用户买了多张票,
则需要推荐相邻(上下相邻、左右相邻都可)的座位。现在使用一个二维数组来表示电影院的座位,
数组中 0 表示未被选座,1 表示已被选座或者为障碍物,
请实现一个方法求出给定影院中最大可推荐的相邻座位个数。
示例
输入:
[1,0,0,1,0,0,0]
[1,0,0,0,0,1,1]
[0,0,0,1,0,0,0]
[1,1,0,1,1,0,0]
输出:18
限定语言:C、C++、Java、Python、JavaScript V8、Go

思路:

这道题一开始感觉怪怪的,要求上下相邻、左右相邻都满足的座位的话,应该是得不到18的,感觉要得到18的话,我想应该是上下左右任一位置满足不被选就行?后来通过群友提醒,原来是这么理解的意思是在能买多个座位的情况下,怎么样选座能形成最大的相邻选座 ->求最大连通域 -> 输出最大可推荐的座位个数,。如果仔细看这个题原型应该是leetcode-200 跳转链接:200. 岛屿数量 - 力扣(LeetCode)

无脑dfs:

    function ss(seat) {
        let count = 0;
        for (let row = 0; row < seat.length; row++) {
            for (let col = 0; col < seat[0].length; col++) {
                if (seat[row][col] === "0") {
                    dfs(row, col);
                }
            }
        }
        function dfs(row, col) {
            if (row < 0 || row >= table.length ||
                col < 0 || col >= table[0].length ||
                table[row][col] === "1"
            ) return;
            table[row][col] = "1";
            count++;
            dfs(row, col - 1);
            dfs(row, col + 1);
            dfs(row - 1, col);
            dfs(row + 1, col);
        }
        return count;
    };
    let arr = new Array(4).fill('0').map(item => new Array(7).fill('0'));
    arr[0][0] = '1';
    arr[0][3] = '1';
    arr[1][0] = '1';
    arr[3][0] = '1';
    arr[2][3] = '1';
    arr[3][1] = '1';
    arr[3][3] = '1';
    arr[3][4] = '1';
    arr[1][5] = '1';
    arr[1][6] = '1';
    alert(ss(arr));