自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(42)
  • 收藏
  • 关注

原创 详细说说从浏览器输入 URL 到显示页面的过程

浏览器解析 URL,确定服务器域名和资源,生成 HTTP 请求信息。通过 DNS 查找服务器域名对应的 IP 地址。DNS 域名用句点分隔,越靠右层级越高。层级关系类似一个树,从上到下分别为根域名服务器、顶级域名服务器(com)、权威域名服务器(server.com)。​解析域名时,客户端先发送一个 DNS 请求给本地域名服务器,查找服务器域名对应的 IP 地址。如果本地找不到,则向上访问根域名服务器,再向下依次访问顶级域名服务器、权威域名服务器,从而找到目标 IP,返回给客户端。..

2021-05-20 09:08:08 253

原创 面试不会虚拟内存、分段分页?这篇内存管理值得你看!

内存管理虚拟内存why、what、how为什么需要虚拟内存?早期计算机在运行时,直接把整个程序加载入内存。这会产生一些问题:如果程序很大或很多时,内存很快会被耗尽。进程间不独立,一个进程可能修改另一个进程数据,导致出错。虚拟内存是什么?于是就有了虚拟内存,它是一种内存管理技术,能为每个进程提供一个独有的、连续的虚拟地址空间。并通过内存交换技术,把不常用的内存换出到硬盘,需要时再换入内存,从而让有限的内存能运行更大的程序。虚拟内存怎么用?当有进程被创建时,操作系统会为其分.

2021-05-05 11:40:36 353

原创 105. 从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树先找根节点,即前序遍历的第一个元素。再找根节点在中序遍历中的索引,将前序、中序遍历划分为两半,来递归构造左右子树。class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, 0, preorder.length - 1, inorder, 0, i

2021-06-22 17:56:04 95

原创 Leetcode 297.二叉树的序列化与反序列化

297. 二叉树的序列化与反序列化序列化时,若当前节点为空,则加入 # 号并返回。否则,加入当前节点值,再递归左右子树。反序列化时,先将字符串转换为列表,再确定根节点,即列表首个元素,再递归生成左右子树。public class Solution { StringBuilder sb = new StringBuilder(); String Serialize(TreeNode root) { serialize(root);

2021-06-22 17:45:11 90

原创 Leetcode 239.滑动窗口的最大值

滑动窗口的最大值先使用双向链表构建一个单调递减队列,有三个方法:push 在队尾添加元素,但要将前面比它小的元素删除。 max 返回最大元素,即队头pop 若元素为队头,则删除(判断是因为有可能被压扁了,已经不存在了)然后,遍历数组,先把队列前 k - 1 个填满,再开始向前滑动移入新元素,再记录最大值,再移出旧元素。public class Solution { class MonotonicQueue { // 双链表,支持头部和尾部增删元素

2021-06-22 17:30:06 105

原创 JDK 8 ArrayList 的扩容机制

调用 add 方法时,public boolean add(E e) { // 先获取最小扩容量 ensureCapacityInternal(size + 1); // 为数组赋值,完成添加。 elementData[size++] = e; return true;}先获取最小扩容量,若数组为空,则为默认容量 10,否则为 size + 1,size 指当前存储的元素个数。private void ensureCapacityInternal(int

2021-06-17 16:46:25 220

原创 Redis 之缓存穿透、雪崩、击穿

目录缓存穿透缓存雪崩缓存击穿缓存穿透缓存穿透:指用户不断请求缓存和数据库中都不存在的数据,导致请求不经过缓存,直接落到数据库上。解决办法有:增加参数校验,或者拉黑访问过于频繁的 ip。缓存无效的 key,并设置过期时间,适用于 key 变化不频繁的情况。使用布隆过滤器,将所有存在的数据哈希到 Redis 的 bitmap 中。加入时,通过多个 hash 确定多个数组下标,将值置为 1。 然后判断时,以同样的方式 hash 确定下标,若值都为 1,则说明存在,否则说明不存在。但数组大小有限,不

2021-06-08 21:56:32 48

原创 HTTP 报文格式

HTTP 有两类报文:请求报文和响应报文。请求报文请求报文由请求行、请求头、请求体组成:请求行由请求方法、URL 和 HTTP 版本组成。常见的请求方法有 get 和 post。它们区别在于:GET 的参数写在 URL 中,而 POST 的参数写在报文 body 中。GET 是从服务器获取资源,而 POST 是向指定的资源提交数据。GET 是只读操作,不会破环服务器的资源,且多次重复操作的结果都相同,所以 GET 是安全且幂等的。而 POST 是提交操作,会破环服务器资源,且多次重复操作的结

2021-05-30 13:29:55 91

原创 一次搞定 IO 多路复用!

发展最基础的 TCP Socket 编程是阻塞的 IO 模型,只能一对一通信,为了服务更多的客户端,需要进行改进。传统的方式是使用多进程模型,每来一个客户端连接,就分配一个进程,但当连接量很大,性能会很低。于是就有了 IO 多路复用,可以在一个进程中处理多个连接,实现方式有 select、poll、epoll。select、pollselect、poll 没有本质的区别,都是使用线性结构存储进程关注的 Socket 集合。只不过,select 使用的线性结构是 BitsMap,有大小限制。而 p

2021-05-22 17:55:29 107

原创 AtomicInteger 底层实现原理

AtomicIntger 是对 int 型的封装,底层基于 CAS 提供原子性的操作,并用 volatile 修饰属性 value,保证可见性。private volatile int value;CAS 指比较并写回,是一种轻量级锁。底层通过操作系统原语实现,保证了原子性。在 CAS 中,线程读取数据不用加锁,在准备写回时,比较原值是否修改,若未被修改则写回,若已被修改,则重新执行读取流程,这是一种乐观策略,认为并发冲突并不总会发生。它适用于少量线程竞争的场景,但会存在几个问题:ABA:比如

2021-05-22 12:01:59 407

原创 简述 synchronized 底层原理及锁升级

底层原理讲一下 synchronized 关键字的底层原理?synchronized 是最常用一种的线程同步方式,可以锁对象、代码块以及方法,底层原理和 JVM 有关。对象在内存中分为三块区域:对象头、实例数据和对齐填充,对象头中保存了指向 Monitor 地址。Monitor 中有 Owner 和 计数器,Owner 指向持有 Monitor 的线程,计数器从 0 开始记录进入数。另外还有两个队列:EntryList、WaitSet,用来存放进入及等待获取锁的线程。进入 synchron

2021-05-20 08:41:16 256

原创 看招,Java 基础十连击!

面向对象面向对象是一种编程思想,从业务中抽象出一个个类,类中包含属性和方法,相比直接实现函数功能的面向过程,更容易维护和扩展,有封装、继承、多态三大特性:封装:将对象的属性私有化,对外只提供接口访问,从而隐藏内部实现,提高程序安全性。继承:从已有类得到继承信息创建新类的过程,实现了代码的复用。子类拥有父类所有属性和方法,但无法访问访问父类私有属性和方法。子类可以拥有自己的属性和方法。子类可以重写父类方法。多态:分为编译时多态(重载)和运行时多态(重写)重载:指同一个类中同名的方法有不同

2021-05-10 09:54:23 67

原创 【社区登录】8 检查登录状态

文章目录自定义注解拦截注解自定义注解// 自定义注解 LoginRequired,声明「只有登录才能访问」// @Target 声明自定义注解作用位置,ElementType.METHOD 作用方法上// @Retention 声明自定义注解有效时间,RetentionPolicy.RUNTIME 程序运行时有效@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface LoginRequire

2020-10-24 17:32:35 87

原创 【社区登录】7 账号设置

上传头像# 配置上传路径(要把文件夹建好,否则会报错)community.path.upload=c:/code/data/upload// 上传头像,通过 SpringMVC 提供的 MultipartFile 处理上传文件@RequestMapping(path = "/upload", method = RequestMethod.POST)public String uploadHeader(MultipartFile headerImage, Model model) { //

2020-10-24 17:31:00 182

原创 【社区登录】6 显示登录信息

每次请求(登录、注册等)都要重复这个流程(页面上都要显示登录信息),所以要用拦截器实现,不用在 Controller 的每个方法里都实现一遍。定义工具类// 获得浏览器传来的 cookie 值public class CookieUtil { public String getValue(HttpServletRequest request, String name) { if (request == null || name == null) t.

2020-10-23 09:54:38 139

原创 【社区登录】5 开发登录

1 访问登录页面2 登录登录凭证,不放 session,存入 login_ticket 表(id、user_id、ticket、status、expired),使用时再存入cookieUserService.login:生成登录凭证 loginTicket,将 ticket 放入 map 中LoginController@RequestMapping(path = "/login", method = RequestMethod.POST)// SpringMVC 将实体类自动注入

2020-10-21 11:49:59 195

原创 【社区登录】4 生成验证码

Kaptcha导入 jar 包<dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version></dependency>配置@Configurationpublic class KaptchaConfig {

2020-10-20 10:50:10 215

原创 【社区登录】3 会话管理

HTTP 是无状态的:同一连接中的请求没有关系,导致没办法在同一网站连续交互,比如用户加一个商品,切一个页面再加一个商品,最后浏览器不知道用户加了哪些商品。Cookie:服务器发送到浏览器并保持在本地的一小块数据,并会在下次请求中被浏览器发送给服务器,用来创建有状态的会话,如保持用户的登陆状态。Session:JavaEE 标准,用于在服务端记录客户端信息;数据存放在服务端更加安全,但也会增加服务端的内存压力。分布式下,请求经 nginx 分配给服务器1,并返回 cookie(sessionId1)

2020-10-20 10:49:22 117 1

原创 【社区登录】2 开发注册

文章目录访问注册页面提交注册数据激活注册账号访问注册页面@Controllerpublic class LoginController { // 访问注册页面 @RequestMapping(path = "/register", method = RequestMethod.GET) public String getRegisterPage() { return "/site/register"; }}<!-- index 头部 --&g

2020-10-19 21:59:39 141

原创 【社区登录】1 发送邮件

1 邮箱设置:开启 SMTP 服务;2 Spring Email:导入 jar<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>2.3.4.RELEASE</version></dependency&g

2020-10-19 21:58:15 652

原创 【Java集合】4 HashMap

文章目录简单介绍实现原理hashputgetresize长度为 2 的整数次方1.8 的优化和 Hashtable 的区别线程安全性节点无序简单介绍Q:简单介绍一下 HashMap?概述+原理+属性+方法:概述HashMap 与 Hashtable 类似,基于哈希表实现,但支持 null 键和值,并且不是线程安全的,性能更好;散列正常时,能提供常数时间的 put / get 操作,但不保证有序;如果需要满足线程安全,可以用 Collections.synchronizedMap(),或者直接用

2020-10-19 08:38:21 73 1

原创 【Java集合】3 HashSet

文章目录实现原理元素不重复实现原理Q:HashSet 的实现原理?HashSet 基于 HashMap 实现,底层创建了一个 Dummy 对象 “PRESENT” 作为 value,所有元素以键的形式放入 HashMap 中,即 HashSet 是以哈希算法来存储元素,所以散列正常时,能提供常数时间的 add、remove 和 contain 操作,但不保证有序。元素不重复Q:HashSet 怎么保证元素不重复的?HashSet 基于 HashMap 实现,底层创建了一个 Dummy 对象 “P

2020-10-19 08:37:56 43

原创 【Java基础】1 基本特性

文章目录1 面向对象的三大特性2 重载和重写的区别3 抽象类和接口的区别1 面向对象的三大特性面向对象是一种 “万物皆对象” 的编程思想,从业务中抽象出一个个类,类中包含属性和方法,相比直接实现函数功能的面向过程,更容易维护和扩展,有封装、继承、多态三大特性。封装:将对象的属性私有化,对外只提供接口访问,从而隐藏内部实现,提高程序安全性。继承:从已有类得到继承信息创建新类的过程,实现了代码的复用。子类拥有父类所有属性和方法,但无法访问访问父类私有属性和方法;子类可以拥有自己的属性和方法;子类

2020-10-19 08:37:12 45

原创 【Java集合】2 ArrayList

文章目录VectorLinkedListVectorQ:ArrayList 和 Vector 的区别?都是基于动态数组实现,支持随机访问,查询快,增删慢,因为要移动后续所有的元素,但 Vector 是线程安全的,ArrayList 不是线程安全的,性能更好;底层使用对象数组保存数据,当数组满时,会自动扩容,创建新的数组,并拷贝原有数组数据,扩容后 ArrayList 容量增加 50%,Vector 增加一倍。LinkedListQ:ArrayList 和 LinkedList 的区别?都

2020-10-18 21:56:05 311 3

原创 【Java集合】1 集合概述

Q:Java 中常用的集合有哪些?Java 集合分为 Collection 和 MapCollectionColletion 包括 List、Set、QueueList:有序集合,允许有重复元素,主要实现类有Vector:线程安全的动态数组ArrayList:与 Vector 类似,基于动态数组实现,支持随机访问,查询快,增删慢,因为要移动后续所有的元素,但它不是线程安全的,性能更好;底层都是使用对象数组保存数据,当数组满时,会自动扩容,创建新的数组,并拷贝原有数组数据,扩容后容量 Arra

2020-10-18 21:54:44 263 4

原创 【Java基础】8 泛型

Java 泛型是通过「类型擦除」实现的伪泛型;类型擦除:指泛型信息只存在编译阶段,之后便会被擦除,所以运行期找不到任何与类型相关的信息;这样做的目的是,为了兼容 Java 5 之前的二进制类库。使用伪泛型的好处在于,实现简单;能提供编译时的类型安全,比如能确保将正确类型的对象放入集合中,避免在运行时出现 ClassCastException;运行期能节省一些类型所占的内存空间;缺点:远不如真泛型灵活和强大。Q:int 可以作为泛型类型吗?基本数据类型不能做泛型类型,可以使用对应的包装

2020-10-18 21:51:25 108

原创 【Java基础】7 动态代理

动态代理是代理模式的一种,代理模式指通过代理静默地解决一些业务无关的问题,比如远程、安全、事务、日志、资源关闭等,让开发者可以只关心业务。分为静态、动态代理:静态代理:事先写好代理类实现简单,且不侵入原码缺点是每个业务类都需要写一个,非常不灵活,而且有冗余问题// 静态代理,给 UserService 添加日志处理public class UserServiceProxy implements UserService { // 被代理对象 private UserServi

2020-10-18 21:50:45 63

原创 【Java基础】6 反射机制

Q1:什么是反射?反射:指在运行时,能取得任意类的内部信息,调用任意对象的属性及方法,的一种机制。Q2:反射如何实现?它借助于 Reflection API 实现,主要涉及四个类:Field:提供类的属性信息;getFields() 、getDeclaredFields(),获取类公有或所有声明的字段;set() 设置属性值;Method:提供类的方法信息;getMethods() 、getDeclaredMethods(),获取类公有或所有声明的非构造的方法;之后使.

2020-10-18 21:50:20 52

原创 【Java基础】5 异常体系

文章目录Exception、Errorthrow、throwsException、ErrorException 和 Error 都是 Throwable 的子类,区别在于:Exception 表示程序可以处理的异常,可以捕获且可能恢复,分为受检查异常和运行时异常:受检查异常:必须显式地进行捕获处理,否则编译不通过,如 IOException 等;运行时异常:通常是可以编码避免的逻辑错误,编译能通过,但是一运行就终止,如 NullPointerException、ClassCastExcepti

2020-10-18 21:48:21 35

原创 【Java基础】4 equals()

文章目录==hashCode()==Q:== 和 equals 的区别?==:运算符对于基本数据类型,比较数值是否相等;对于引用类型,比较对象内存地址是否相同。equals():Object 类的方法,用于比较两个对象是否相等,不能比较基本数据类型。默认实现是,用 == 比较对象的内存地址;一般会重写,转换成值的比较。Q:null 哪个能用?都能用,但在 equals 只能做参数Q:不重写equals方法,那么a==b和a.equals(b)一样吗?一样,equals 默认

2020-10-18 21:47:01 149

原创 【Java基础】3 final

Q:final、finally、finalize 的区别?final修饰类,表示被不可继承;修饰方法,表示不可被重写;从而保护类的基础功能不被篡改。修饰变量:对于基础类型,使其数值不变,可用于保护只读数据,减少额外的同步开销;对于引用类型,使其引用不变,但对象本身不受影响;比如,修饰一个 list 对象,它的引用不能被修改,但可以正常增删元素,要 list 真正不可变,要用 Java 9 后提供的 list.of() 。List<String> list = List.of(

2020-10-18 21:45:11 53

原创 【Java基础】2 基础类

基础类StringObjectStringQ:String、StringBuilder、StringBuffer 的区别?String:底层用被 final 修饰的 char 数组保存数据,所以它是不可变的,也是线程安全的;Java 9 后改用 byte 数组和一个标识编码的属性 coder,因为发现实际存储拉丁字符居多,改用 byte 可以节省内存,提高操作速度;由于 String 的不可变,所以每次对它的改变,都要产生新的 String 对象,这会影响系统的性能,所以只适合操作少量数据。

2020-10-18 21:43:51 92 1

原创 版本控制

官网下载(百度网盘有备份)打开 git cmd,配置用户名、邮箱创建密钥,及其存放地址配置密钥至远程仓库(如 GitHub)配置 IDEA配置 git.exe创建本地仓库选择目录提交至本地仓库远程仓库新建项目,并取得项目地址.git,push...

2020-10-18 16:52:14 79

原创 调试技巧

响应状态码200:请求成功302:重定向重定向过程,浏览器发出两次请求:进行删除,返回 302,以及重定向目标;访问该目标,完成重定向。这样做的目的:降低耦合,并实现功能跳转。404:请求失败,访问资源不在服务器上500:服务器遇到不知道如何处理的情况服务端断点调试标记断点,DEBUG 执行程序F5:进入方法内F6:下一步F7:调至下一断点客户端断点调试浏览器 F12 开发者模式,sources 下找 jsF10:下一步F11:进入方法内F8:执行到底设置日志

2020-10-17 10:37:45 104

原创 项目首页

分两步:开发首页,显示前十帖子;开发分页,分页显示所有。开发首页开发顺序:DAO -> Service -> ControllerDAO(建表、实体类、Mapper 接口、Mapper 映射文件)建表:讨论贴content:帖子内容,不知道最大长度,故用 text 类型。char:长度固定,适用身份证、手机号码等定长属性;varchar:可变长度,可设置最大长度,适用长度可变的属性;text:不设置长度,适用不知道属性最大长度时;查询速度:char > v

2020-10-11 08:50:46 398 2

原创 MyBatis 入门

安装数据库MySQL 8.0.21MySQL 8.0.19安装教程(windows 64位) MySQL Workbench 8.0.21下载安装:选择好安装路径,一路 next 就好。使用:核心组件SqlSessionFactory:用于创建 SqlSession 的工厂类;SqlSession:用于向数据库执行 SQL;主配置文件:XML 配置文件,用于对 MyBatis 底层行为做详细的配置;Mapper 接口:Dao 接口;Mapper 映射器:用于编写 SQL,并将 S

2020-09-28 18:16:05 68

原创 Spring MVC 入门

HTTP超文本传输协议,用于传输 HTML 等内容的应用层协议,规定了浏览器和服务器之间如何通信,以及通信时的数据格式。三层架构和MVC三层架构:表现层、业务层、数据层MVC:Model 模型层(数据)、View 视图层、Controller 控制层浏览器请求先到 Controller,Controller 让业务层处理,得到数据封装到 Model 中,然后传给 View,View 生成 HTML 返回给浏览器。前端控制器 DispatcherServlet 负责调度 MVC(下图 Fron

2020-09-25 21:43:00 51

原创 Spring 入门

IoCIoC(Inversion of Control):控制反转,一种面向对象编程的设计思想。DI(Dependency Injection):依赖注入,IoC 思想的实现方式。IoC Container:IoC 容器,实现依赖注入的关键,本质上是一个工厂。@SpringBootApplicationSpring Boot 核心注解,目的是开启自动配置。主要包含 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan:

2020-09-01 16:51:00 86

原创 Intellij IDEA 2020 新建 Spring Boot 项目

Spring Boot 核心作用:起步依赖、自动配置、端点监控。点击新建项目,选择 Spring Initializr(创建 Spring Boot 项目的引导工具)如果没有 Spring Initializr,在 settings -> Plugins 中搜索并勾选 spring boot,重启即可。项目设置,选择依赖Spring Boot 开发者工具:Spring Boot DevToolsWeb 开发:Spring WebNext,Finish,等待构建启动项目,

2020-08-16 16:52:40 1094

原创 安装 Intellij IDEA 2020

官网下载Ultimate:专业版,收费,有教育邮箱可以免费使用Community:社区版,免费安装选择 32/64 位,其他可以不点初始配置选择皮肤插件后面要用在装,这里先下一步配置 Maven选择 Settings,搜索 Maven,修改为自己 Maven 的安装位置,以及 settings.xml 的位置新建一个 Maven 项目点击 New Project,选择 Maven,选择 JDK,以及用模板创建 Maven 项目点 Next,Next..

2020-08-13 15:24:23 464

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除