后端整理(集合框架、IO流、多线程)
1. 集合框架
Java集合类主要有两个根接口Collection和Map派生出来
Collection派生两个子接口
- List
List代表了有序可重复集合,可以直接根据元素的索引进行访问 - Set
Set代表无序不可重复集合,只能根据元素本身进行访问
Map接口派生
Map代表的是存储key-value对的集合,可根据元素的key来访问value
1.1 List
List集合特点:有索引,可重复,有序
扩容机制
- 初始值为10
- 如果数组的长度小于需要的最小容量则自动扩容
- 扩容到原来的1.5倍
ArrayList
底层通过数组实现,查询快,增删慢,线程不安全
访问数据的时间复杂度是O(1)
LinkedList
底层通过双向 链表实现,查询慢,增删快,线程不安全
访问数据的时间复杂度是O(n)
Vector
List接口的古老实现类。线程安全,执行效率低
扩容机制不同于ArrayList,由1.5倍改成1倍
1.2 Set
1.2.1 HashSet
其底层HashMap,也就是数组+链表+红黑树(JDK8)的结构
HashSet集合特点:无序,不可重复,无索引
扩容机制
HashSet底层也是数组,初始容量为16,当使用了超过0.75,即16*0.75=12时,就会扩大容量为原来的两倍
什么情况下为转为红黑树
当链表长度 >= 8,数组长度 >= 64时,会转为红黑树
LinkedHashSet
继承于HashSet,底层是LinkedHashMap,是一个有序去重集合,线程不安全
有序因为它根据hashCode决定元素的存储位置,同时使用链表来维护元素的次序
1.2.2 TreeSet
TreeSet是SortedSet接口的实现类,底层是红黑树,元素有序
排序方式
自然排序(实现Comparable接口)和 定制排序(Comparator)
1.3 Map
Map集合特点
- 键值对(key-value)映射关系
- 是单向的一对一关系,即一个键对应一个值
- 键不可重复,值可重复
- 无序
1.3.1 HashMap
HashMap的底层在jdk7及以前,是数组+链表;jdk8及以后,是数组+链表+红黑树
如何判断重复
先比较hashcode,若相同则使用equals比较插入的值,若值不同,则插入,若值不同,则不插入
2 IO流
IO流的体系
IO流的四大类
- 字节输入流: 以内存为基准,把磁盘文件/网络中的数据以字节的形式读入到内存中去
- 字节输出流: 以内存为基准,把内存中的数据以字节的形式写出到磁盘文件或网络中去
- 字符输入流: 以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入内存中
- 字符输出流: 以内存为基准,把内存中的数据以字符的形式写出到磁盘文件或网络中去
2.1 IO流实现文件的上传下载
2.1.1 文件上传
文章引用IO流–文件上传实现(侵删)
文件上传,我们就需要的一个服务器和客户端,两者需要进行通信,两者通信的要素是服务器的IP地址和对应的端口号才能建立连接
- 首先开启服务器,并开启一个端口号给客户端进行连接通信
serverSocket = new ServerSocket(port);
- 服务器通过监听端口来进行确定是否有客户端进行访问
socket = serverSocket.accept();
- 服务器准备完成,可以与客户端进行通信,首先客户端创立连接
socket = new Socket(InetAddress.getByName(IP), port);
- 连接成功,然后通过IO流进行文件传输,先读取文件,再将文件转为IO流输出(读取是本地读取,输出是输出给服务端)
//2.然后向服务器发送消息,需要一个输出流os = socket.getOutputStream();//3.读取本地的文件并输出,需要一个输入流is = new FileInputStream("123.txt");
- 客户端需要通过一个缓冲区来让文件实现完整的上传和输出,通过一个字节数组,保证整个文件不会因为字符数量的大小导致文件上传失败
//4.读取文件中的内容并输出,读取文件的内容需要一个字节流,用字节数组来接收byte[] buffer = new byte[1024];//这个字节数组是属于IO流中的缓冲区,int length ;while ((length=is.read(buffer) )!= -1){os.write(buffer,0,length);}
- 到这一步,客户端的任务完成了大半,然后就是服务器端的接受操作,与客户端也是大同小异,通过文件字节输入流和文件字节输出流对连接中的数据进行读取和输出
//1.先创建一个端口号供客户端去连接,其实应该先有一个服务器端口号,那客户端才能连上(怎么创建一个端口号?)serverSocket = new ServerSocket(8099);//2.服务器监听端口号,看端口号是否有客户端连接socket = serverSocket.accept();//3.创建一个输入流和一个输出流,输入流用于接收客户端传来的数据,输出流用于输出is = socket.getInputStream();//在建立起的连接中获取信息os = new FileOutputStream("receive.txt");//这里输出的用的是文件流int len ;byte[] bytes = new byte[1024];while ((len = is.read(bytes)) != -1){os.write(bytes,0,len);}
完整代码实现
客户端
/**客户端*/
public class TcpClient {public static void main(String[] args) {Socket socket = null;OutputStream os = null;FileInputStream is = null;try {//1.客户端要连接服务器,需要创建一个连接,创建连接需要服务器的IP号和对应的端口号socket = new Socket(InetAddress.getByName("127.0.0.1"), 8099);//2.然后向服务器发送消息,需要一个输出流os = socket.getOutputStream();//3.读取本地的文件并输出,需要一个输入流is = new FileInputStream("123.txt");//4.读取文件中的内容并输出,读取文件的内容需要一个字节流,用字节数组来接收byte[] buffer = new byte[1024];//这个字节数组是属于IO流中的缓冲区,int length ;while ((length=is.read(buffer) )!= -1){os.write(buffer,0,length);}} catch (IOException e) {e.printStackTrace();}finally {//5.关闭连接if (is != null){try {is.close();} catch (IOException e) {e.printStackTrace();}}if (os != null){try {os.close();} catch (IOException e) {e.printStackTrace();}}if (socket != null){try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
}
服务器
/**服务器*/
public class TcpServer {public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;InputStream is = null;FileOutputStream os =null;try {//1.先创建一个端口号供客户端去连接,其实应该先有一个服务器端口号,那客户端才能连上(怎么创建一个端口号?)serverSocket = new ServerSocket(8099);//2.服务器监听端口号,看端口号是否有客户端连接socket = serverSocket.accept();//3.创建一个输入流和一个输出流,输入流用于接收客户端传来的数据,输出流用于输出is = socket.getInputStream();//在建立起的连接中获取信息os = new FileOutputStream("receive.txt");//这里输出的用的是文件流int len ;byte[] bytes = new byte[1024];while ((len = is.read(bytes)) != -1){os.write(bytes,0,len);}} catch (IOException e) {e.printStackTrace();}finally {if (os != null){try {os.close();} catch (IOException e) {e.printStackTrace();}}if (is != null){try {is.close();} catch (IOException e) {e.printStackTrace();}}if (socket != null){try {socket.close();} catch (IOException e) {e.printStackTrace();}}if (serverSocket != null){try {serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}
}
2.1.2 文件下载
文章引用利用io流下载文件(侵删)
public void download(HttpServletRequest request, HttpServletResponse response) {InputStream fis=null;OutputStream toClient=null;try {//获取下载的路径File file=new File("C:\\Users\\kinggao1\\Desktop\\工作周总结.docx");//获取文件名String filename=file.getName();//取得文件的后缀名String ext=filename.substring(filename.lastIndexOf(".")+1).toUpperCase();//以流的形式下载文件fis=new BufferedInputStream(new FileInputStream(file));System.out.println("文件大小:"+fis.available());//创建一个和文件一样大小的缓存区byte[] buffer=new byte[fis.available()];//读取流fis.read(buffer);//清空首部空白行response.reset();//设置文件下载后的指定文件名response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("gb2312"),"ISO8859-1"));response.addHeader("Content-Length", "" + file.length());//response.getOutputStream() 获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。toClient = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");//将buffer 个字节从指定的 byte 数组写入此输出流。toClient.write(buffer);//刷新此缓冲的输出流。这迫使所有缓冲的输出字节被写出到底层输出流中。 把缓存区的数据全部写出toClient.flush();} catch (IOException e) {e.printStackTrace();} finally {try {//关闭流fis.close();//关闭缓冲输出流toClient.close();} catch (IOException e) {e.printStackTrace();}}}
2.2 IO流实现文件上传时限制文件大小
获取文件IO流的大小
long fileLenght = getFileLenght(file);
再和给定大小判断
如果超出就跑出自定义异常
3 线程
3.1 4种线程的创建方法
- 继承Thread方法,实现run方法
- 实现Callable接口,重写call方法
- 实现Runnable接口,重写run方法
- 线程池构建线程
3.2 线程的状态
3.3 自定义线程池的核心参数
- 核心线程数
- 最大线程数
- 最大存活时间
- 最大存活时间单位
- 阻塞队列
- 线程工厂
- 拒绝策略
拒绝策略有四种:
- 抛出异常
- 把处理返回给调用者,谁调用谁处理
- 直接拒绝
- 清理掉最早的线程,再加入新建的线程
3.4 锁
文章参考于阿里面试失败后,一气之下我图解了Java中18把锁
3.4.1 悲观锁
悲观锁相当与生活中悲观的人,什么事都会忘坏的方向思考
具体来说,就是一个共享数据加了悲观锁,那么线程每次想要操作数据时,都会考虑数据可能也会被其他线程操作,所以每次操作前都会上锁,这样别的线程想要操作这个数据但是没有锁只能够阻塞了
Java中,synchronized就是一种典型的悲观锁
3.4.2 乐观锁
与悲观锁相反,乐观锁相当于生活中的一个乐观的人,什么事情都会往好的方向进行思考
所以,乐观锁在操作数据时不会给共享数据上锁,但是会在更新的时候判断在此期间是否会有其他线程对数据进行了更新
乐观锁可以使用<font color="pink"版本号机制和CAS算法实现,在Java语言中 java.util.concurrent.atomic 包下的原子类就是使用CAS乐观锁实现的
两种锁的使用场景
乐观锁适用于冲突小(可以理解为读多写少)的场景,因为不用上锁,释放锁,省去了锁的开销,从而提升了吞吐量
悲观锁适用于写多读少的场景,冲突比较严重,线程竞争比较激烈,使用乐观锁就是导致线程不断的进行重试,这样还可能降低了性能
3.4.3 互斥锁
互斥锁是独占锁的一种常规实现,是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排他性
互斥锁一次只能一个线程拥有互斥锁,其他线程只有等待。
3.4.4 自旋锁
自旋锁是指线程在没有获得锁资源时不是直接挂起,而是执行一个忙循环,这个忙循环就是所谓的自旋
相关文章:

后端整理(集合框架、IO流、多线程)
1. 集合框架 Java集合类主要有两个根接口Collection和Map派生出来 Collection派生两个子接口 List List代表了有序可重复集合,可以直接根据元素的索引进行访问Set Set代表无序不可重复集合,只能根据元素本身进行访问 Map接口派生 Map代表的是存储key…...

C++ 类和对象篇(二) this指针
目录 一、this指针概念 二、this指针的特性 三、this指针存在哪里? 四、this指针可以为空吗? 一、this指针概念 1.是什么? 它是类内非静态成员函数的隐含形参,this指针指向调用该函数的对象。 this指针是C编译器给每个“非静态…...

Excel快捷键F1-F9详解:掌握实用快捷操作,提升工作效率
Excel是广泛应用于办公场景的优质电子表格软件,然而,许多人只是使用鼠标点击菜单和工具栏来完成操作,而忽略了快捷键的威力。在本文中,我们将详解Excel中的F1-F9快捷键,帮助您掌握实用的快捷操作,提升工作效…...
Webpack 安装教程
Webpack 是一个前端资源加载/打包工具。 安装 Webpack 使用 cnpm 安装 webpack: cnpm install webpack -g 创建项目 接下来我们创建一个目录 app: mkdir app 在 app 目录下添加 runoob1.js 文件,代码如下: app/runoob1.js 文件…...

移远通信首批加入“5G+eSIM计算终端产业合作计划”,助力大屏移动终端全时在线
7月29日,在全球数字娱乐产业盛会 ChinaJoy上,中国联通携手高通公司、GSMA发布了“5GeSIM 计算终端产业合作计划”。 作为全球领先的物联网整体解决方案供应商,移远通信首批加入该计划,副总经理刘明辉受邀参加5GeSIM 计算终端产业合…...
全网最强大的工具箱—utools介绍及分享
今天来介绍一个相见恨晚的PC端工具——utools,什么是utools?用其自身的话来说:“uTools是一个极简、插件化、跨平台的现代化桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。”,体验了下,好用且强大&…...

Linux常用基础命令❀
文章目录❀ ❀ls命令 ❀cd命令 ❀pwd命令 ❀date命令 ❀创建、删除文件和目录命令 ❀alias命令 ❀复制、移动、重命名、查看(文件、目录)命令 ❀find查找、wc统计命令 ❀vi/vim命令 1、打开文件 2、工作模式 vi与vim的四个模式 进入编辑模式…...

SQL-进阶
mysql --local-infile -u root -pset global local_infile 1;load data local infile 目录 into able 表名 fields terminated by , lines terminated by \n;...

[Pytorch]卷积运算conv2d
文章目录 [Pytorch]卷积运算conv2d一.F.Conv2d二.nn.Conv2d三.nn.Conv2d的运算过程 [Pytorch]卷积运算conv2d 一.F.Conv2d torch.nn.functional.Conv2d()的详细参数: conv2d(input: Tensor, weight: Tensor, bias: Optional[Tensor]None, stride: Union[_int, _s…...

主流开源监控系统一览
减少故障有两个层面的意思,一个是做好常态预防,不让故障发生;另一个是如果故障发生,要能尽快止损,减少故障时长。而监控的典型作用,就是帮助我们发现及定位故障,这两个环节对于减少故障时长至关…...

爬虫原理详解及requests抓包工具用法介绍
文章目录 一、什么是爬虫?二、爬虫的分类三、网址的构成四、爬虫的基本步骤五、动态页面和静态页面六、伪装请求头七、requests库介绍1. 概念:2. 安装方式(使用镜像源):3. 基本使用:4. response对象对应的方…...

tinkerCAD案例:31. 3D 基元形状简介
tinkerCAD案例:31. 3D 基元形状简介 1 将一个想法从头脑带到现实世界是一次令人兴奋的冒险。在 Tinkercad 中,这将从一个新的设计开始。 在新设计中,简单的原始形状可以通过不同的方式组合成更复杂的形状。 在这个项目中,你将探索…...

Vue2基础一、快速入门
零、文章目录 Vue2基础一、快速入门 1、Vue 概念 (1)为什么学 前端必备技能 岗位多,绝大互联网公司都在使用Vue 提高开发效率 高薪必备技能(Vue2Vue3) (2)Vue是什么 **概念:…...
【POJ-3279】Fliptile(递推+搜索)
POJ-3279. Fliptile(递推搜索) Vjudge链接 题目描述 农场主约翰知道,一头智力得到满足的奶牛是一头快乐的奶牛,它会产更多的奶。他为奶牛安排了一项脑力活动,让它们摆弄一个 M N M N MN 的方格 ( 1 ≤ M ≤ 15 …...
522个matplotlib绘图案例,包含:折线图、散点图、条形图、饼图、直方图、3D图等,源码可直接运行!
文章目录 matplotlib介绍图表介绍折线图(Line Plot)散点图(Scatter Plot)条形图(Bar Plot)饼图(Pie Chart)直方图(Histogram)箱线图(Box Plot&…...

windows安装Elasticsearch8.9.0
官网解压安装好路径(非中文,无空格) 可参考 言之有李LAX csdn http://t.csdn.cn/S2oju本人使用jdk17 修改配置elasticsearch.yml xpack.security.enabled: false xpack.security.http.ssl:enabled: false直接点击bin\elasticsearch.bat…...

用Delphi编写一个通用视频转换工具,让视频格式转换变得更简单
用Delphi编写的简单视频格式转换程序,它使用TComboBox、TOpenDialog和TSaveDialog组件来选择转换格式、选择源视频文件和选择目标视频文件。程序还使用TEdit组件允许用户输入参数,然后将这些组件中的信息拼接成转换命令并在DOS窗口中运行它。 procedure…...
Kafka系列之:安装Know Streaming详细步骤
Kafka系列之:安装Know Streaming详细步骤 一、相关技术博客二、安装elasticsearch1.下载elasticsearch2.创建数据目录3.创建es用户4.修改最大文件数5.解压elasticsearch6.赋予es用户目录权限7.修改es配置8.切换es用户启动elasticsearch三、安装KnowStreaming1.下载KnowStreami…...

绝杀 GETPOST 嵌套的 JSON 参数
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于Web应用程序中的数据传输。在HTTP数据包信息传递时,JSON扮演着非常正常的角色,因为它是一种通用的数据格式,可以被多种编程语言和应用程…...

Spring 项目过程及如何使用 Spring
文章目录 1.创建 Spring 项目步骤1.1 创建 Maven 项目1.2添加 Spring 框架支持1.3 添加启动项2.如何使用 Spring2.1 存储 Bean 对象2.1.1 创建 Bean对象2.1.2 将 Bean对象注册到容器中 2.2 获取并使用 Bean对象2.2.1 使用 ApplicationContext 获取对象2.2.2 使用 BeanFactory 获…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...