2024.11.03 周日
上午练车,中午午睡,下午两点开始学习(晚上休息会儿)。
八股
HTTP是什么?
- HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。
- HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
HTTP常见的状态码有哪些?
-
「200 OK」
是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。 -
「204 No Content」
也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。 -
「206 Partial Content」
是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态 -
「301 Moved Permanently」
表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。 -
「302 Found」
表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。 -
「304 Not Modified」
不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。 -
「400 Bad Request」
表示客户端请求的报文有错误,但只是个笼统的错误。 -
「403 Forbidden」
表示服务器禁止访问资源,并不是客户端的请求出错。 -
「404 Not Found」
表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。 -
「500 Internal Server Error」
与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。 -
「501 Not Implemented」
表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。 -
「502 Bad Gateway」
通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。 -
「503 Service Unavailable」
表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
HTTP常见字段有哪些?
-
Host: www.A.com
-
Content-Length: 1000
- HTTP 协议通过设置回车符、换行符作为 HTTP header 的边界,通过 Content-Length 字段作为 HTTP body 的边界,这两个方式都是为了解决“粘包”的问题。
-
Connection: Keep-Alive
- 开启了 HTTP Keep-Alive 机制后, 连接就不会中断,而是保持连接。当客户端发送另一个请求时,它会使用同一个连接,一直持续到客户端或服务器端提出断开连接。
-
Content-Type: text/html; Charset=utf-8
- 客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式——>
Accept: */*
- 客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式——>
-
Content-Encoding: gzip
- 服务器返回的数据采用了 gzip 方式压缩,告知客户端需要用此方式解压。
-
Accept-Encoding: gzip, deflate
- 客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法。
GET和POST方法都是安全和幂等的吗?
- 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
- 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。
如果「安全」放入概念是指信息是否会被泄漏的话,虽然 POST 用 body 传输数据,而 GET 用 URL 传输,这样数据会在浏览器地址拦容易看到,但是并不能说 GET 不如 POST 安全的。
因为 HTTP 传输的内容都是明文的,虽然在浏览器地址拦看不到 POST 提交的 body 数据,但是只要抓个包就都能看到了。
所以,要避免传输过程中数据被窃取,就要使用 HTTPS 协议,这样所有 HTTP 的数据都会被加密传输。
HTTP缓存有哪些实现方式?
-
强制缓存 [
Status Code:200 (from disk cache)
]- 强缓存通过两个HTTP响应头部实现:
Cache-Control
和Expires
,建议使用Cache-Control
实现强缓存。 Cache-Control
实现流程:- 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小
- 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器
- 服务器再次收到请求后,会再次更新 Response 头部的
Cache-Control
- 强缓存通过两个HTTP响应头部实现:
-
协商缓存 [
Status Code:304
][告诉浏览器可以使用本地缓存的资源]- 协商缓存可以基于两种头部来实现。
- 第一种:
If-Modified-Since
和Last-Modified
- 基于时间实现的,服务器收到请求后,对比两个字段的时间。
- 第二种:
If-None-Match
和ETag
- 基于唯一标识实现的
- 资源过期时,浏览器发现响应头中有Etag,再次向服务器发起请求时,会将请求头
If-None-Match
值设置为Etag
的值。 - 服务器收到请求后进行比对,如果资源没有变化返回
304
,如果资源变化了返回200
。
算法
200.岛屿数量(bfs解法)
46.全排列(回溯算法)
198.打家劫舍(动态规划-类似爬楼梯的递归)
215.数组中的第k个最大元素(Arrays.sort()
)
215.数组中的第k个最大元素(补充:快速排序)
Arrays.sort()
适用范围:数组对象(eg: int[ ];float[ ];char[ ];double[ ])
回溯算法
回溯属于纯暴力搜索算法,问题类型:组合问题(无顺序)、切割问题(字符串切割)、子集问题(类似组合问题)、排列问题(有顺序)、棋盘问题(N皇后)
// 46.全排列问题回溯解法(排列问题)
class Solution {
public List<List<Integer>> permute(int[] nums) {
//回溯算法
List<List<Integer>> res = new ArrayList<List<Integer>>();
// 将原int[]中的值填入ArrayList中
List<Integer> output = new ArrayList<Integer>();
for (int num : nums){
output.add(num);
}
int n = nums.length;
backtrack(n, output, res, 0);
return res;
}
public void backtrack(int n, List<Integer> output, List<List<Integer>> res, int first){
// 所有数都填完了
if (first == n){
res.add(new ArrayList<Integer>(output));
}
// 指针first是左侧维护的数组中下一个待填的数,指针i代表右侧未维护数组中填入first的不同可能性
for (int i = first; i < n; ++i){
// 动态维护数组
Collections.swap(output, first, i);
// 继续递归填下一个数
backtrack(n, output, res, first + 1);
// 撤销操作
Collections.swap(output, first, i);
}
}
}
快速排序(标准算法模板)
具体步骤
- 1,创建两个指针分别指向数组的最左端以及最右端
- 2,在数组中任意取出一个元素作为基准
- 3,左指针开始向右移动,遇到比基准大的停止
- 4,右指针开始向左移动,遇到比基准小的元素停止,交换左右指针所指向的元素
- 5,重复3,4,直到左指针超过右指针,此时,比基准小的值就都会放在基准的左边,比基准大的值会出现在基准的右边
- 6,然后分别对基准的左右两边重复以上的操作,直到数组完全排序
// 标准快排算法
public class QuickSort {
// 快速排序算法
public void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
// 递归排序左半部分
quickSort(arr, low, pi - 1);
// 递归排序右半部分
quickSort(arr, pi + 1, high);
}
}
// 划分函数,用于找到基准元素的正确位置
int partition(int[] arr, int low, int high) {
int pivot = arr[high]; // 选择最后一个元素作为基准
int i = low - 1; // 初始化较小元素的索引
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
// 交换元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 将基准元素放到正确的位置
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1; // 返回基准元素的位置
}
public static void main(String[] args) {
int[] arr = {10, 7, 8, 9, 1, 5};
QuickSort quickSort = new QuickSort();
quickSort.quickSort(arr, 0, arr.length - 1);
System.out.println("Sorted array:");
for (int value : arr) {
System.out.print(value + " ");
}
}
}
项目
苍穹外卖
软件开发流程
- 需求分析
- 完成需求规格说明书、产品原型编写。
- 需求规格说明书, 一般来说就是使用 Word 文档来描述当前项目的各个组成部分,如:系统定义、应用环境、功能规格、性能需求等,都会在文档中描述。
- 产品原型,一般是通过网页(html)的形式展示当前的页面展示什么样的数据, 页面的布局是什么样子的,点击某个菜单,打开什么页面,点击某个按钮,出现什么效果,都可以通过产品原型看到。
- 设计
- UI设计
- 数据库设计
- 接口设计
- 编码
- 编写项目代码、并完成单元测试。
- 测试
- 在该阶段中主要由测试人员, 对部署在测试环境的项目进行功能测试, 并出具测试报告。
- 上线运维
- 在项目上线之前, 会由运维人员准备服务器上的软件环境安装、配置, 配置完毕后, 再将我们开发好的项目,部署在服务器上运行。
技术选型
- 用户层
- 本项目中在构建系统管理后台的前端页面,我们会用到H5、Vue.js、ElementUI、apache echarts(展示图表)等技术。而在构建移动端应用时,我们会使用到微信小程序。
- 网关层
- Nginx是一个服务器,主要用来作为Http服务器,部署静态资源,访问性能高。在Nginx中还有两个比较重要的作用: 反向代理和负载均衡, 在进行项目部署时,要实现Tomcat的负载均衡,就可以通过Nginx来实现。
- 应用层
- SpringBoot: 快速构建Spring项目, 采用 “约定优于配置” 的思想, 简化Spring项目的配置开发。
- SpringMVC:SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合,可以无缝集成。
- Spring Task: 由Spring提供的定时任务框架。
- httpclient: 主要实现了对http请求的发送。
- Spring Cache: 由Spring提供的数据缓存框架
- JWT: 用于对应用程序上的用户进行身份验证的标记。
- 阿里云OSS: 对象存储服务,在项目中主要存储文件,如图片等。
- Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。
- POI: 封装了对Excel表格的常用操作。
- WebSocket: 一种通信网络协议,使客户端和服务器之间的数据交换更加简单,用于项目的来单、催单功能实现。
- 数据层
- MySQL: 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。
- Redis: 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存。
- Mybatis: 本项目持久层将会使用Mybatis开发。
- pagehelper: 分页插件。
- spring data redis: 简化java代码操作Redis的API。
- 工具
- git: 版本控制工具, 在团队协作中, 使用该工具对项目中的代码进行管理。
- maven: 项目构建工具。
- junit:单元测试工具,开发人员功能实现完毕后,需要通过junit对功能进行单元测试。
- postman: 接口测工具,模拟用户发起的各类HTTP请求,获取对应的响应结果。