前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构和算法面试常见题必考以及前端面试题

数据结构和算法面试常见题必考以及前端面试题

作者头像
汀丶人工智能
发布2023-03-07 18:52:10
5890
发布2023-03-07 18:52:10
举报
文章被收录于专栏:NLP/KGNLP/KG

1.数据结构和算法

1.1 反转单向链表

代码语言:javascript
复制
public class Node {
    public int value;
    public Node next;
}

public Node reverseList(Node head) {
    Node pre = null;
    Node next = null;
    while (head != null) {
        next = head.next;
        head.next = pre;
        pre = head;
        head = head.next
    }
    return pre;
}

1.2 在顺序表中插入和删除一个结点平均移动多少个结点?

在等概率的情况下,顺序表插入一个结点需要平均移动n/2个结点。删除一个结点需要平均移动(n-1)/2个结点。具体的移动次数取决于长度n和位置i,两者越近,移动的越少。

1.3 如何以递归和非递归方式实现二分查找

非递归:

代码语言:javascript
复制
private int binarySearch(int[] arr, int searchKey) {
  if (arr == null) {
    return -1;
  }
  int n = arr.length;
  int left = 0;
  int right = n - 1;
  while (left <= right) {
    int mid = left + ((right -left) >> 1);
    if (arr[mid] > searchKey) {
      right = mid - 1;
    } else if (arr[mid] < searchKey) {
      left = mid + 1;
    } else {
      return mid;
    }
  }
  return -1;
}

递归:

代码语言:javascript
复制
private int binarySearchRecursive(int[] arr, int left, int right) {
  if (arr == null) {
    return -1;
  }
  int n = arr.length;
  int left = 0;
  int right = n -1;
  while (left <= right) {
    int mid = left + ((right - left) >> 1);
    if (arr[mid] > searchKey) {
      binarySearchRecursive(arr, left, mid - 1);
    } else if (arr[mid] < searchKey) {
      binarySearchRecursive(arr, mid + 1, right);
    } else {
      return mid;
    }
  }
  return -1;
}

需要注意的是,二分查找算法的时间复杂度为O(logn),最坏情况下的时间复杂度为O(logn)

1.4 求二叉树的深度

代码语言:javascript
复制
private int getDepth(Node node) {
  if (node == null) {
    return 0;
  }
  int left = getDepth(node.left);
  int right = getDepth(node.right);
  return left > right ? (left + 1) : (right + 1);
}

1.5 如何在排序的数组中,找出给定数字出现的次数

其实我的想法是通过hashmap来实现,其实也没必要在乎数组是否是排序的。时间复杂度方面,遍历整个数组,将数组元素添加到hash中,最后再查询,时间复杂度应该是O(n).

代码语言:javascript
复制
function getTimes(arr, key) {
    var n = arr.length;
    var hash = {};
    for (var i = 0; i < n; i ++) {
        var ele = arr[i];
        if (!hash[ele]) {
            hash[ele] = 1;
        } else {
            hash[ele] ++;
        }
    }
    if (hash[key]) {
        return hash[key];    
    } else {
        return -1;
    }
}
代码语言:javascript
复制
    private static void stasTimes(int[] arr, int key) {
        int len = arr.length;
        HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
        for (int i =0; i < len; i++) {
            if (hash.containsKey(arr[i])) {
                Integer val = hash.get(arr[i]) + 1;
                hash.put(arr[i], val);
            } else {
                hash.put(arr[i], 1);
            }
        }
        for (Integer hashKey: hash.keySet()) {
            if (hashKey.intValue() == key) {
                System.out.println(key + " has appeared " + hash.get(hashKey) + " times");
            }
        }
    }

1.6 如何把字符串中的指定字符移动到字符串的前面

代码语言:javascript
复制
private char[] moveChar(String str, char a) {
  char[] arr = str.toCharArray();
  int i = arr.length - 1;
  while (arr[i] != a) {
    i --;
  }
  for (int j = i - 1; j >= 0; j --) {
    if (arr[j] != a) {
      arr[i] = arr[j];
      arr[j] = a;
      i --;
    }
  }
  return arr;
}

1.7 排序算法总结

冒泡排序

代码语言:javascript
复制
public static void bubbleSort(int[] arr) {
  if (arr == null || arr.length == 0) {
    return;
  }
  for (int i = 0; i < arr.length - 1; i++) {
    for (int j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j] > arr[j+1]]) {
        swap(arr, j+1, j);
      }
    }
  }
}
public static void swap(int[] arr, int i, int j) {
  int temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

1.8 数组和链表的区别

  • 数组必须事先定义固定的长度,链表采用动态分配内存的形式实现。
  • 数组从栈中分配空间,自由度小;链表从对中分配内存,自由度大,但管理麻烦。
  • 数组中的数据在内存中时顺序存储的,链表是随机存储的。
  • 数组便于查询;链表便于插入删除。

1.9 什么排序元素比较次数和数组初始状态无关

选择排序

##1.10 排序算法比较

排序算法

平均时间复杂度

最好情况

最坏情况

空间复杂度

稳定性

冒泡排序

O(n^2)

O(n)

O(n^2)

O(1)

稳定

选择排序

O(n^2)

O(n^2)

O(n^2)

O(1)

不稳定

插入排序

O(n^2)

O(n)

O(n^2)

O(1)

稳定

希尔排序

O(nlogn)

O(nlog^2n)

O(nlog^2n)

O(1)

不稳定

归并排序

O(nlog(n))

O(nlogn)

O(nlogn)

O(n)

稳定

快速排序

O(nlogn)

O(nlogn)

O(n^2)

O(logn)

不稳定

堆排序

O(nlogn)

O(nlogn)

O(nlogn)

O(1)

不稳定

计数排序

O(n+k)

O(n+k)

O(n+k)

O(k)

稳定

桶排序

O(n+k)

O(n+k)

O(n^2)

O(n+k)

稳定

基数排序

O(n*k)

O(n*k)

O(n*k)

O(n+k)

稳定

.

2.面试题

2.1 百度一面

  1. 如何实现水平垂直居中
  2. Position 属性的几种区别
  3. 讲一下盒子模型
  4. BFC 怎么实现
  5. 如何实现左右固定,中间自适应的布局
  6. 用 JS 实现一个柯里化函数
  7. 用 JS 实现一个栈
  8. 实现一个 TS 类,如 Partial 、Tick
  9. JS 任务执行机制
  10. 给出一段 Promise+setTimeout 的代码,写出输出顺序
  11. Promise 有哪些方法
  12. 对 async/await 的理解
  13. HTTP 请求响应头有哪些
  14. HTTPS 的是如何进行数据加密的

2.2 字节

  1. redux 中间件有了解吗
  2. Hooks 有了解吗
  3. Canvas 了解吗
  4. 开发过程中图表组件用的是是什么,看过 Echarts 的源码吗
  5. 在开发过程中遇到了哪些难点

2.3 小米

一面(技术面)

基本围绕简历聊,印象比较深的有几个问题

  • 1.vue 的源码是否看过,说一下比较有收获的几个点
  • 2.说一下 css 的三大特性并展开说一下应用场景
  • 3.说一下 CSS 七层层叠顺序
  • 4.说一下从浏览器输入网址到页面渲染中间发生了什么
  • 5.说下你知道的 HTTP 状态码并说出它们的出现场景

二面(技术面)

主要聊项目,技术聊的比较少,说一下印象深的问题

  • 1.如何实现一个简单的单点登录
  • 2.说一下关系数据库和非关系数据库的区别,并说下使用场景
  • 3.说一下关系数据库外键的使用

三面(技术面)

有印象的问题

  • 1.手写翻转二叉树
  • 2.说下归并排序的思路和应用场景
  • 3.说下你知道的设计模式及应用场景
  • 4.说一下从浏览器输入网址到页面渲染中间发生了什么
  • 5.如何用缓存进行前端优化;说下浏览器缓存、DNS 缓存、nginx 缓存、服务端缓存的区别;强缓存和协商缓存的应用

四面(技术面)

项目经历为主,以及管理方面的问题,技术方面没聊,有印象的问题

  • 1.如何确保项目按时交付
  • 2.如何安排开发和管理的时间分配
  • 3.如何体现项目价值

五面(技术加面)

感觉是专门准备了一些有深度的问题来问,有印象的有

  • 1.如何进行前端性能优化
  • 2.说说重绘、重排、回流
  • 3.如何开启 GPU 加速,GPU 加速的作用是什么
  • 4.是否了解浏览器内核相关技术
  • 5.说一下 jsbridge 是如何实现的
  • 6.说一下 V8 的垃圾回收机制
  • 7.说一下 VUE3.0 比 VUE2.0 做了哪些改动

1、关于ES6 Proxy (2019 今日头条)

2、你觉得TypeScript 和 JavaScript有什么区别

  • 语言层面
  • Javascript 和 TypeScript 都是ECMAScript 的具体实现
  • TypeScript 是静态类型,而JavaScript 是动态类型
  • TypeScript 扩展了JavaScript 并且完全包容javascript 执行方面
  • TS 需要编译
  • JS 不需要编译 厂商层面
  • Javascript 由Netscape 率先

TypeScript中的 type 和 instance 区别

代码语言:javascript
复制
interface User {
  name: string,
  age: number
}

insterface SetUser {
  (name: string, age: number) : void;
}


type SetUser = (name: string, age: number) => void;

// 都允许扩展


// interface extends type

type Name = {
  name: string;
}

instance
  • 不同点
代码语言:javascript
复制
// type 不是一个类型,它是类型别名
 // type 可以声明基本类型别名,联合类型,元祖等类型
 // 基本类型别名
 type Name = string


// interface 可以 而type不行

// interface 能够声明合并
interface User {
  name: string,
  age: number
}
interface User {
  sex: string
}

new Error 不会终止成员运行

async / await 如果右边的方法执行出错了该怎么办 (百度一面2020)

  • 方式一 使用Promise 的catch 方法捕获异常 不完善
  • 方式二 在async 函数中使用try -catch 捕获异常 (推荐)
代码语言:javascript
复制
async function f() {
  console.log(1)
  await new Promise((resolve, reject) => {
    console.log(2)
    throw new Error('出错了')
  }).catch(err => {
    console.log(3)
    console.log('执行失败了')
  })
  console.log(4)
}
// 1234

使用 try-catch 的时候,会把容易引发异常的代码写到try 里面

代码语言:javascript
复制
async function f() {
  try {
    // await new Promise((resolve, reject) => {
    //   // throw new Error('出错了')
    //   resolve()
    // })
    await new Promise((resolve, reject) => {
      throw new Error('出错了')
    })
    
    console.log('正常输出')
  } catch (err) {
    // 这里用来捕获异常
    console.log('异常了)
  }
}
代码语言:javascript
复制
async function Login () {
  // 接口请求异常, 
  // 用户名错误、密码错误、用户不存在、500
  // 前提条件: 接口把所有的异常都通过HTTp状态吗来返回
  // 尤其是在使用axios 请求库的时候, 它会把所有超出200- 300范围的状态码捕获
  try {
     catch (err) {

     }
  }
}

注意

  • try-catch 只能捕获同步异常
  • 还有async 中的await Promise异常
  • try-catch 不能直接捕获Promise 调用异常
代码语言:javascript
复制
try {
  const p = new Promise((resolve, reject) => {
    throw new Error('error')
    fs.readFile('./login.js', (err, data) => {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    })
  })
  // 这样可以捕获到
  // p.then(data => {
  //   console.log(data)
  // }).catch (err => {
  //   console.log('手动 调用catch 捕获异常')
  // })
} catch (err) {
  console.log('失败了')
}

// 没有错误
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.数据结构和算法
    • 1.1 反转单向链表
      • 1.2 在顺序表中插入和删除一个结点平均移动多少个结点?
        • 1.3 如何以递归和非递归方式实现二分查找
          • 1.4 求二叉树的深度
            • 1.5 如何在排序的数组中,找出给定数字出现的次数
              • 1.6 如何把字符串中的指定字符移动到字符串的前面
                • 1.7 排序算法总结
                  • 1.8 数组和链表的区别
                    • 1.9 什么排序元素比较次数和数组初始状态无关
                    • 2.面试题
                      • 2.1 百度一面
                        • 2.2 字节
                          • 2.3 小米
                            • 一面(技术面)
                            • 二面(技术面)
                            • 三面(技术面)
                            • 四面(技术面)
                            • 五面(技术加面)
                            • async / await 如果右边的方法执行出错了该怎么办 (百度一面2020)
                        相关产品与服务
                        消息队列 TDMQ
                        消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档