从 SSLTLS 的底层实现来看 网络安全的庞大复杂体系
文章目录
- 前言
- 1. HTTP协议通信的问题
- 1.1 tcpdump 抓取http 请求包
- 1.2 报文分析
- 1.3 HTTP 协议问题
- 2. SSL & TLS 协议的基本介绍和历史演进
- 3. TLS 1.2 实现加密传输的过程
- 3.1 TLS HandShake 协议概览
- 3.2 第一次握手:ClientHello
- 3.3 第二次握手:从ServerHello 到 ServerHelloDone
- 3.3.1 ServerHello
- 3.3.2 Server Certificate
- 3.3.3 ServerKeyExchange
- 3.3.4 CertificateRequest
- 3.3.5 ServerHelloDone
- 3.4 第三次握手
- 3.4.1 Client Certificate
- 3.4.2 Client Key Exchange Message
- 3.4.3 Certificate Verify
- 3.4.4 Finished
- 4. 参考文献
前言
近期工作需要接入http 接口到存储引擎,因为公司内网 需要保证内网安全,所有的http请求通信都需要通过 https
,也就是安全的http 协议才行。这个时候,实现的http 接口也就需要支持 SSL & TLS
。这里会产生一些疑惑,http请求和https 请求的本质区别是什么?为什要有https ,也就是SSL & TLS
的出现,他们要解决http 解决不了的什么问题?
这不了解还好,一了解 并深入底层 才发现 SSL
和TLS
的发展史已经接近整个互联网的发展史,他们底层的技术栈已经被作为互联网信息传输的基础,是一个庞大的系统。然后就不得不感叹技术之广之深,习以为常的技术却深藏奥秘 和 互联网的精髓,再看看我这种每天只想做一只只完成工作的咸鱼,相比互联网前沿探索的先辈来说真是自愧不如。
还是回归正题,先做一个SSL & TLS
的笔记记录吧。
本文将从如下几个方面展开:
- 当前http 协议通信的问题?
- SSL & TLS 协议的基本介绍和历史演进?
- 然后从 它们的实现过程 来看 https 如何通过 SSL&TLS 解决http 的问题?
1. HTTP协议通信的问题
互联网是一个开放的环境,任何人持有一个接入网络的终端,都能够去访问其他任何服务器。而终端和服务器之间的通信内容都有可能被其他人看到/截取/修改。我们看看不使用https 通信的情况下,能够看到通信双方都互相接收发送什么内容?
1.1 tcpdump 抓取http 请求包
开启一个终端:
tcpdump tcp port 80 -n -A -s 0
监听通过80端口的所有请求信息。开启另一个终端:通过
curl
发送http请求curl -d "city=dongguan&appkey=8010132dcf54491a4eaa387f4db61774" "http://way.jd.com/he/freeweather"
可以看到这里向url
http://way.jd.com/he/freeweather
发送的是一个post请求,将本地用户的请求信息带着发送给了这个 url。最后会收到远端服务器返回的一个json字符串,表示本地用户的请求结果。
{"code":"10000","charge":false,"msg":"查询成功", \"result":{"HeWeather5":[{"aqi":{"city": \{"aqi":"28","co":"0.5","no2":"18","o3":"87"...
1.2 报文分析
这个时候我们再去 tcpdump 开启的终端看看抓取到的通信的内容。
如下为截取的抓取结果,后面其实还有http 的四次挥手,不过不影响我们分析http 请求。
可以看到很明显的一点,我们通过 http
发送的不安全的请求,在第三方抓包的时候能够看到双方通信的所有内容,也就是明文通信。假如我们是一个登陆网站,那我们post 到远端服务器的个人用户名/密码/其他信息 的所有数据都会被第三方看到,当然看到的话也能够被修改,这对于处于互联网中的个人隐私来说简直是一个灾难。
这个时候,我们把curl
请求的http请求切换为https
,能够看到抓取到的报文信息就看不到用户信息了,基本都是密文。
1.3 HTTP 协议问题
综上,我们能够很明显得看到 http 不加密协议的问题:
- 窃听风险(eavesdropping):第三方可以获知通信内容。
- 篡改风险(tampering): 第三方可以修改通信内容
- 冒充风险(pretending): 第三方可以冒充他人参与通信。
而,加上了HTTPS 即 SSL & TLS
安全协议,为了解决以上是三个风险,我们期望能够达到:
所有信息都是加密传播,第三方无法窃听。
具有校验机制,一旦被篡改,通信双方会立刻发现。
配备身份证书,防止身份被冒充。
第一点的加密传输,我们能够从 tcpdump 的抓包内容中看到这个特性,第二第三点则是SSL & TLS 协议栈背后的通信的细节,我们接下来将描述这个过程。
2. SSL & TLS 协议的基本介绍和历史演进
前面我们说 安全加密通信 都是将SSL
和TLS
放在一起进行描述,SSL(Secure Socket Layer)和 TLS(Transport Layer Security) 都是加密协议,它们从作用上并没有区别,都是为了解决加密传输的问题。事实上,TLS 是 一个 SSL 比较新的版本,TSL 功能上和SSL的区别是为了解决早期 SSL的一些安全性问题。
SSL & TLS 的发展史如下:
- SSL 1.0 – 因为一些安全性问题,从来没有被公开过
- SSL 2.0 – 1995年发布。因为一些安全性问题,在2011年被废弃。
- SSL 3.0 – 1996年发布。因为一些安全性问题,在2015年被废弃。
- TLS 1.0 – 在1999年作为SSL 3.0 升级版本,已经在2020年废弃。
- TLS 1.1 – 在2006年发布,在2020年废弃。
- TLS 1.2 – 2008年发布。
- TLS 1.3 – 2018年发布。
也就是我们现在浏览器 以及 企业内部 的加密通信大多是TLS1.2 版本及以上,后续介绍的SSL & TLS 如何进行安全通信的细节是在TLS1.2
版本之上进行的。
TLS/SSL 的基本加密思路是通过 公钥加密 ,也就是客户端会先向服务端索要 公钥,然后用公钥加密信息,服务端收到信息再通过公钥进行解密。
3. TLS 1.2 实现加密传输的过程
总体介绍一下TLS/SSL 的加密过程如下:
客户端向服务器端索要并验证公钥。
双方协商生成"对话密钥"。
双方采用"对话密钥"进行加密通信。
在TLS 1.2 版本中,整个协议栈由两个协议层组成:TLS record protocol
和 TLS HandShake protocol
,而在这两个TLS 本身的协议层之下则是一些更加可靠的传输协议(TCP这种)。
其中 TSL record protocol
主要有如下两个特性:
- 保证链接是私密的。这一层会对数据进行加密,并且保证用于当前通信的公有密钥是唯一的,也就是只有连接者和服务器知道具体的公钥。
- 保证链接是可靠的。
在上面的协议之下,TLS 还维护了一个 TLS HandShake protoco L
,这个协议是TLS 解决 http 三个主要问题的核心协议,其允许服务器和客户端之间在进行真正的数据传输之前进行互相验证并协商加密算法 和 加密密钥。
接下来我们要详细看一下TLS HandShake protocol
的协议实现过程。
3.1 TLS HandShake 协议概览
TLS 握手协议的步骤主要是如下几步(我们前面用tcpdum 抓到的三次握手):
- 交换Hello Message, 主要进行一些加密算法 的验证 以及 一些伪随机数的交换。
- 交换一些必要的加密参数,来允许客户端和 server 认同 premaster secret的值.
- 交换证书和加密信息 来让客户端和服务端进行互相身份的验证。
- 通过 premaster secret 生成一个master 密钥 和 交换一些随机值。
- 将这一些安装参数提供给 上层的 TLS Record Protocol.
- 允许客户端和服务端在他们本地计算安全参数,从而保证即使有攻击发生,链接请求也不会在客户端或者服务端建立成功。
从服务端和客户端的角度来看,主要有如下几个步骤:
Client ServerClientHello -------->ServerHelloCertificate*ServerKeyExchange*CertificateRequest*<-------- ServerHelloDoneCertificate*ClientKeyExchangeCertificateVerify*[ChangeCipherSpec]Finished -------->[ChangeCipherSpec]<-------- FinishedApplication Data <-------> Application Data
关于底层的HandShake
结构体类型如下:
enum {hello_request(0), client_hello(1), server_hello(2),certificate(11), server_key_exchange (12),certificate_request(13), server_hello_done(14),certificate_verify(15), client_key_exchange(16),finished(20), (255)
} HandshakeType;struct {HandshakeType msg_type; /* handshake type */uint24 length; /* bytes in message */select (HandshakeType) {case hello_request: HelloRequest;case client_hello: ClientHello;case server_hello: ServerHello;case certificate: Certificate;case server_key_exchange: ServerKeyExchange;case certificate_request: CertificateRequest;case server_hello_done: ServerHelloDone;case certificate_verify: CertificateVerify;case client_key_exchange: ClientKeyExchange;case finished: Finished;} body;
} Handshake;
3.2 第一次握手:ClientHello
首先 客户端 和服务器进行第一个的链接的时候会 发送ClientHello 请求到服务器。这个阶段主要是双方交换一些安全属性的信息。
其中ClientHello
的消息结构体如下:
struct {ProtocolVersion client_version;Random random;SessionID session_id;CipherSuite cipher_suites<2..2^16-2>;CompressionMethod compression_methods<1..2^8-1>;select (extensions_present) {case false:struct {};case true:Extension extensions<0..2^16-1>;};
} ClientHello;
结构体内部的成员即是 这个 Request 客户端要发送给服务端的内容,主要包括
client_version
:当前TLS 协议的版本号random
: 一个客户端生成的伪随机数,主要由两部分构成gmt_unix_time
和random_bytes
,当前系统时间和一个28bytes的伪随机数。session_id
: 客户端希望本次链接的标识。Ciper_suites
:表示客户端支持的一些加密方式列表(RSA等)。compression_methods
:一个客户端支持的 压缩方式的列表。
3.3 第二次握手:从ServerHello 到 ServerHelloDone
第二次握手包含五个阶段,主要是服务端的回复内容。
主要的内容如下:
- 确认使用的加密通信版本。如果版本不一致(比如TLS 1.2),则服务器关闭通信功能
- 一个服务器生成的随机数,后续用于生成对话密钥。
- 确认使用的加密方法,比如RSA
- 服务器的认证证书。
- Extensions,类似请求客户端证书,比如某一些企业的请求接入,需要客户端提供企业之前提供过的认证才行。
以上内容主要被以下几个请求依次发送:
3.3.1 ServerHello
这个结构体内容如下:
struct {ProtocolVersion server_version;Random random;SessionID session_id;CipherSuite cipher_suite;CompressionMethod compression_method;select (extensions_present) {case false:struct {};case true:Extension extensions<0..2^16-1>;};
} ServerHello;
server_version
: server 支持的 TLS 协议版本random
: server 会在 client 发送过来的随机数基础上再生成一个随机数。session_id
: 收到client 发送过来的session_id 之后,会从自己的session列表中查找这个id,找到了则直接复用。否则,server的session_id 会直接填充一个新的session_id返回给客户端,与此同时 也会决定使用服务端的加密算法。cipher_suite
: 从客户端发送过来的 加密算法列表中选择一个加密算法。如果前面的session_id 从服务端维护的列表中找到了,则直接复用这个session_id 的加密算法。compression_method
:服务端选择客户端发来的压缩算法列表中的一个。当然,如果复用了session_id,压缩算法同样也会被复用。
3.3.2 Server Certificate
用于发送服务器的认证证书到客户端。再ServerHello 消息发送之后发送,消息结构体如下:
struct {ASN.1Cert certificate_list<0..2^24-1>;
} Certificate;
certificate_list
证书列表。第一个证书必须是发送者的证书。后续的每一个证书必须证明前面的证书是合理的。
同样,如果服务端想要客户端的证书,那客户端发送过来的证书也需要按照这种方式发送。
3.3.3 ServerKeyExchange
在服务端发送了认证证书之后会发送。这个请求发送的原因是 服务端认为自己发送给客户端的认证证书并没有包含足够的数据来允许客户端交换自己的 premaster key。如果使用如下交换密钥算法则客户端会被允许交换:DHE_DSS, DHE_RSA, DH_anon;使用如下交换算法,则客户端不会交换master key:RSA, DH_DSS, DH_RSA。
它的数据结构如下:
struct {select (KeyExchangeAlgorithm) {case dh_anon:ServerDHParams params;case dhe_dss:case dhe_rsa:ServerDHParams params;digitally-signed struct {opaque client_random[32];opaque server_random[32];ServerDHParams params;} signed_params;case rsa:case dh_dss:case dh_rsa:struct {} ;/* message is omitted for rsa, dh_dss, and dh_rsa *//* may be extended, e.g., for ECDH -- see [TLSECC] */};
} ServerKeyExchange;
param
: 服务器key的交换参数
主要包含一些交换算法:enum { dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa/* may be extended, e.g., for ECDH -- see [TLSECC] */} KeyExchangeAlgorithm;struct {opaque dh_p<1..2^16-1>;opaque dh_g<1..2^16-1>;opaque dh_Ys<1..2^16-1>; } ServerDHParams; /* Ephemeral DH parameters */
signed_params
: 对于非匿名密钥的交换,服务器会附加这个参数,标识自己(非匿名密钥 太了解)
3.3.4 CertificateRequest
对于非匿名服务器(企业认证的服务器)来说,会为注册用户发送一个客户端证书,注册用户接入的时候服务端也会请求客户端的认证证书。也就是整体描述 从ServerHello 到 ServerHelloDone 内容的第五段消息。
消息结构体如下:
struct {ClientCertificateType certificate_types<1..2^8-1>;SignatureAndHashAlgorithmsupported_signature_algorithms<2^16-1>;DistinguishedName certificate_authorities<0..2^16-1>;
} CertificateRequest;
certificate_types
服务端为客户端提供的认证证书类型列表enum {rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),fortezza_dms_RESERVED(20), (255) } ClientCertificateType;
supported_signature_algorithms
, 服务端支持的签名/hash 验证算法的列表certificate_authorities
可信的出版证书机构的名称。
3.3.5 ServerHelloDone
服务端在前面的消息发送完成之后会发送这个消息,表示服务端的消息已经发送完毕,客户端可以进行证书校验 以及 判断是否能够接受服务端的公钥,而服务端则会等待客户端的回复。
3.4 第三次握手
客户端校验服务端的认证证书,如果证书不是可信的机构颁布 或者 证书中的域名与实际的域名不匹配,或者证书已经过期,就会向客户端显示一个告警,由客户端选择是否继续访问。
如果证书没有问题,客户端就会从证书中取出服务端的公钥,向服务端发送如下内容:
- 一个随机数。该随机数用服务器公钥加密,防止被窃听。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
- 如果服务端需要客户端提供可信证书,那客户端也需要发送一个认证证书。
这一次握手对应客户端的三个请求,从Client Certificate 到 Finish 。
3.4.1 Client Certificate
这个请求发送的要求是 服务端 请求客户端的认证证书。
证书的格式和服务端的类似。
3.4.2 Client Key Exchange Message
客户端的编码改变通知。这个请求是无论什么时候必须要发送给服务端的。表示客户端任何 和 服务端协商的premaster-key,后续的通信都将通过这个密钥进行。
选择哪一种编码算法取决于服务端ServerKeyExchanged 请求中选择的 交换算法。
消息结构体如下:
struct {select (KeyExchangeAlgorithm) {case rsa:EncryptedPreMasterSecret;case dhe_dss:case dhe_rsa:case dh_dss:case dh_rsa:case dh_anon:ClientDiffieHellmanPublic;} exchange_keys;
} ClientKeyExchange;
3.4.3 Certificate Verify
客户端认证服务端的证书。
struct {digitally-signed struct {opaque handshake_messages[handshake_messages_length];}
} CertificateVerify;
这个结构体中的 handshake_messages 变量引用了从 client hello 到 当前消息之前的所有握手阶段的消息。
3.4.4 Finished
这个完成握手的请求会在客户端的编码改变请求 以及 证书验证请求发送之后发送。Finished 请求是一个被之前握手阶段协商的算法、公钥和对称密钥保护的消息。在这个消息发送完毕收到服务端对客户端Finished 消息回复之后 两者将通过协商后的加密算法进行通信。
再次看看整个https 的三次握手步骤:
Client ServerClientHello -------->ServerHelloCertificate*ServerKeyExchange*CertificateRequest*<-------- ServerHelloDoneCertificate*ClientKeyExchangeCertificateVerify*[ChangeCipherSpec]Finished -------->[ChangeCipherSpec]<-------- FinishedApplication Data <-------> Application Data
可以看到,服务端收到客户端的Finished消息之后,会回复:
- 服务端的编码改变通知,表示后续服务端将使用协商好的对称密钥加密 以及 pre-masterkey 公钥进行解密。
- 服务端结束握手的通知。
之后就是用协商好的加密密钥 进行 应用数据的加解密传输了。
可以看到,在第三次握手结束后,服务端和客户端都拥有了三个随机数(客户端ClientHello生成的,服务端ServerHello生成的,客户端ClientKeyExchangeMessage生成的),这三个随机数能够保证整个加密过程的保密性(密文很难被解析到);同时 认证证书 的存在 也保证了通信的可靠性(也就是为什么不推荐大家访问浏览器报警证书不匹配问题的网站,访问的网站没有使用版本匹配/最新 的证书,无法保证传输数据的保密性)。
4. 参考文献
https://kinsta.com/knowledgebase/tls-vs-ssl/
TLS 1.2 reference detail
相关文章:

UICollectionView
UICollectionView 多列的UITableView,最简单的形式,类似于iBooks中书架的布局,书架中放着你下载的和购买的电子书。 最简单的UICollectionView是一个GridView,可以多列的方式进行展示。 包含三部分,都是UIView的子类: …

Java项目:课程资源管理+在线考试平台(java+SSH+mysql+maven+tomcat)
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能包括: 管理员可以增删改查教材、教材商、入库教材、用户(用 户包括学生和教师)可以对教材商、教材进行。xcel的导入 导出操作。教师可以领取入库的教材,可以退还教…

python twisted 笔记
2019独角兽企业重金招聘Python工程师标准>>> 1.Twisted框架构建简单的C/S 要写一个基于twisted框架的服务器,你要实现事件处理器,它处理诸如一个新的客户端连接、新的数据到达和客户端连接中断等情况。 在Twisted中,你的事件处理器定义在一个…

决策树J48算法
1. J48原理 2. 举例 3. 总结 1. J48原理 基于从上到下的策略,递归的分治策略,选择某个属性放置在根节点,为每个可能的属性值产生一个分支,将实例分成多个子集,每个子集对应一个根节点的分支,然后在每个分支…

分布式系统 一致性模型的介绍 以及 zookeeper的 “线性一致性“ 讨论
文章目录1. 一致性 概览1.1 分布式系统的 “正确性”1.2 线性一致性(Linearizability)1.3 顺序一致性(Sequential consistency)1.4 因果一致性(Casual consistency)1.5 最终一致性(Eventual consistency)2. Zookeeper 的 “线性一致性” 问题3. 参考一致性算是分布式系统的定位…

Java项目:(小程序)全套商城系统(spring+spring mvc+mybatis+layui+微信小程)
源码获取:博客首页 "资源" 里下载! 一、项目简述 本系统功能包括: 商品模块: 商品添加、规格设置,商品上下架等 订单模块: 下单、购物车、支付,发货、收货、评 退款等 营销模块: 积分、优惠券、分销、砍价、拼团、秒 多…

【转】[退役]纪念我的ACM——headacher@XDU
转自:http://hi.baidu.com/headacher/item/5a2ce1d50609091b20e25022 退役了,是时候总结一下我ACM的生涯了。虽然很舍不得,但这段回忆很值得纪念。ACM生涯虽然结束,但是新生活总要继续,还有很多东西需要我去学习&#…

VMware扩大硬盘后修改Linux逻辑卷大小
一、背景随着业务的不断成熟,数据库积累的数据也越来越多了。前些天发现服务器的磁盘将要满了。因此向虚拟化管理员申请增加磁盘空间。由于这个系统是建立在威睿的vSphere平台上的,因此虚拟化管理员只简单地通过 VMware vSphere Client 扩大了磁盘空间&a…

axios与ajax区别
1.jQuery ajax $.ajax({ type: POST, url: url, data: data, dataType: dataType, success: function () {}, error: function () {}});优缺点: 本身是针对MVC的编程,不符合现在前端MVVM的浪潮基于原生的XHR开发,XHR本身的架构不清晰,已经有…

单机 “5千万以上“ 工业级 LRU cache 实现
文章目录前言工业级 LRU Cache1. 基本架构2. 基本操作2.1 insert 操作2.2 高并发下 insert 的一致性/性能 保证2.3 Lookup操作2.4 shard 对 cache Lookup 性能的影响2.4 Erase 操作2.5 内存维护3. 优化前言 近期做了很多 Cache 优化相关的事情,因为对存储引擎较为熟…

Java项目:校园人力人事资源管理系统(java+Springboot+ssm+mysql+jsp+maven)
源码获取:博客首页 "资源" 里下载! 校园人力资源管理系统:学校部门管理,教室管理,学历信息管理,职务,教师职称,奖励,学历,社会关系,工作…

GPS部标平台的架构设计(十)-基于Asp.NET MVC构建GPS部标平台
在当前很多的GPS平台当中,有很多是基于asp.NETsiverlight开发的遗留项目,代码混乱而又难以维护,各种耦合和关联,要命的是界面也没见到比Javascript做的控件有多好看,随着需求的增多,平台已经臃肿不堪。 设计…

关于CSDN不给任何通知强制关闭我的6年博客,我深表痛心
关于CSDN不给任何通知强制关闭我的6年博客,我深表痛心。最近有很长一段时间没有去csdn博客了, 前几天去看的时候发现博客被封闭了。 我联系了管理员,但是没有得到任何回复。 我猜想,可能是不是我在博客文章里面加入 自己网站的网…

Vue 环境搭建(win10)
1.安装node node官网安装地址 推荐安装稳定版本(LTS)以及安装路径为系统盘(C) 查看node安装成功否 注释:以下命令使用 命令提示符(管理员)权限,win10 对user权限的限制了访问权限。node -v 查看…

Java项目:化妆品商城系统(java+Springboot+ssm+mysql+jsp+maven)
源码获取:博客首页 "资源" 里下载! 一、项目简述 本系统主要实现的功能有: 网上商城系统,前台后台管理,用户注册,登录,上架展示,分组展示,搜索,收…

python 绘图脚本系列简单记录
简单记录平时画图用到的python 便捷小脚本 1. 从单个文件输入 绘制坐标系图 #!/usr/bin/python # coding: utf-8 import matplotlib.pyplot as plt import numpy as np import matplotlib as mpl import sysfile_name1 sys.argv[1] data_title sys.argv[2] print(file_name1…

iOS-c语言小练习01
// // main.c // C-变量的地址 // // Created by cgq on 15/4/9. // Copyright (c) 2015年 cgq. All rights reserved. // #include <stdio.h> //访问变量的地址 void test1() { char a A; int b 44; printf("a的值:%d\n",a); pri…

蓝桥杯 【基础练习】 十六进制转八进制
问题描述给定n个十六进制正整数,输出它们对应的八进制数。输入格式输入的第一行为一个正整数n (1<n<10)。接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进…

泛在网:泛在网
ylbtech-泛在网:泛在网泛在网络来源于拉丁语Ubiquitous,从字面上看就是广泛存在的,无所不在的网络。也就是人置身于无所不在的网络之中,实现人在任何时间、地点,使用任何网络与任何人与物的信息交换,基于个…

Mac 从Makefile 编译 Rocksdb 源码的一些注意事项
文章目录前言Makefile 编译流程1. 平台变量/环境变量的初始化。2. 编译需要的源码文件变量初始化。3. include 目录的设置。4. 编译的执行逻辑。问题记录1:可能的打包命令ar 失效问题5. 执行具体的编译指令问题记录2: jar 包编译前言 最近在Mac 本地编译Rocksdb 过…

Java项目:在线考试系统(单选,多选,判断,填空,简答题)(java+Springboot+ssm+mysql+html+maven)
源码获取:博客首页 "资源" 里下载! 功能: 学生信息 班级 专业 学号 姓名 在线考试 成绩查询 个人信息 密码修改 教师管理 教师编号 姓名 所教科目 题库管理 单选题 多选题 填空题 判断题,简答题(人工…

看了极光推送技术原理的几点思考
看了极光推送技术原理的几点思考 分类: android2012-11-26 20:50 16586人阅读 评论(18) 收藏 举报目录(?)[] 移动互联网应用现状 因为手机平台本身、电量、网络流量的限制,移动互联网应用在设计上跟传统 PC 上的应用很大不一样,需要根据手机…

查询远程或本地计算机的登录账户
用下面这个函数能获取远程或本地电脑的当前登录用户,同时附加了它的计算机名,所以当你查询多台电脑时将知道结果从哪里来。function Get-LoggedOnUser {param([String[]]$ComputerName $env:COMPUTERNAME)$ComputerName | ForEach-Object {(quser /SERV…

LIS ZOJ - 4028
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode4028 memset超时 这题竟然是一个差分约束 好吧呢 对于每一个a[i], l < a[i] < r 那么设一个源点s 使 l < a[i] - s < r 是不是就能建边了 然后对于每一个f[i] 如果前面有一个相等的f[j] 则肯定 a[i…

存储引擎 K/V 分离下的index回写问题
前言 近期在做on nvme hash引擎相关的事情,对于非全序的数据集的存储需求,相比于我们传统的LSM或者B-tree的数据结构来说 能够减少很多维护全序上的计算/存储资源。当然我们要保证hash场景下的高写入能力,append-only 还是比较友好的选择。 …

经典贪心法:时间序列问题及其全局最优性证明
贪心算法是指在对问题求解时,总做出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解。一旦贪心算法求出了一个可行解,就要确定这个算法是否找到了最优解。为此,要么证…

Java项目:在线水果商城系统(java+JSP+Spring+SpringMVC +MyBatis+html+mysql)
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能: 区分为管理员用户和普通用户,普通用户:用户注册登录,首页水果展示,商品分类展示,购物车添加,下单&…

曲苑杂坛--收缩数据库文件
很多人在删除大量数据后收缩数据库,却发现没法收缩到预期效果。 由于使用DBCC SHRINKFILE来收缩数据文件时,是针对数据区来收缩,因此可以先使用DBCC SHOWFILESTATS来查看文件中未使用的分区数(TotalExtents-UsedExtents),如果删除…

python字典去重
今天实习的web大表哥说帮我看环境不过前提是要我帮他写个python合并列表的demo,大概思路就是利用zip库进行keys和values的遍历,然后在输出就行key1{name1:小明,name2:小红} key2{小明:[men,20],小红:[women,30]} for k,v in zip(key1.values(),key1.keys()):for i, …

关于 线程模型中经常使用的 __sync_fetch_and_add 原子操作的性能
最近从 kvell 这篇论文中看到一些单机存储引擎的优秀设计,底层存储硬件性能在不远的未来可能不再是主要的性能瓶颈,反而高并发下的CPU可能是软件性能的主要限制。像BPS/AEP/Optane-SSD 等Intel 推出的硬件存储栈已经能够在延时上接近DRAM的量级ÿ…