【面经】2024秋美团后端开发岗(AI面)

一 Java的基本数据类型有哪些,大小以及范围是多少

        Java有八大数据类型,包括short、int、long、byte、float、double、boolean、char

byte:

  • byte 数据类型是8位、有符号的,以二进制补码表示的整数;
  • 最小值是 -128(-2^7);
  • 最大值是 127(2^7-1);
  • 默认值是 0;
  • byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
  • 例子:byte a = 100,byte b = -50。

short:

  • short 数据类型是 16 位、有符号的以二进制补码表示的整数
  • 最小值是 -32768(-2^15);
  • 最大值是 32767(2^15 - 1);
  • Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
  • 默认值是 0;
  • 例子:short s = 1000,short r = -20000。

int:

  • int 数据类型是32位、有符号的以二进制补码表示的整数;
  • 最小值是 -2,147,483,648(-2^31);
  • 最大值是 2,147,483,647(2^31 - 1);
  • 一般地整型变量默认为 int 类型;
  • 默认值是 0 ;
  • 例子:int a = 100000, int b = -200000。

long:

  • long 数据类型是 64 位、有符号的以二进制补码表示的整数;
  • 最小值是 -9,223,372,036,854,775,808(-2^63);
  • 最大值是 9,223,372,036,854,775,807(2^63 -1);
  • 这种类型主要使用在需要比较大整数的系统上;
  • 默认值是 0L;
  • 例子: long a = 100000L,long b = -200000L。
    "L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。

float:

  • float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
  • float 在储存大型浮点数组的时候可节省内存空间;
  • 默认值是 0.0f;
  • 浮点数不能用来表示精确的值,如货币;
  • 例子:float f1 = 234.5f。

double:

  • double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
  • 浮点数的默认类型为 double 类型;
  • double类型同样不能表示精确的值,如货币;
  • 默认值是 0.0d;
  • 例子:double d1 = 7D ;

boolean:

  • boolean数据类型表示一位的信息;
  • 只有两个取值:true 和 false;
  • 这种类型只作为一种标志来记录 true/false 情况;
  • 默认值是 false;
  • 例子:boolean one = true。

char:

  • char 类型是一个单一的 16 位 Unicode 字符;
  • 最小值是 \u0000(十进制等效值为 0);
  • 最大值是 \uffff(即为 65535);
  • char 数据类型可以储存任何字符;
  • 例子:char letter = 'A';。

二 如何简单设计一个用户评论回复通知系统

        设计一个用户评论回复通知系统通常涉及几个核心组件:数据存储(如数据库)、前端界面、后端逻辑处理以及通知机制。

1. 数据模型设计

        首先,需要设计数据库模型来存储用户、评论和回复的信息。假设有两个主要的数据表:

  • Users: 存储用户信息(如用户ID、用户名、邮箱等)。
  • Comments: 存储评论信息(如评论ID、内容、所属用户ID、关联帖子ID、创建时间等)。
  • Replies: 存储回复信息(如回复ID、内容、所属用户ID、关联评论ID、创建时间等)。

2. 后端服务设计

a. 评论与回复API

  • 添加评论API:用户向指定帖子添加评论。
  • 添加回复API:用户向指定评论添加回复。

b. 通知逻辑

  • 当一个回复被创建时,系统需要识别出这条回复是针对哪个评论的,并进一步识别出这条评论是由哪个用户创建的。
  • 系统需要有一个机制来追踪哪些用户需要被通知(在这个例子中,是评论的原始作者)。
  • 可以通过发送邮件、站内消息或其他通知方式来通知用户。

代码示例

// 假设ReplyService类处理回复的创建  
public class ReplyService {  
      
    // 添加回复的方法  
    public void addReply(Reply reply) {  
        // 保存回复到数据库  
        // ...  
          
        // 查找评论的原始作者  
        Comment comment = commentRepository.findById(reply.getCommentId());  
        User originalAuthor = userRepository.findById(comment.getUserId());  
          
        // 发送通知给原始作者  
        sendNotification(originalAuthor, "您收到了新的回复!");  
    }  
      
    // 发送通知的方法(这里以邮件为例)  
    private void sendNotification(User user, String message) {  
        // 使用邮件服务发送通知  
        // ...  
    }  
}

3. 通知机制

  • 邮件通知:使用JavaMail API或其他邮件服务库(如Spring Mail)来发送邮件通知。
  • 站内消息:在数据库中创建一个消息表,将通知作为站内消息发送给用户,并通过前端显示。
  • 实时通知(可选):使用WebSocket或其他实时通信技术来即时通知用户。

4. 安全性与隐私

  • 确保所有用户数据(包括通知内容)都经过适当的加密和安全处理。
  • 允许用户选择是否接收通知,并提供取消订阅的功能。

5. 前端集成

  • 在前端显示通知(如通过WebSocket实时更新,或通过轮询检查新的通知)。
  • 允许用户查看和管理他们的通知(如阅读、删除等)。

三 TCP的握手机制

        第一次握手:客户端请求建立连接,向服务端发送一个同步报文(SYN=1),同时选择一个随机数 seq = x 作为初始序列号,并进入SYN_SENT状态,等待服务器确认。

        第二次握手::服务端收到连接请求报文后,如果同意建立连接,则向客户端发送同步确认报文(SYN=1,ACK=1),确认号为 ack = x + 1,同时选择一个随机数 seq = y 作为初始序列号,此时服务器进入SYN_RECV状态。

        第三次握手:客户端收到服务端的确认后,向服务端发送一个确认报文(ACK=1),确认号为 ack = y + 1,序列号为 seq = x + 1,客户端和服务器进入ESTABLISHED状态,完成三次握手。

        理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

四  Java 中的接口是什么?接口和抽象类有何区别?

语法层面上的区别:

  • 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
  • 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

设计层面上的区别:

  • 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
  • 设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。

五 数据库的垂直分表和水平分表

        水平拆分的意思,就是把一个表的数据给弄到多个库的多个表里去,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。水平拆分的意义,就是将数据均匀放更多的库里,然后用多个库来抗更高的并发,还有就是用多个库的存储容量来进行扩容。

img

        垂直拆分的意思,就是把一个有很多字段的表给拆分成多个表或者是多个库上去。每个库表的结构都不一样,每个库表都包含部分字段。一般来说会将较少的访问频率很高的字段放到一个表里去,然后将较多的访问频率很低的字段放到另外一个表里去。因为数据库是有缓存的,你访问频率高的行字段越少,就可以在缓存里缓存更多的行,性能就越好。这个一般在表层面做的较多一些。

img

六 如何使用 top 命令监控系统性能?

        top命令(Table of Processes)是Linux中用来监视系统运行状态和查看系统中运行的进程的实时动态管理命令。它可以显示系统的总体信息,包括运行时间、负载、运行的进程数、CPU使用率、内存使用率等。基本语法为:

top [options]

        top命令的常用选项包括:

七 Linux系统中,如何查看CPU的系统信息

        使用 lscpu 命令获取 CPU 信息

八 java的序列化是什么,一般如何实现序列化

        序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。核心作用是对象状态的保存与重建。我们都知道Java对象是保存在JVM的堆内存中的,也就是说如果JVM堆不存在了,那么对象也就跟着消失了。

        而序列化提供了一种方案,可以让你在即使JVM停机的情况下也能把对象保存下来的方案。就像我们平时用的U盘一样。把Java对象序列化成可存储或传输的形式(如二进制流),比如保存在文件中。这样,当再次需要这个对象的时候,从文件中读取出二进制流,再从二进制流中反序列化出对象。

        实现序列化的方式包括实现Serializable接口和实现Externalizable接口。

九 解释一下 cookie 和 session 的区别。

  • 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。

  • 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。

  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。

  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。

  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

十 redis 持久化策略有哪些?有什么区别?

        为了能够重用Redis数据,或者防止系统故障,我们需要将Redis中的数据写入到磁盘空间中,即持久化。Redis提供了两种不同的持久化方法可以将数据存储在磁盘中,一种叫快照`RDB`,另一种叫只追加文件`AOF`。

RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘(`Snapshot`),它恢复时是将快照文件直接读到内存里。

优势:适合大规模的数据恢复;对数据完整性和一致性要求不高

劣势:在一定间隔时间做一次备份,所以如果Redis意外`down`掉的话,就会丢失最后一次快照后的所有修改。

AOF:以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。AOF采用文件追加方式,文件会越来越大,为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时, Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.。

优势:

- 每修改同步:`appendfsync always` 同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好
- 每秒同步:`appendfsync everysec` 异步操作,每秒记录,如果一秒内宕机,有数据丢失
- 不同步:`appendfsync no`   从不同步

劣势: 相同数据集的数据而言`aof`文件要远大于`rdb`文件,恢复速度慢于`rdb`;`aof`运行效率要慢于`rdb`,每秒同步策略效率较好,不同步效率和`rdb`相同

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值