携程Java后端实习一面

携程的面试比较注重八股文和项目,算法相关没有字节腾讯严厉,大家参加携程的技术岗面试需要重视八股文和项目细节,要学会深挖项目,希望大家早日oc😊👍

HashMap底层原理,扩容机制,从并发问题引出ConcurrentHashMap,问如何上锁

HashMap底层原理

  • HashMap 基于数组和链表(在 JDK 1.8 之后引入了红黑树)实现。它通过哈希函数将键映射到数组的索引位置上。
  • 当发生哈希冲突时,会将相同索引位置的元素存储在一个链表中或转换为红黑树。

扩容机制

  • 当 HashMap 中的元素数量超过数组容量的负载因子(默认 0.75)时,会触发扩容操作,将容量加倍并重新分配所有元素到新的数组中。
  • 扩容时需要重新计算所有元素的哈希值,并重新插入到新的数组位置上。

并发问题与 ConcurrentHashMap

  • HashMap 在多线程环境中会出现数据不一致的问题,例如死循环、数据丢失等。
  • ConcurrentHashMap 通过分段锁机制进行并发控制,将整个 Map 分成多个 Segment,每个 Segment 独立加锁,减少锁竞争。
  • JDK 8 之后,ConcurrentHashMap 改用 CAS(Compare-And-Swap)和 Synchronized 结合的方式来提高并发性能。

线程通信的方式

  1. wait() 和 notify()/notifyAll():通过对象监视器进行通信,wait() 使线程等待,notify() 唤醒等待的线程。
  2. Condition:Java 5 引入的更灵活的线程通信机制,与 ReentrantLock 结合使用。
  3. 阻塞队列(BlockingQueue):生产者-消费者模式下常用,如 ArrayBlockingQueue、LinkedBlockingQueue。
  4. 信号量(Semaphore):控制同时访问特定资源的线程数量。
  5. 管道流(PipedInputStream 和 PipedOutputStream):用于线程间数据传输。

线程池参数以及线程池的好处

线程池参数

  1. corePoolSize:核心线程数,始终保持在线的线程数量。
  2. maximumPoolSize:最大线程数,线程池能容纳的最大线程数。
  3. keepAliveTime:空闲线程存活时间,当线程数超过核心线程数时,多余的空闲线程会在指定时间后终止。
  4. unit:keepAliveTime 的时间单位。
  5. workQueue:用于存放等待执行任务的队列。
  6. threadFactory:线程工厂,用于创建新线程。
  7. handler:拒绝策略,当任务队列已满且无法继续创建线程时,处理新任务的策略。

线程池的好处

  1. 重用线程:减少了频繁创建和销毁线程的开销。
  2. 控制最大并发数:通过配置最大线程数来控制并发数量,防止系统资源耗尽。
  3. 管理任务队列:有助于任务的排队和调度。
  4. 提高响应速度:线程池中的线程可以及时处理新任务,减少等待时间。

Mysql索引底层数据结构,用B+树的好处

Mysql索引底层数据结构

  • B+树 是 MySQL 索引的主要数据结构,适用于大多数存储引擎,如 InnoDB。
  • B+树是一种平衡树,所有叶子节点在同一层,并通过双向链表连接。

B+树的好处

  1. 有序性:有助于范围查询和排序操作。
  2. 磁盘读写效率高:B+树节点包含多个元素,一次磁盘读取可以获取更多数据,减少磁盘I/O次数。
  3. 查询效率高:通过树的平衡性保证查询的时间复杂度为 O(log n)。
  4. 适合范围查询:通过叶子节点的链表,可以高效地进行范围查询。

索引的类型

  1. 主键索引(Primary Key Index):唯一标识表中的每一行,不允许重复和空值。
  2. 唯一索引(Unique Index):保证列中的值唯一,但允许空值。
  3. 普通索引(Index):加速查询,没有唯一性限制。
  4. 全文索引(Full-text Index):用于全文搜索,如匹配关键字。
  5. 组合索引(Composite Index):在多个列上创建的索引,加速多条件查询。

如何优化查询语句

  1. 使用合适的索引:建立并使用索引,避免全表扫描。
  2. 选择合适的字段:只查询必要的字段,减少数据传输量。
  3. 避免使用 SELECT *:明确指定查询的列。
  4. 使用 WHERE 子句过滤数据:减少结果集的大小。
  5. 避免在 WHERE 子句中进行函数运算:可能导致索引失效。
  6. 使用 JOIN 代替子查询:提高查询效率。
  7. 适当使用 LIMIT:限制结果集大小,减少不必要的数据处理。
  8. 分析查询执行计划:使用 EXPLAIN 关键字查看查询的执行计划,找出瓶颈。

网络七层模型和四层模型的区别

网络七层模型(OSI模型)

  1. 物理层:传输原始比特流。
  2. 数据链路层:提供节点间的数据传输,进行帧的传输和纠错。
  3. 网络层:负责数据包的路由和转发。
  4. 传输层:提供端到端的通信,确保数据完整性和可靠传输。
  5. 会话层:管理会话,控制建立、维护和终止会话。
  6. 表示层:数据的表示、加密和解密、数据格式转换。
  7. 应用层:提供应用服务,如HTTP、FTP、SMTP等。

四层模型(TCP/IP模型)

  1. 网络接口层:对应OSI模型的物理层和数据链路层。
  2. 互联网层:对应OSI模型的网络层。
  3. 传输层:对应OSI模型的传输层。
  4. 应用层:对应OSI模型的会话层、表示层和应用层。

输入网址到网页显示,期间发生了什么

  1. DNS解析:将域名转换为IP地址。
  2. 建立TCP连接:通过三次握手与服务器建立TCP连接。
  3. 发送HTTP请求:客户端向服务器发送HTTP请求报文。
  4. 服务器处理请求:服务器处理请求并生成响应。
  5. 发送HTTP响应:服务器将响应报文返回给客户端。
  6. 浏览器渲染页面:浏览器解析HTML、CSS、JavaScript等文件,构建DOM树和渲染树,绘制页面。

网络传输如何保证可靠性和安全性

可靠性

  1. TCP协议:通过序列号、确认机制、重传机制和窗口控制实现可靠数据传输。
  2. 错误检测:使用校验和等方法检测并纠正传输错误。
  3. 拥塞控制:避免网络拥塞,提高传输效率。

安全性

  1. 加密:使用TLS/SSL协议加密数据,保护传输过程中的数据安全。
  2. 身份验证:验证通信双方的身份,防止伪装和中间人攻击。
  3. 数据完整性:使用消息摘要算法确保数据在传输过程中未被篡改。

手撕算法:最大连续子数组和(hot 100)

问题描述: 找到一个整数数组的一个连续子数组,使得该子数组的和最大,并返回这个最大和。

示例代码(Java)

public int maxSubArray(int[] nums) {
    int maxSoFar = nums[0];
    int maxEndingHere = nums[0];
    for (int i = 1; i < nums.length; i++) {
        maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]);
        maxSoFar = Math.max(maxSoFar, maxEndingHere);
    }
    return maxSoFar;
}

解释

  1. 初始化maxSoFarmaxEndingHere 都初始化为数组的第一个元素。
  2. 迭代:遍历数组,对于每个元素,更新 maxEndingHere 为当前元素和 maxEndingHere 之和的较大值。
  3. 更新最大值:每次都更新 maxSoFarmaxSoFarmaxEndingHere 中的较大值。
  4. 返回结果:返回 maxSoFar 即为最大子数组和。
### 携程 API Token 的获取与使用 携程 API 的 `Token` 是一种认证机制,用于验证请求的身份并保护接口的安全性。以下是关于如何获取和使用携程 API 中的 `Token` 的详细说明。 #### 1. 获取 AppId 和 Key 在使用任何第三方 API 前,通常需要先申请开发者账号,并获得相应的应用凭证。对于携程 API 来说,这包括两个重要参数: - **AppId**: 应用程序唯一标识符。 - **Key (Secret)**: 秘钥,用于签名计算。 这些信息可以通过注册成为携程开放平台开发者账户后,在控制台中找到[^1]。 #### 2. 计算 Sign 并换取 Token 为了安全起见,携程 API 使用了一种基于时间戳 (`timestamp`) 和密钥 (`key`) 的签名算法来生成 `Sign` 参数。具体流程如下: - 构造字符串:将当前的时间戳(单位为秒)与秘钥拼接成一个字符串形式的数据。 - 加密处理:利用 MD5 或其他指定加密方式对上述字符串进行哈希运算得出最终的结果作为 sign 值。 ```python import hashlib import time def generate_sign(app_key, timestamp): raw_data = f"{timestamp}{app_key}" md5_hasher = hashlib.md5() md5_hasher.update(raw_data.encode('utf-8')) return md5_hasher.hexdigest() current_time = int(time.time()) app_key = 'your_secret_key' sign_value = generate_sign(app_key, current_time) print(f"Generated SIGN Value: {sign_value}") ``` 随后可以携带 appId、timestamp 及刚刚生成好的 sign 向服务器发起请求交换实际可用的 access_token。 #### 3. 验证接口调用方式 如果尝试访问某些特定功能却失败,则可能是由于未按照规定的方式执行操作所致。例如部分端点仅支持 POST 请求而非 GET 方法;因此务必确认文档中标明的支持 HTTP 动词以及其它约束条件[^3]。 另外值得注意的是有些场景下可能还需要额外提供 authorization header 字段或者附加 query parameters 才能成功完成身份校验过程。 #### 4. 安全注意事项 尽管已经介绍了怎样正确地取得 token ,但仍需强调几点保障措施以防止敏感资料泄露风险发生: - 不要在前端暴露 private keys; - 对于长期有效的 tokens 要妥善保管好它们; - 如果发现异常活动立即撤销现有 credentials 并重新创建新的 ones. 以上便是有关于携程 api token 获取及其运用方面的指导内容总结。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓宜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值