计算机网络笔记(6)

基本数据链路层协议

协议1:一个乌托邦式的单工协议

单工协议即数据只能单向传输。这个协议假设信道永远不会丢失或损坏帧,接收方的处理能力足够快,缓冲区足够大。

发送程序无限循环,接受程序响应事件,协议1中不包含流量控制和纠错功能。

协议2:无错信道上的单工停-等式协议

发送方的速度如果过快,接收方会被淹没,除了增强接收方的处理能力,可以让接收方给发送方发送反馈,发送方收到后才可以发送下一帧。

发送程序无限循环并等待接收方确认,接受程序响应事件后发送确认帧。

协议3:有错信道上的单工停-等式协议

有错信道上传输数据需要增加校验,接收方仅在数据正确时发送确认帧。但在确认帧丢失的情况下(超时),发送方将重发。接收方难以判断帧是重发还是新发,因此帧前加上序号以区分。

重复的帧也会收到确认帧,以便发送方决策。

Java: No enclosing instance of type xxx is accessible

public class KMeans {
	class point{
		double x;
		double y;
		point(double x,double y){
			this.x=x;
			this.y=y;
		}
	}
	public static void main(String args[]) throws IOException {
		point p=new point(1,1);
	}
}

上面这段代码会遇到No enclosing instance of type xxx is accessible(xxx类型的装入实例不可用)报错,原因在于编译运行KMeans类的时候,并没有产生实例(你看main也是静态方法);而KMeans下包含的point内部类是非静态的,只有实例对象才能使用它。外部类是直接被加载到内存了,而内部非静态类就需要一个实例对象来包含它。

知道了这一点,就可以得出结局方案,可以把point改为静态类,也可以新建KMeans实例后再使用point类。

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1q1xzkj9mydbq

死锁(Deadlock)简析

参考了学堂在线操作系统课程30240243X

死锁是操作系统中进程共享资源时由于循环占有并等待资源而造成的无限期等待状态。

比如A进程占有资源R1,需要资源R2,而B进程占有资源R2并需要资源R1,A、B进程互相等待对方完成任务并释放资源,形成了死锁。

死锁条件与预防(Prevention)方案

形成死锁需要同时满足4个条件(逻辑上的关系不很明确,但这4个讨论足够关键):

1.互斥

即一个资源只能同时被一个进程所使用。可以想象,如果一个资源可以被同时使用,那么不会出现等待资源的情况。

预防

通过封装使独占资源可以同时使用,比如在打印机内部维护打印缓存队列。

2.持有并等待

至少持有一种资源,同时至少等待一种资源。

预防

持有资源可能会被其他进程请求,不持有则不可能被请求,无法形成环,我们可以要求进程在申请资源时保证其不持有任何资源。有时候这条规则变成进程初始化时必须申请完所有需要的资源。

3.非抢占

资源只能由使用它的进程完成任务后释放。

预防

如果允许抢占,即释放需要而被占用的资源,那么不需要等待,不会形成环。我们也要求只有在进程能同时获取(或抢占)到所有资源时才分配,这一点和解除持有并等待类似。

4.循环等待

进程间存在一个循环。如进程A需要进程B的资源,进程B需要进程C的资源,进程C需要进程A的资源。

预防

对资源排序,要求进程按顺序申请资源。比如进程A需要R1、R2,于是先申请R1、R2,结束任务后进程B再申请,但B可以先申请R3。也就是说,申请资源的顺序一定要符合资源的排序,资源申请形成了一个单向的通道。

预防的缺点

预防可能会导致进程等待资源时间变长很多,对效率影响很大,因此很少采用。

死锁避免(Deadlock Avoidance)

利用额外的先验信息,在进程请求分配资源时判断分配是否可能造成死锁,有可能则不分配。

避免的要求

要求进程声明所需的最大资源数,操作系统限制提供的资源,确保能满足进程所需的所有资源。这种方法要求分配资源时动态检查,不会出现死锁时分配资源。

检查要求在占有资源的所有进程中,存在一个安全序列使得这些进程能够执行完他们的所有任务。我们给这些进程编号P[1]到P[N],要求P[I]请求的资源<=当前空闲资源+P[1到I-1]占有的所有资源。换句话说,前面的进程完成任务后会释放资源,这部分资源加上原本就可用的资源必须能够满足后面请求资源的进程,如果不够则有可能出现死锁。

银行家算法(Banker's Algorithm)

银行在提供贷款时有两个条件,一个是客户申请贷款时告知银行他需要多少钱并能用完后归还,另一个是银行提供的贷款不超过自身持有的资金但尽量满足客户需求。银行家算法与此类似。

我们假设系统中有n个线程,m种类型的资源。

于是我们可以画一个Max矩阵(n*m的总需求量矩阵)表示线程Ti最多需要请求Rj类型的资源Max[i,j]个实例;已经分配的资源用Allocation矩阵(n*m)表示;还需要的资源(Max-Allocation)用Need矩阵表示;还可以分配的(空闲的)资源用Available矩阵表示。

操作系统每次分配资源时都要检查,如果分配后,存在一个进程顺序{P1,P2,...}使得他们按顺序申请资源而不会造成某个进程无法取得其所需的最大资源,那么分配完的情况是安全的,操作系统同意分配。不安全状态不一定是死锁,但随着进程继续最终会变成死锁状态。

银行家算法允许互斥、部分分配和不可抢占,能够提高资源利用率,但应用程序提前声明所需的最大资源量是很难实行的。

死锁检测和恢复(Deadlock Detection & Recovery)

监测到死锁后用结束部分进程、强制释放资源或回滚等方法解除死锁。由于死锁发生概率小,预防开销大,Windows、UNIX以及数据库系统都采用这种方法。

计算机网络笔记(7)

回顾

帧同步、差错控制、对等通信协议

乌托邦协议、简单流量控制、出错重传(定时器、序列号)、捎带确认

发送窗口的大小等于能够发送的帧的数量

数据链路层和传输层使用滑动窗口协议

滑动窗口协议

全双工:任何一方即是发送方也是接收方。

捎带确认:确认并非单独的帧,而是被附加到数据帧。

序号:任何帧都有一个序号,确认帧也包含被确认帧的序号。

窗口:窗口是一个环,并且存在上下界。发送方窗口内的序号代表那些可以被发送或还未收到确认的帧。当有新的包从网络层传来,它被赋予最高序号的下一个序号,同时窗口上边界前移一个序号。收到确认帧后,窗口下边界也前移一个序号。

对于接收方,如果接收到的帧的序号等于窗口下边界,那么下边界前移,如果落在窗口内,那么放入缓存区,落在窗口外则被丢弃。在任何情况下,接收方都要发送确认帧,这可以为发送方的行为提供决策依据。

协议4:一位的滑动窗口协议

发送窗口大小=接收窗口大小=1,效率极低。只有窗口大于1才能提高信道利用率。

特殊情形

如果超时时间过短,那么每一帧都可能被发送多次。

当双方同时开始发送,会出现如下情景:发送方收到带有确认信息的帧,但确认信息不正确(发送方发送的第一帧也含有确认信息),导致双方都必须重发。

PS:我感觉第一帧如果能特殊标记,那么也能够避免第一帧携带的确认信息+同时发送导致重发的情况。

协议5:回退n

发送窗口大于1,接收窗口等于1。出错时重传帧数多,适用于信道质量好,出错率少的情况。

阻塞前发送的帧数

w<=1+2BD,具体参考https://www.guohere.com/4613.html的20题。

可发送帧数与序号

可发送帧数在协议5中并不等于序号空间的大小,而是要-1,因为在确认帧丢失并重发的情况下,接收方需要判断新的一批是新帧还是重发帧。

协议6:选择重传

发送窗口和接收窗口都大于1,ack累计,出错时可以累计重传,可以否定重传。于是接收方可以只丢弃错帧,发送方可以只重传出错帧,适用于信道质量不好的情况。

接收方的窗口大小要小于等于表达第n帧的状态数,否则窗口重叠会导致无法辨认重传信息属于哪个窗口。发送窗口一般等于接收窗口,接收窗口必须小于能表达的窗口序号/2。

了解概念

HDLCHigh-level Data Link Control)协议

面向连接:协议建立、释放逻辑连接

流控制:滑动窗口协议,有序号和确认

差错控制:使用回退n帧协议或者选择重传协议

PPPPoint-to-Point Protocol)协议

面向字符的数据链路协议,字符填充成帧,面向网络层的IP协议,具有差错控制、身份认证功能

ADSL

广泛用于通过本地回路宽带接入

链路层总结

帧同步、差错控制、协议

第四章介质访问控制子层(Media Access ControlMAC

概念

MAC层介于物理层与数据链路层之间,Link层包括MAC和LLC。

以太网(Ethernet)包括经典以太网与8028.3Ether ne

数据通信方式

单播(unicast):点对点

广播(broadcast):全部可以传输,信道共享。MAC算法使广播基于规则而平等。

组播(multicast):一组中的广播

动态分配信道

ALOHA协议

无线中,设备随时可以发送信息,由于可能冲突而浪费信道容量,闲时很高效,忙时几乎无法避免冲突,信道利用率只有18.4%。

时隙(SlottedALOHA协议

时间分槽,时间被分成很多固定长度(一帧的传输时间)的时间片,设备在任意时间片开始时发送信息,减小了冲突的可能(只可能发生在同一时间片),信道利用率36.8%

载波侦听多路访问协议(Carrier Sense Multiple AccessCSMA

CSMA的特征是“先听后发”,是对ALOHA协议的改进。

非持续式:侦听信道,介质空闲时发送,介质忙时等待一个随机时间,再忙再重复。会由于等待的随机时间浪费信道容量。

1-持续式:侦听信道,介质闲时发送,忙时持续侦听,一旦空闲立即发送,如果冲突,等待一个随机时间再继续侦听。多个设备准备发送时,由于侦听到同一空闲,会发生冲突。

p-持续式:侦听信道,如介质空闲,以p的概率发送,(1-p)的概率等待随机时间。如介质忙或等待了一个随机时间,持续侦听,空闲后重复步骤一。

冲突域(物理层概念):数据包产生和冲突的网络区域,存在共享媒质区就一定存在冲突域。CSMA即使侦听到空闲,仍然有可能冲突,原因有两点:同时开始的传输、介质中的传播延迟

npm,yarn如何查看源和换源

转自https://zhuanlan.zhihu.com/p/35856841

重新安装npm后总要设置一下

npm, yarn查看源和换源:

npm config get registry  // 查看npm当前镜像源

npm config set registry https://registry.npm.taobao.org/  // 设置npm镜像源为淘宝镜像

yarn config get registry  // 查看yarn当前镜像源

yarn config set registry https://registry.npm.taobao.org/  // 设置yarn镜像源为淘宝镜像

镜像源地址部分如下:

npm --- https://registry.npmjs.org/

cnpm --- https://r.cnpmjs.org/

taobao --- https://registry.npm.taobao.org/

nj --- https://registry.nodejitsu.com/

rednpm --- https://registry.mirror.cqupt.edu.cn/

npmMirror --- https://skimdb.npmjs.com/registry/

deunpm --- http://registry.enpmjs.org/

Json Web Tokens

这篇文章是对网络上相关信息的总结,详情可以参考《JSON Web Token 入门教程》

http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

使用JWT

JWT作为一道具有过期时间的令牌存储在Cookie或localStorage,与服务器通信时都会捎带上。既可以写在Cookie里,也可以放在HTTP头中,还可以写在具体的请求里。

JWT结构

JWT由3个JSON对象组成,最终的JWT是经过转码(参考Base64)的字符串。

Header

键包括alg(algorithm)与typ(type),指出了签名算法与令牌类型。

Payload

JWT传输的信息,键包括生效时间、过期时间、签发人等。

Signature

在服务器上用密钥生成Header与Payload的签名,防止JWT信息被篡改。

JWT注意事项

  • JWT默认不加密,有需要可以加密
  • 如果不加密,建议使用HTTPS协议防止被盗用
  • JWT有效时长无法更改,不建议设置时间太长

用CSS画一个QQ音乐图标

主要用到了relative定位、border的垂直和水平分量,之所以用区块遮盖实现内凹,因为radial-gradient我不太熟悉。

<head>
    <style>
         :root {
            --color: rgb(68, 202, 68);
        }
        
        .div {
            width: 240px;
            height: 240px;
            border-radius: 120px;
            background-color: rgb(235, 227, 128);
        }
        
        .music {
            --vertical: 40px;
            --horizontal: 50px;
            width: 100px;
            height: 80px;
            background: var(--color);
            border-bottom-left-radius: var(--horizontal) var(--vertical);
            border-bottom-right-radius: var(--horizontal) var(--vertical);
            border-top-left-radius: var(--horizontal) var(--vertical);
            border-top-right-radius: var(--horizontal) var(--vertical);
            position: relative;
            top: calc(100% - 90px);
            left: calc((100% - 100px)/2);
        }
        
        .pole {
            height: 170px;
            width: 10px;
            background: var(--color);
            position: relative;
            left: 52px;
            bottom: 120px;
            border: 10px;
            transform: rotate(-27deg);
        }
        
        .flag {
            width: 80px;
            height: 40px;
            background-color: var(--color);
            border-bottom-right-radius: 60px 35px;
        }
        
        .block {
            background: rgb(235, 227, 128);
            width: 80px;
            height: 20px;
            border-bottom-left-radius: 70px 20px;
            position: relative;
            bottom: 1px
        }
    </style>
</head>

<body>
    <div class="div">
        <div class="music">
            <div class="pole">
                <div class="flag">
                    <div class="block"></div>
                </div>
            </div>
        </div>

    </div>
</body>

CSS Functions && CSS Variables

CSS Variables

Syntax

{
--variable:#ffffff;
color: var(--variable);
}

CSS Functions

calc()

calc()用于对数值作计算,单位包括长宽(px、vw等)、频率(Hz等)、角度(deg、rad、turn等)、时间(s、ms)、小数和整数。

calc()要求+和-的左右有空格。

例如,width:calc(100% - 30px)定义了比父元素宽度小30px的宽度。

attr()

attr()用于取回被选择元素的属性,比如对一个<img>标签,可以用attr(src)获取图片地址。如果css选择器选择了多个元素,attr()在每个元素上可能有不同结果。

max()

取最大值。

min()

取最小值。

fit-content()

fit-content()接受一个参数,如果这个参数超过可设置的最大值,那么用最大值替代,如果小于最小值,则用最小值替代。原理其实是min(maximum size, max(minimum size, argument))。

env()

env()的作用类似于var(),但env()除了返回值,还会改变user agent-defined环境变量的值,MDN有如下例子:

body {
  padding:
    env(safe-area-inset-top, 20px)
    env(safe-area-inset-right, 20px)
    env(safe-area-inset-bottom, 20px)
    env(safe-area-inset-left, 20px);
}

第二个参数是可以省略的,这样不会更改user agent-defined环境变量的值。

user agent stylesheet即浏览器默认样式表,比如<h1></h1>会自带margin。有时这会给开发和适配带来不便,解决方案是使用reset.css。

counter()

MDN示例,看完应该明白了:

HTML

<ol>
  <li></li>
  <li></li>
  <li></li>
</ol>

CSS

ol {
  counter-reset: listCounter;/**重置计数器**/
}
li {
  counter-increment: listCounter;/**每多一个li元素listCounter+1**/
}
li::after {
  content: "[" counter(listCounter) "] == [" counter(listCounter, upper-roman) "]";/**通过counter获取listCounter的值**/
}

RESULT

linear-gradient()

线性渐变图像,支持设置颜色、角度、位置(百分比位置),例如:

background: linear-gradient(0.5turn, #e66465 0%, #9198e5 100%);

repeat()、minmax()

和Grid配合使用,详情参考CSS Grid

rotate()、matrix()、scale()、translate()、skew()等

旋转、矩阵表达的线性变换、缩放、移动、扭曲,详情参考CSS transform

opacity()、blur()等

透明、模糊,详情参考CSS filter

一些实验特性

element()

比如background:element(#id)可以以#id选择的元素为背景,element()使元素作为图片使用。仅Firefox支持。

JavaScript原型链档案

原型链是JavaScript中的“继承”。

JavaScript中的“类”

事实上JavaScript一直以来都是基于对象和原型的,除了Number、String、Boolean等基本数据类型之外,JavaScript中的一切都是对象。ES6中新增的class、constructor、static、extends、super等关键字都是基于对象和原型的语法糖。

JavaScript中的“继承”

我们知道extends关键字可以用来继承类,其实类会被babel编译成函数(也是对象),而对象就有原型链的说法。

什么是原型链

通俗地讲,你创建了一个对象a,然后基于对象a又创建了一个对象b(使用Object.create(obj)),这时访问b的属性,如果b没有这个属性,那么JavaScript会在b的原型中寻找这个属性,而b的原型包含a的所有属性。这样的继承关系可以存在于更多对象间,比如a->b->c从而形成了原型链。

JavaScript中原型链的使用

如何访问原型链

在JavaScript中,每一个对象都有一个__proto__属性,我们可以通过Obj.__proto__访问原型。

构造函数constructor有一个prototype属性,用构造函数创建的对象的__proto__实际上指向了constructor的prototype属性。我们可以通过Object.prototype查看Object的原型对象。

使用Class

Class与extends完全基于原型链。

使用new

用new创建对象时,对象的__proto__会指向构造器的prototype。在JavaScript中,构造器不一定是constructor(),任何一个函数(除箭头函数)都可以成为构造器,因此,只要设置好某个函数的prototype属性,new得到的对象就能使用原型链。

使用Object.create()

该函数的第一个参数就是新对象的原型。

使用JavaScript类型

例如,Array数组的原型链arr -> Array.prototype -> Object.prototype,Function类似。