【后端开发面试题】每日 3 题(五)

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:https://blog.csdn.net/newin2020/category_12903849.html

📚专栏简介:在这个专栏中,我将会分享后端开发面试中常见的面试题给大家~

❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

1. 如何优化一个高并发场景下的数据库读写性能?

数据库层面

  • 索引优化

    • 合理创建索引,对经常用于查询条件、排序和连接的字段添加索引,如在用户表的 username 字段上添加索引,可加快按用户名查询的速度。
    • 避免过多索引,因为索引会增加写操作的开销,且占用额外的磁盘空间。定期分析查询语句,删除不必要的索引。
    • 使用复合索引,当多个字段经常一起用于查询条件时,创建复合索引可以提高查询效率。例如,对于经常同时根据 user_id 和 create_time 查询订单的场景,创建 (user_id, create_time) 复合索引。
  • 数据库架构优化

    • 读写分离:采用主从复制架构,主库负责写操作,从库负责读操作。这样可以将读压力分散到多个从库上,提高系统的读性能。例如,在电商系统中,商品信息的查询可以从从库获取,而订单的创建则在主库进行。
    • 分库分表:当数据量非常大时,将数据分散存储在多个数据库或表中。水平分表按照数据的行进行划分,如按时间将订单表拆分为多个表;垂直分表按照数据的列进行划分,将不常用的字段拆分到另一个表中。
  • 数据库参数调整

    • 根据服务器的硬件资源和业务特点,调整数据库的配置参数。例如,调整 innodb_buffer_pool_size 以提高 MySQL 的缓存效率,确保常用数据能在内存中快速访问。
      应用层面
  • 缓存机制

    • 使用内存缓存(如 Redis)来减轻数据库的读压力。将经常访问的数据(如热门商品信息、用户信息等)存储在缓存中,应用程序优先从缓存中获取数据,只有在缓存中不存在时才去查询数据库,并将查询结果更新到缓存中。
    • 缓存更新策略:采用合适的缓存更新策略,如缓存失效、缓存更新和缓存删除等。例如,当数据发生更新时,及时更新缓存中的数据,以保证数据的一致性。
  • 异步处理

    • 将一些非关键的数据库操作(如日志记录、统计信息更新等)进行异步处理。可以使用消息队列(如 Kafka、RabbitMQ)将这些操作发送到队列中,由专门的消费者进行处理,避免阻塞主业务流程。
  • 限流和熔断

    • 实现限流机制,限制对数据库的并发访问量,防止过多的请求压垮数据库。可以使用令牌桶算法或漏桶算法来实现限流。
    • 引入熔断机制,当数据库出现故障或响应时间过长时,自动熔断对数据库的访问,返回默认数据或错误信息,避免系统雪崩。

2. 简述 Go 语言中 goroutine 和线程的区别

内存占用

  • 线程:操作系统线程的栈空间通常较大,一般为几兆字节。这是因为线程需要保存大量的上下文信息,以支持复杂的系统调用和切换操作。较大的栈空间会占用较多的系统内存资源,当创建大量线程时,容易导致内存耗尽。

  • goroutine:Go 语言中的 goroutine 栈空间初始时非常小,通常只有几 KB,并且可以根据需要动态增长和收缩。这使得在 Go 程序中可以轻松创建大量的 goroutine,而不会像线程那样消耗过多的内存。

    调度开销

  • 线程:线程的调度由操作系统内核负责,涉及用户态和内核态的切换,这种切换开销较大,因为需要保存和恢复大量的上下文信息。此外,操作系统线程的调度是全局的,会影响整个系统的性能。

  • goroutine:goroutine 的调度由 Go 运行时(runtime)负责,在用户态进行调度,避免了频繁的内核态切换,调度开销较小。Go 运行时采用了 M:N 调度模型,将 M 个 goroutine 映射到 N 个操作系统线程上,提高了并发性能。

    创建和销毁开销

  • 线程:创建和销毁操作系统线程的开销较大,因为涉及到内核资源的分配和释放。例如,创建一个新线程需要分配栈空间、内核数据结构等,销毁线程时需要回收这些资源。

  • goroutine:goroutine 的创建和销毁开销非常小,Go 运行时可以快速地创建和销毁 goroutine,使得程序可以高效地处理大量的并发任务。

    并发性能

  • 线程:由于线程的调度开销和内存占用问题,在处理大量并发任务时,线程的性能会受到限制。过多的线程会导致上下文切换频繁,增加系统的负载,降低并发性能。

  • goroutine:goroutine 由于其轻量级的特点,可以轻松创建大量的并发任务,并且调度开销小,因此在高并发场景下表现出色。Go 语言的并发模型使得开发者可以更方便地编写高效的并发程序。

3. 在 Node.js 中,如何处理异步操作中的错误?

回调函数方式

在传统的异步操作中,通常使用回调函数来处理结果和错误。回调函数的第一个参数通常用于传递错误信息,如果没有错误则为 null。

javascript 复制代码
const fs = require('fs');

fs.readFile('nonexistentfile.txt', 'utf8', (err, data) => {
    if (err) {
        console.error('读取文件时出错:', err);
        return;
    }
    console.log('文件内容:', data);
});

Promise 方式

使用 Promise 可以更好地管理异步操作和错误处理。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。可以使用 .then() 方法处理成功的结果,使用 .catch() 方法处理错误。

javascript 复制代码
const fs = require('fs').promises;

fs.readFile('nonexistentfile.txt', 'utf8')
  .then(data => {
        console.log('文件内容:', data);
    })
  .catch(err => {
        console.error('读取文件时出错:', err);
    });

async/await 方式

async/await 是基于 Promise 的语法糖,使异步代码看起来更像同步代码。可以使用 try...catch 块来捕获和处理异步操作中的错误。

javascript 复制代码
const fs = require('fs').promises;

async function readFileAsync() {
    try {
        const data = await fs.readFile('nonexistentfile.txt', 'utf8');
        console.log('文件内容:', data);
    } catch (err) {
        console.error('读取文件时出错:', err);
    }
}

readFileAsync();

全局错误处理

在 Node.js 中,可以使用 process.on('uncaughtException') 来捕获未被处理的同步错误,使用 process.on('unhandledRejection') 来捕获未被处理的 Promise 拒绝。

javascript 复制代码
process.on('uncaughtException', (err) => {
    console.error('未处理的同步错误:', err);
    // 可以进行一些清理操作,然后退出进程
    process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的 Promise 拒绝:', reason);
});
相关推荐
Neil__Hu4 分钟前
Go的基本语法学习与练习
java·c语言·c++·python·qt·学习·golang
彬sir哥10 分钟前
水仙花数(华为OD)
java·c语言·javascript·c++·python·算法
爱上妖精的尾巴25 分钟前
3-7 WPS JS宏 工作表移动复制实例-2(多工作簿的多工作表合并)学习笔记
javascript·笔记·学习·wps·js宏·jsa
不会飞的小龙人34 分钟前
Docker安装Postgres_16数据库
数据库·docker·postgresql·容器·portainer
zerolbsony1 小时前
tidb vs starrocks 资源估算pk
数据库·tidb·数据库开发
2302_799525742 小时前
【go语言】——方法集
开发语言·后端·golang
海盐泡泡龟2 小时前
表格管理---React
前端·javascript·react.js
_GR2 小时前
Redis存储⑮Redis的应用_分布式锁_Lua脚本/Redlock算法
数据库·redis·分布式·缓存
葡萄_成熟时_2 小时前
JavaWeb后端基础(4)
java·开发语言·数据库·maven·web
风无雨2 小时前
React的TSX中如何同时使用CSS模块的类名和字符串类名
javascript·css·react.js