大数据正式Zebra1
Zebra1
进程
- 进程
- 程序加载到内存中之后被cpu所计算的过程,进程是计算机资源分配和任务调度的最小单位
- 三个维度
- 进程
- 物理内存维度:每一个进程都要分配一个连续的内存空间【首尾地址】
- 执行角度/逻辑角度:每个进程都可以被cpu计算,每一个进程都能挂起然后让另外的进程被cpu计算--对于单核cpu而言,每一个时刻只能执行一个进程【对于Windows而言,默认是一个核处理,对于linux而言,有几个核就可以用几个核】【微观:串行】【宏观:并行--多道编程】
- 时间角度:在每一个时间角度而言,进程是向前扑进的
- 进程
- 为什么要有进程
- 不引进进程,每个时刻只能有一个任务在执行,效率低下----减少响应时间,提高使用效率、
- IO事件发生时,cpu是不进行计算的【cpu的利用率=1-cpu的利用率n】,理论上来说,进程越多,cpu的利用率越高----提高cpu的利用率
- 进程的生命周期
- 产生
- 系统启动,会创建系统进程
- 用户请求创建进程
- 父进程(主进程)自动去启动子进程
- 进程的消亡
- 正常消亡:进程正常结束
- 意外消亡:进程执行过程中出现错误或异常
- 他杀:一个进程被另外的进程强制关闭
- 产生
- 进程的状态
- 就绪
- 运行
- 阻塞
- 进程的状态转化
- 就绪->运行
- 运行->阻塞
- 运行->就绪
- 阻塞->就绪
- 进程的任务调度算法
- 时间片轮询算法
- 优先级调度算法
- 短任务优先算法
- FIFS,先来先服务
线程
- 线程
- 是进程中执行的任务,线程本质上也是在完成任务、是简化版的进程
- 一个进程中,至少有一线程在执行
- 线程是任务执行的最小单位
Socket/ServerSocket
- Bio(BlockingIO):阻塞式IO--阻塞在一些场景会相对影响效率,因为流有方向性,所以在数据传输的时候往往创建多个流对象,如果流长时间不关闭的话,会造成资源的大量的浪费,无法从流中抽取一段数据
- Nio(NewIO)(NonBlockingIO):非阻塞式IO,基于通道和缓冲区
- 通道【道路】
- 没有方向性--即双向
- 缓冲区【车】
- 实际来传输数据的
- 通道【道路】
- Buffer
- 一个用于特定基本类型的基本数据
- 一般ByteBuffer居多
- 图示
ByteBuffer
- 抽象类
- allocate--获取ByteBuffer对象
- get取值
- put设置值
- flip反转缓冲区
- limit限制位
- position操作位
例
package com.peng.socket;import java.nio.ByteBuffer;import org.junit.Test;public class TestByteBuffer {@Testpublic void testByteBuffer() {// 属性// 1.capacity容量位--表示缓冲区的容量// 2.position操作位--表示要操作的位--当缓冲区刚刚创建的时候,默认为0--每添加一个字节的数据的时候,就 向后移一位// 3.limit限制位--表示position所能达到的最大位置--当缓冲区刚刚创建的时候,limit设置为何容量的大小一样// 创建缓存区,并且指定了 大小:1024字节ByteBuffer bb = ByteBuffer.allocate(1024);// 向缓冲区添加数据bb.put("hello".getBytes());System.err.println("当前的位置:" + bb.position());bb.position(0);// 操作位移到最前面System.err.println("第一个字节:" + bb.get());// 方法--翻转缓冲区flip:先将限制位设置为操作位,再将操作位设置为0// bb.flip();// 方法--rewind:重绕缓冲区--只是将操作位归零// 分界System.err.println("============分解符=============");// 如果知道具体的数据,建议使用这种方法ByteBuffer bb2 = ByteBuffer.wrap("hello".getBytes());System.err.println(bb2.get());while (bb2.hasRemaining()) {// 是否还有剩余数据System.err.println(bb2.get());}} }
- 抽象类
数组复制--保持数据的不变性--副本,不改变原数据
Channel
- 用于I/O操作的连接
- FileChannel
- DataChannel
- ServerSocketChannel
- SocketChannel
- 支持非阻塞连接
- 抽象类
- 创建:open函数
- 双向通讯
Channel的连接步骤
- 客户端
- 打开客户端通道
- 设置为非阻塞通讯
- 连接
- 人为阻塞--防止无效的连接
- 写出数据
- 服务器端
- 打开服务器端的通道
- 绑定要监听的端口号
- 设置为非阻塞
- 接收连接
- 人为阻塞--防止没有获取的真正的连接
- 读取数据
- 例子【客户端】
@Test public void test() throws Exception {// 打开通道--默认为阻塞连接SocketChannel s = SocketChannel.open();// 设置为非阻塞s.configureBlocking(false);// 发起连接s.connect(new InetSocketAddress("localhost", 8090));// 人为阻塞--连接失败则会继续连接while (!s.finishConnect()) {}// 写数据s.write(ByteBuffer.wrap("hello".getBytes()));System.out.println("写出成功!"); }
- 例子【服务端】
@Test public void testServerSocketChannel() throws Exception {// 打开通道--默认为阻塞连接ServerSocketChannel ss = ServerSocketChannel.open();// 设置为非阻塞ss.configureBlocking(false);// 绑定监听的端口ss.bind(new InetSocketAddress(8090));SocketChannel channel = ss.accept();// 人为阻塞while (channel == null) {channel = ss.accept();}// 设置为非阻塞// channel.configureBlocking(false);// 准备缓冲区ByteBuffer buffer = ByteBuffer.allocate(100);// 读出数据channel.read(buffer);// 反转缓冲区--方便之后处理数据buffer.flip();System.out.println("数据:" + new String(buffer.array(), 0, buffer.limit()));System.out.println("接收成功!"); }
Selector选择器
例子
package com.peng.socket;import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set;import org.junit.Test;public class TestSelect {@Testpublic void test1() throws Exception {// 打开客户端通道SocketChannel sc = SocketChannel.open();// 非阻塞sc.configureBlocking(false);// 获取选择器Selector selc = Selector.open();// 将通道注册到选择器上sc.register(selc, SelectionKey.OP_CONNECT);// 注册connect权力// 发起连接sc.connect(new InetSocketAddress("localhost", 8090));while (true) {// 筛选--进行选择--是否包含发放的权力selc.select();// 获取筛选之后的 有用的事件Set<SelectionKey> keys = selc.selectedKeys();// 获取迭代器Iterator<SelectionKey> it = keys.iterator();// 遍历while (it.hasNext()) {// 将遍历到的这个事件获取出来SelectionKey key = it.next();// 可能会发起连接if (key.isConnectable()) {// 获取到对应的通道SocketChannel scx = (SocketChannel) key.channel();// 判断连接是否成功while (!scx.finishConnect()) {}// 重新注册写的权限scx.register(selc, SelectionKey.OP_WRITE | SelectionKey.OP_READ);// 将会将原来的权限覆盖掉}// 可能会写数据if (key.isWritable()) {// 从事件身上获取通道SocketChannel scx = (SocketChannel) key.channel();// 写数据String msg = "hello,hello";scx.write(ByteBuffer.wrap(msg.getBytes()));// 将权限进行修改scx.register(selc, key.interestOps() & ~SelectionKey.OP_WRITE);// 取消写的权限}// 可能从服务器获取数据if (key.isReadable()) {// 从事件身上获取通道SocketChannel scx = (SocketChannel) key.channel();// 读数据ByteBuffer buffer = ByteBuffer.allocate(1024);scx.read(buffer);buffer.flip();System.out.println(new String(buffer.array(), 0, buffer.limit()));// 将读的事件scx.register(selc, key.interestOps() & ~SelectionKey.OP_READ);// 取消读的权限}// 防止事件处理失败--防止重复事件it.remove();}}}/*** 服务器端* */@Testpublic void serverTest() throws Exception {// 打开服务器的通道ServerSocketChannel ssc = ServerSocketChannel.open();// 绑定端口号ssc.bind(new InetSocketAddress(8090));// 设置为非阻塞ssc.configureBlocking(false);// 打开选择器Selector selc = Selector.open();// 注册到选择器上ssc.register(selc, SelectionKey.OP_ACCEPT);while (true) {// 进行选择selc.select();// 将时间获取出来Set<SelectionKey> keys = selc.selectedKeys();// 获取到迭代器Iterator<SelectionKey> it = keys.iterator();// 遍历while (it.hasNext()) {SelectionKey key = it.next();// 可能是接受事件if (key.isAcceptable()) {// 从事件身上获取通道ServerSocketChannel scx = (ServerSocketChannel) key.channel();// 判断连接是否成功SocketChannel sc = scx.accept();while (sc == null) {sc = scx.accept();}sc.configureBlocking(false);// 注册写的权限sc.register(selc, SelectionKey.OP_WRITE | SelectionKey.OP_READ);// 将会将原来的权限覆盖掉}}// 可能是可写事件if (key.isWritable()) {// 从事件身上获取通道SocketChannel scx = (SocketChannel) key.channel();// 写数据String msg = "hello,hello---------I'm Server ";scx.write(ByteBuffer.wrap(msg.getBytes()));// 将权限进行修改scx.register(selc, key.interestOps() & ~SelectionKey.OP_WRITE);// 取消写的权限}// 可能是可读事件if (key.isReadable()) {// 从事件身上获取通道SocketChannel scx = (SocketChannel) key.channel();// 读数据ByteBuffer buffer = ByteBuffer.allocate(1024);scx.read(buffer);buffer.flip();System.out.println(new String(buffer.array(), 0, buffer.limit()));// 修改权限scx.register(selc, key.interestOps() & ~SelectionKey.OP_READ);// 取消读的权限}// 防止事件处理失败--防止重复事件it.remove();}}} }
- 执行结果
- 一个服务端,处理多个客户端的请求
- 监听事件
- 连接一般是客户端
- 接受一般是服务器
- 读写--客户端和服务端都有
NIO
- 数据可以双向传输-- 减少了流的数量,降低服务器的内存消耗
- 由于数据是在缓冲区的,所以可以针对缓冲区的数据做定向操作【视频剪切后加头后还能进行小段播放】
- 能够用一个或少量的服务器来完成大量的用户的请求处理,适用于短任务请求【长任务适用于Socket,点对点】
比较【bio(Socket)与Nio】
bio | nio |
---|---|
流有方向 | 通道,在一个通道上可以进行数据的输入和输出 |
流的数据数连续不断地,不能很灵活的操作数据 | Buffer传输数据的载体,是一个缓冲区,本质上是一个数组结构,缓冲区的大小可以自由控制(注意:实际大小不要超过32GB) |
阻塞通信模型--一个请求产生一个线程 | 非阻塞性通讯模型--一个线程或几个线程处理多用户的请求 |
不适合高并发和高访问,适合长请求 | 适合做高并发和高访的场景,短请求的场景 |
关键技术:buffer,channel |
问题
- A和B同时发送大量的数据,产生了数据粘包,如何处理
- 思路
- 定长--如果数据长度不够,填充无用数据--无用数据的区分
- 约定结尾的符号--结束符号可能会与实际内容冲突、
- 序列化/反序列化【一般用这个】--【约定了起始和结束的协议】
- 思路
大数据正式Zebra1相关推荐
- 大数据正式京淘附加爬虫
大数据正式京淘附加爬虫 爬虫技术 httpClient:抓取整个页面 htmlUnit:可以二次提交 jsoup:可以获取以上两个技术的所有内容 jsoup 爬取整个页面 爬取整个网站 爬取页面中的某 ...
- Cloud一分钟 | 苹果更新“隐私页面”;中国联通大数据正式升级,进入数智新阶段...
Hello,everyone: 10月22日早,星期一,祝大家工作愉快! 一分钟新闻时间: 完 1.微信群: 添加小编微信:tangguoyemeng,备注"进群+姓名+公司职位" ...
- 大数据使用及现状调研报告
大数据使用及现状调研报告 大数据,指无法在一定时间范围内用常规软件工具进行捕捉.管理和处理的数据集合,是需要新处理模式才能具有更强的决策力.洞察发现力和流程优化能力的海量.高增长率和多样化的信息资产. ...
- 【2016年第3期】以大数据为核心 驱动智慧城市变革
单志广,房毓菲 国家信息中心信息化研究部,北京 100045 摘要:建设智慧城市已成为国家发展新空间的重要举措,近年来我国智慧城市建设取得了积极进展.当前社会正在迈入大数据时代,大数据将成为智慧城市建 ...
- 这是您正在找的大数据、人工智能实战培训课程!
实战!实战!实战!课堂没有冗长乏味的理论讲授,通过密集的高强度实战课程,带领学员克服大数据.人工智能能力提升中各阶段的典型痛点和难点,帮助学员迅速从"初出茅庐"的新兵成长为&quo ...
- 已有123所大学将云创大数据人工智能免费直播课引入课堂!
4月28日,云创大数据正式发文公布了云创大学可以为高校提供高质量免费直播授课的通知.消息一经发出,受到各高校的积极反馈.截止到目前,已有123所大学将云创的大数据人工智能免费直播课引入课堂. 从5月2 ...
- 大数据产业版图:东南沿海引领 独角兽扎堆北上深杭
当今世界最有价值的资源是什么?数据一定是不可回避的.数据是重要的基础性战略资源,大数据发展正在驱动经济社会诸多领域发生深刻变革--目前已成为各界的共识.大数据也是信息经济的关键生产要素,大数据产业的发 ...
- 中国大数据产业版图:东南沿海继续引领 独角兽扎堆北上深杭
当今世界最有价值的资源是什么?数据一定是不可回避的.数据是重要的基础性战略资源,大数据发展正在驱动经济社会诸多领域发生深刻变革--目前已成为各界的共识.大数据也是信息经济的关键生产要素,大数据产业的发 ...
- 大数据学习资源之DataCamp
"有很多事情我们做的并不完美,但这可能是当时当刻唯一正确的决定." --托尼老师 <Nature>杂志早在2008年第一次提出"Big Data" ...
最新文章
- cannot assign module before Module.__init__() call
- [转]NS2仿真过程中解决动画仿真节点未定义问题
- asm 查看 数据文件 修改 时间_更高效的GMX分段模拟方法:修改tpr文件
- java date 最小值_java – Datepicker和timepicker – 设置最大值和最小值
- MongoDB数据库备份与恢复
- Problem - 6111迷宫出逃
- 十二、程序返回、数据类型表示、代码注释
- 从源码角度解析线程池中顶层接口和抽象类
- 方维模板修改,发布分享、主题有商品时,标签需自动写到input里,不要再手动去点击添加,手动点击可取消...
- 自学python需要安装什么-Python学习需要安装的工具
- JDY-24M钥匙标签使用说明
- Hibernate的配置文件配置
- 11.4-11.10PS自学第6课——套索与魔棒工具
- 2022-UNCTF部分wp以及web的赛后复现学习
- lol服务器崩溃补偿领取中心,LOL官方: 服务器崩溃补偿! 全服再次免费赠送皮肤一款!...
- vue axios介绍
- 测试人员如何区分前端和后台BUG方法流程
- spring用到的设计模式
- php人民币小写转大写函数
- win7系统双硬盘双系统问题解决