All posts by dotte

What is a Full Stack developer?

Is it reasonable to expect mere mortals to have mastery over every facet of the development stack? Probably not, but Facebook can ask for it. I was told at OSCON by a Facebook employee that they only hire ‘Full Stack’ developers.  Well, what does that mean?

To me, a Full Stack Developer is someone with familiarity in each layer, if not mastery in many and a genuine interest in all software technology.

Good developers who are familiar with the entire stack know how to make life easier for those around them. This is why I’m so against silos in the work place. Sure, politics and communication challenges get in the way in large organizations. I think the point Facebook is going for with their hiring policy is, if smart people use their heads and their hearts, a better product gets built in less time.

Layers of the Full Stack:

  1. Server, Network, and Hosting Environment.
    1. This involves understanding what can break and why, taking no resource for granted.
    2. Appropriate use of the file system, cloud storage, network resources, and an understanding of data redundancy and availability is necessary.
    3. How does the application scale given the hardware constraints?
    4. What about multi-threading and race conditions? Guess what, you won’t see those on your development machine, but they can and do happen in the real world.
    5. Full stack developers can work side by side with DevOps. The system should provide useful error messages and logging capabilities. DevOps will see the messages before you will, so make them count.
  2. Data Modeling
    1. If the data model is flawed, the business logic and higher layers start to need strange (ugly) code to compensate for corner cases the data model doesn’t cover.
    2. Full stack developers know how to create a reasonably normalized relational model, complete with foreign keys, indexes, views, lookup tables, etc.
    3. Full stack developers are familiar with the concept of non-relational data stores and understand where they shine over relational data stores.
  3. Business Logic
    1. The heart of the value the application provides.
    2. Solid object oriented skills are needed here.
    3. Frameworks might be needed here as well.
  4. API layer / Action Layer / MVC
    1. How the outside world operates against the business logic and data model.
    2. Frameworks at this level should be used heavily.
    3. Full stack developers have the ability to write clear, consistent, simple to use interfaces. The heights to which some APIs are convoluted repel me.
  5. User Interface
    1. Full stack developers: a) understand how to create a readable layout, or b) acknowledge they need help from artists and graphic designers. Either way, implementing a good visual design is key.
    2. Can include mastery of HTML5 / CSS.
    3. JavaScript is the up and coming language of the future and lots of exciting work is being done in the JavaScript world (node, backbone, knockout…)
  6. User Experience
    1. Full stack developers appreciate that users just want things to work.
    2. A good system doesn’t give its users carpal tunnel syndrome or sore eyes. A full stack developer can step back and look at a process that needs 8 clicks and 3 steps, and get it down to one click.
    3. Full stack developers write useful error messages. If something breaks, be apologetic about it. Sometimes programmers inadvertently write error messages that can make people feel stupid.
  7. Understanding what the customer and the business need.
    1. Now we are blurring into the line of architect, but that is too much of a hands off role.
    2. Full stack developers have a grasp of what is going on in the field when the customer uses the software. They also have a grasp of the business.

 

Other Pieces of the Puzzle:

  1. Ability to write quality unit tests. By the way, even JavaScript can have unit tests these days.
  2. Understanding of repeatable automated processes for building the application, testing it, documenting it, and deploying it at scale.
  3. An awareness of security concerns is important, as each layer presents its own possible vulnerabilities.

 

Closing Thoughts:

It is very bad practice to tightly couple code to a specific implementation (library, OS, hardware, etc). Just because a full stack developer understands the entire spectrum doesn’t mean they have license to take shortcuts. Well, actually they do if it is a build and throw away prototype.

Technology start-ups need full stack developers for their versatility!  However, as an organization matures, it needs more and more focused skills.

I’m not sure you can call yourself a full stack developer until you have worked in multiple languages, platforms, and even industries in your professional career. Full stack goes beyond a ‘senior engineer’, as it is along the same lines as a polyglot programmer but with a higher view of all the connecting pieces. Note that on my list, only items 3-5 involve writing code.

from:http://www.laurencegellert.com/2012/08/what-is-a-full-stack-developer/

Functor, Applicative, 以及 Monad 的图片阐释

这是个简单的值:

我们都知道怎么加一个函数应用到这个值上边:

很简单了. 我们来扩展一下, 让任意的值是在一个上下文当中. 现在的情况你可以想象一个可以把值放进去的盒子:

现在你把一个函数应用到这个值的时候, 根据其上下文你会得到不同的结果. 这就是 Functor, Applicative, Monad, Arrow 之类概念的基础. Maybe 数据类型定义了两种相关的上下文:

很快我们会看到对一个 Just a 和一个 Nothing 来说函数应用有何不同. 首先我们来说 Functor!

Functor

当一个值被封装在一个上下文里, 你就不能拿普通函数来应用:

就在这里 fmap 出现了. fmap is from the street, fmap is hip to contexts. fmap 知道怎样将一个函数应用到一个带有上下文的值. 你可以对任何一个类型为 Functor 的类型使用 fmap.

比如说, 想一下你想把 (+3) 应用到 Just 2. 用 fmap:

  > fmap (+3) (Just 2)
Just 5

这是在幕后所发生的:

Bam! fmap 告诉了我们那是怎么做到的!

So then you’re like, 好吧 fmap, 请应用 (+3) 到一个 Nothing?

  > fmap (+3) Nothing
Nothing

就像 Matrix 里的 Morpheus, fmap 就是知道要做什么; 你从 Nothing 开始, 那么你再由 Nothing 结束! fmap 是禅. So now you’re all like, 准确说究竟什么是 Functor? 嗯, Functor 就是任何能用 fmap 操作的数据类型. 因此 Maybe 是个 functor. 而且我们很快会看到, list 也是 functor.

这样上下文存在就有意义了. 比如, 这是在没有 Maybe 的语言里你操作一个数据库记录的方法:

  post = Post.find_by_id(1)
if post
  return post.title
else
  return nil
end

但用 Haskell:

  fmap (getPostTitle) (findPost 1)

如果 findPost 返回一条 post, 我们就通过 getPostTitle 得到了 title. 如果返回的是 Nothing, 我们加e得到 Nothing! 非常简洁, huh? <$>fmap 的中缀表达式版本, 所以你经常是会看到:

  getPostTitle <$> (findPost 1)

另一个例子: 当你把函数应用到 list 时发生了什么?

List 仅仅是另一种让 fmap 以不同方式应用函数的上下文!

Okay, okay, 最后一个例子: 你把一个函数应用到另一个函数时会发生什么?

  fmap (+3) (+1)

这是个函数:

这是一个函数应用到另一个函数上:

结果就是又一个函数!

  > import Control.Applicative
> let foo = (+3) <$> (+2)
> foo 10
15

这就是函数复合! 就是说, f <$> g == f . g!

注意: 目前为止我们做的是将上下文当作是一个容纳值的盒子. But sometimes the box analogy wears a little thin. 特别要记住: 盒子是有效的记忆图像, 然呵又是你并没有盒子. 有时你的 “盒子” 是个函数.

Applicative

Applicative 把这带到了一个新的层次. 借助 applicative, 我们的 values 就被封装在了上下文里, 就像 Functor:

而我们的函数也被封装在了上下文里!

Yeah. Let that sink in. Applicative 并不是开玩笑. Control.Applicative 定义了 <*>, 这个函数知道怎样把封装在上下文里的函数应用到封装在上下文里的值:

也就是:

  Just (+3) <*> Just 2 == Just 5

使用 <*> 能带来一些有趣的情形. 比如:

  > [(*2), (+3)] <*> [1, 2, 3]
[2, 4, 6, 4, 5, 6]

这里有一些是你能用 Applicative 做, 而无法用 Functor 做到的. 你怎么才能把需要两个参数的函数应用到两个封装的值上呢?

  > (+) <$> (Just 5)
Just (+5)
> Just (+5) <$> (Just 4)
ERROR ??? WHAT DOES THIS EVEN MEAN WHY IS THE FUNCTION WRAPPED IN A JUST

Applicative:

  > (+) <$> (Just 5)
Just (+5)
> Just (+5) <*> (Just 3)
Just 8

ApplicativeFunctor 推到了一边. “大腕儿用得起任意个参数的函数,” 他说. “用 <$><*> 武装之后, 我可以接受需要任何个未封装的值的函数. 然后我传进一些封装过的值, 再我就得到一个封装的值的输出! AHAHAHAHAH!”

  > (*) <$> Just 5 <*> Just 3
Just 15
An applicative watching a functor apply a function

一 applicative 看着一 functor 应用一函数

还有啦! 有一个叫做 liftA2 的函数也做一样的事:

  > liftA2 (*) (Just 5) (Just 3)
Just 15

Monad

如何学习 Monad:

  1. 拿个计算机科学的 PhD.
  2. 把她抛在一边, 因为这个章节里你用不到她!

Monads add a new twist.

Functor 应用函数到封装过的值:

Applicative 应用封装过的函数到封装过的值:

Monads 应用会返回封装过的值的函数到封装过的值. Monad 有个 >>= (念做 “bind”) 来做这个.

一起看个例子. Good ol’ Maybe is a monad:

Just a monad hanging out

Just a monad hanging out

假定 half 是仅对偶数可用的函数:

  half x = if even x
           then Just (x `div` 2)
           else Nothing

我们给它传入一个封装过的值会怎样?

我们要用到 >>=, 用来强推我们封装过的值到函数里去. 这是 >>= 的照片:

它怎么起作用的:

  > Just 3 >>= half
Nothing
> Just 4 >>= half
Just 2
> Nothing >>= half
Nothing

其中发生了什么?

如果你传进一个 Nothing 就更简单了:

酷! 我们来看另一个例子: 那个 IO monad:

明确的三个函数. getLine 获取用户输入而不接收参数:

  getLine :: IO String

readFile 接收一个字符串 (文件名) 再返回文件的内容:

  readFile :: FilePath -> IO String

putStrLn 接收一个字符串打印:

  putStrLn :: String -> IO ()

这三个函数接收一个常规的值 (或者不接收值) 返回一个封装过的值. 我们可以用 >>= 把一切串联起来!

  getLine >>= readFile >>= putStrLn

Aw yeah! 我们不需要在取消封装和重新封装 IO monad 的值上浪费时间. >>= 为我们做了那些工作!

Haskell 还为 monad 提供了语法糖, 叫做 do 表达式:

  foo = do
    filename <- getLine
    contents <- readFile filename
    putStrLn contents

结论

  • functor: 通过 fmap 或者 <$> 应用是函数到封装过的值
  • applicative: 通过 <*> 或者 liftA 应用封装过的函数到封装过的值
  • monads: 通过 >>= 或者 liftM 应用会返回封装过的值的函数到封装过的值

所以, 亲爱的朋友 (我想在这点上我们是朋友), 我想我们都一致认为 monad 是简单的而且是个高明的观念(tm). Now that you’ve wet your whistle on this guide, why not pull a Mel Gibson and grab the whole bottle. 看下 LYAH 上关于 Monad 的 章节. 很多东西我其实掩饰了因为 Miran 深入这方面做得很棒.

from:http://jiyinyiyong.github.io/monads-in-pictures/

http://www.ruanyifeng.com/blog/2015/07/monad.html

详解https是如何确保安全的?

Https 介绍

什么是Https

HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL

Https的作用

  • 内容加密 建立一个信息安全通道,来保证数据传输的安全;
  • 身份认证 确认网站的真实性
  • 数据完整性 防止内容被第三方冒充或者篡改

Https的劣势

  • 对数据进行加解密决定了它比http慢

    需要进行非对称的加解密,且需要三次握手。首次连接比较慢点,当然现在也有很多的优化。

出于安全考虑,浏览器不会在本地保存HTTPS缓存。实际上,只要在HTTP头中使用特定命令,HTTPS是可以缓存的。Firefox默认只在内存中缓存HTTPS。但是,只要头命令中有Cache-Control: Public,缓存就会被写到硬盘上。 IE只要http头允许就可以缓存https内容,缓存策略与是否使用HTTPS协议无关。

HTTPS和HTTP的区别

  • https协议需要到CA申请证书。
  • http是超文本传输协议,信息是明文传输;https 则是具有安全性的ssl加密传输协议。
  • http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  • http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

http默认使用80端口,https默认使用443端口

下面就是https的整个架构,现在的https基本都使用TLS了,因为更加安全,所以下图中的SSL应该换为SSL/TLS

https_01

下面就上图中的知识点进行一个大概的介绍。

加解密相关知识

对称加密

对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。
常见的对称加密有:DES(Data Encryption Standard)、AES(Advanced Encryption Standard)、RC4、IDEA

非对称加密

与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey);并且加密密钥和解密密钥是成对出现的。非对称加密算法在加密和解密过程使用了不同的密钥,非对称加密也称为公钥加密,在密钥对中,其中一个密钥是对外公开的,所有人都可以获取到,称为公钥,其中一个密钥是不公开的称为私钥。

非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是 2048 位,意味着待加密内容不能超过 256 个字节。

摘要算法

数字摘要是采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。“数字摘要“是https能确保数据完整性和防篡改的根本原因。

数字签名

数字签名技术就是对“非对称密钥加解密”和“数字摘要“两项技术的应用,它将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
数字签名的过程如下:
明文 --> hash运算 --> 摘要 --> 私钥加密 --> 数字签名

数字签名有两种功效:
一、能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
二、数字签名能确定消息的完整性。

注意:
数字签名只能验证数据的完整性,数据本身是否加密不属于数字签名的控制范围

数字证书

为什么要有数字证书?

对于请求方来说,它怎么能确定它所得到的公钥一定是从目标主机那里发布的,而且没有被篡改过呢?亦或者请求的目标主机本本身就从事窃取用户信息的不正当行为呢?这时候,我们需要有一个权威的值得信赖的第三方机构(一般是由政府审核并授权的机构)来统一对外发放主机机构的公钥,只要请求方这种机构获取公钥,就避免了上述问题的发生。

数字证书的颁发过程

用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息(根证书私钥签名)。用户就可以使用自己的数字证书进行相关的各种活动。数字证书由独立的证书发行机构发布,数字证书各不相同,每种证书可提供不同级别的可信度。

证书包含哪些内容

  • 证书颁发机构的名称
  • 证书本身的数字签名
  • 证书持有者公钥
  • 证书签名用到的Hash算法

验证证书的有效性

浏览器默认都会内置CA根证书,其中根证书包含了CA的公钥

  1. 证书颁发的机构是伪造的:浏览器不认识,直接认为是危险证书
  2. 证书颁发的机构是确实存在的,于是根据CA名,找到对应内置的CA根证书、CA的公钥。用CA的公钥,对伪造的证书的摘要进行解密,发现解不了,认为是危险证书。
  3. 对于篡改的证书,使用CA的公钥对数字签名进行解密得到摘要A,然后再根据签名的Hash算法计算出证书的摘要B,对比A与B,若相等则正常,若不相等则是被篡改过的。
  4. 证书可在其过期前被吊销,通常情况是该证书的私钥已经失密。较新的浏览器如Chrome、Firefox、Opera和Internet Explorer都实现了在线证书状态协议(OCSP)以排除这种情形:浏览器将网站提供的证书的序列号通过OCSP发送给证书颁发机构,后者会告诉浏览器证书是否还是有效的。

1、2点是对伪造证书进行的,3是对于篡改后的证书验证,4是对于过期失效的验证。

SSL 与 TLS

SSL (Secure Socket Layer,安全套接字层)

SSL为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取,当前为3.0版本。

SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

TLS (Transport Layer Security,传输层安全协议)

用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。

SSL/TLS协议作用:

  • 认证用户和服务器,确保数据发送到正确的客户机和服务器;
  • 加密数据以防止数据中途被窃取;
  • 维护数据的完整性,确保数据在传输过程中不被改变。

TLS比SSL的优势

  1. 对于消息认证使用密钥散列法:TLS 使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络(如因特网)上传送时,该代码确保记录不会被变更。SSLv3.0还提供键控消息认证,但HMAC比SSLv3.0使用的(消息认证代码)MAC 功能更安全。
  2. 增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。
  3. 改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。
  4. 一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。
  5. 特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。

SSL、TLS的握手过程

SSL与TLS握手整个过程如下图所示,下面会详细介绍每一步的具体内容:

https握手流程图

客户端首次发出请求

由于客户端(如浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。在TLS握手阶段,客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret 。

客户端需要提供如下信息:

  • 支持的协议版本,比如TLS 1.0版
  • 一个客户端生成的随机数,稍后用于生成”对话密钥”
  • 支持的加密方法,比如RSA公钥加密
  • 支持的压缩方法

服务端首次回应

服务端在接收到客户端的Client Hello之后,服务端需要确定加密协议的版本,以及加密的算法,然后也生成一个随机数,以及将自己的证书发送给客户端一并发送给客户端,这里的随机数是整个过程的第二个随机数。

服务端需要提供的信息:

  • 协议的版本
  • 加密的算法
  • 随机数
  • 服务器证书

客户端再次回应

客户端首先会对服务器下发的证书进行验证,验证通过之后,则会继续下面的操作,客户端再次产生一个随机数(第三个随机数),然后使用服务器证书中的公钥进行加密,以及放一个ChangeCipherSpec消息即编码改变的消息,还有整个前面所有消息的hash值,进行服务器验证,然后用新秘钥加密一段数据一并发送到服务器,确保正式通信前无误。
客户端使用前面的两个随机数以及刚刚新生成的新随机数,使用与服务器确定的加密算法,生成一个Session Secret。

ChangeCipherSpec
ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。

服务器再次响应

服务端在接收到客户端传过来的第三个随机数的 加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成秘钥,一切准备好之后,也会给客户端发送一个 ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了。之后,服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。

后续客户端与服务器间通信

确定秘钥之后,服务器与客户端之间就会通过商定的秘钥加密消息了,进行通讯了。整个握手过程也就基本完成了。

值得特别提出的是:
SSL协议在握手阶段使用的是非对称加密,在传输阶段使用的是对称加密,也就是说在SSL上传送的数据是使用对称密钥加密的!因为非对称加密的速度缓慢,耗费资源。其实当客户端和主机使用非对称加密方式建立连接后,客户端和主机已经决定好了在传输过程使用的对称加密算法和关键的对称加密密钥,由于这个过程本身是安全可靠的,也即对称加密密钥是不可能被窃取盗用的,因此,保证了在传输过程中对数据进行对称加密也是安全可靠的,因为除了客户端和主机之外,不可能有第三方窃取并解密出对称加密密钥!如果有人窃听通信,他可以知道双方选择的加密方法,以及三个随机数中的两个。整个通话的安全,只取决于第三个随机数(Premaster secret)能不能被破解。

其他补充

对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出 Cerficate Request 消息,要求客户端发送证书对客户端的合法性进行验证。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。

PreMaster secret前两个字节是TLS的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在Client Hello阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。所以,服务端需要对密文中解密出来对的PreMaster版本号跟之前Client Hello阶段的版本号进行对比,如果版本号变低,则说明被串改,则立即停止发送任何消息。

session的恢复

有两种方法可以恢复原来的session:一种叫做session ID,另一种叫做session ticket。

session ID

session ID的思想很简单,就是每一次对话都有一个编号(session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的”对话密钥”,而不必重新生成一把。

session ID是目前所有浏览器都支持的方法,但是它的缺点在于session ID往往只保留在一台服务器上。所以,如果客户端的请求发到另一台服务器,就无法恢复对话

session ticket

客户端发送一个服务器在上一次对话中发送过来的session ticket。这个session ticket是加密的,只有服务器才能解密,其中包括本次对话的主要信息,比如对话密钥和加密方法。当服务器收到session ticket以后,解密后就不必重新生成对话密钥了。

目前只有Firefox和Chrome浏览器支持。

总结

https实际就是在TCP层与http层之间加入了SSL/TLS来为上层的安全保驾护航,主要用到对称加密、非对称加密、证书,等技术进行客户端与服务器的数据加密传输,最终达到保证整个通信的安全性。

参考文章
数字证书的基础知识
HTTPS科普扫盲帖
和安全有关的那些事
OpenSSL 与 SSL 数字证书概念贴
基于OpenSSL自建CA和颁发SSL证书
聊聊HTTPS和SSL/TLS协议
SSL/TLS协议运行机制的概述
图解SSL/TLS协议
大型网站的 HTTPS 实践
SSL/TLS原理详解
扒一扒HTTPS网站的内幕
白话解释 OSI模型,TLS/SSL 及 HTTPS
OpenSSL HeartBleed漏洞原理漫画图解

 

简单来说,HTTPS的握手过程就是使用非对称加密的通信过程在客户端和服务端之间协商出一个基于随机数的对称加密密钥,之后的通信过程使用该密钥进行对称加密通信

from:http://www.wxtlife.com/2016/03/27/%E8%AF%A6%E8%A7%A3https%E6%98%AF%E5%A6%82%E4%BD%95%E7%A1%AE%E4%BF%9D%E5%AE%89%E5%85%A8%E7%9A%84%EF%BC%9F/

科普:量子计算机是这样计算的

导读:AlphaGo大战李世石,最终以4:1击败李世石。计算机击败了人类已成事实,不用怀疑。当你知道量子计算机就是为“优化”问题而诞生时,你就会懂得这个结果将是必然。但是我们看到,部分媒体一知半解,过分渲染了量子计算机的能力,片面解读了它的计算优势。当您看了这两篇D-Wave公司的文章,您就会明白:什么是量子计算机、它是如何实现和工作的、它长得什么样、解决什么类型的问题等……D-Wave系统公司,是世界上第一个量产量子计算机的公司,堪称量子计算机的鼻祖。本文及下一篇文章都是翻译他们写的科普文章《量子计算入门》和《D-Wave量子计算机硬件介绍》,李电匠在此逐段逐段的翻译整合如下,之前的分开翻译的部分,请进入历史消息中查找。李电匠只有国家四级的英语水平,不当之处,敬请谅解!

本教程是想介绍量子计算中的概念和术语、提供一个量子计算机大致概念以及为何您可能会想去弄一个。这里的材料是用非常高阶的概念写的,目的是让那些有工科背景和无工科背景的观众比较容易理解。若您有物理、数学、编程方面的背景,则对您理解本文中的概念是有帮助的,但这并不是硬性要求。跟着本入门的阅读,您将学到:

1:量子物理是如何给了我们一种新的计算方式

2:量子计算和古典计算的相似性和差异性

3:量子计算的基本单元是如何用来解决难题的

4:为什么量子计算同样适用于人工智能、机器自学应用以及量子计算机可能会用作人工智能的协处理器

第一节

1.1 – 传统计算机原理

为了理解量子计算,我们先来了解一下传统计算机原理是有帮助的。我们采用了现代数字化计算机和它们的能力去执行大量不同的软件应用,比如,我们的台式机,笔记本和智能手机可以运行电子表格、流媒体视频、允许我们和世界另一端的人聊天以及让我们沉浸在栩栩如生的3D场景中。但是对于这些数字化计算机的核心来说,他们都有共同点:他们都是执行简单算法操作,他们的计算能力取决于能做这些事情的计算速度的极大值。电脑美妙执行数十亿条指令。这些指令执行的如此迅速以便于电脑可以允许我们运行非常复杂的高级软件。传统电脑的原理总体来说可以用图1来表示

科普:量子计算机是这样计算的

图1,传统电脑中的数据流

尽管在许多领域中传统电脑很好的解决了很多问题,但在某些领域中使用传统电脑进行计算看起来非常困难。比如这些领域:图像识别、自然语言(让电脑理解我们人类所说的话而不是编程语言)、必须让电脑先学习相关经验才有能力处理的某些特殊的任务。甚至有些是在过去几十年已经投入大量努力和研究到某个领域,但我们在这个领域的进展还是很慢的,我们不得不去使用大量超级计算机去运算,消耗着大量的能源和空间。

我们可能会问:难道这世上没有其他设计计算机系统的方式吗?如果我们可以从挠头思考开始,做些完全不同的,使得计算效果在传统电脑发现很难的领域有较大的改进。那么我们怎样才能重新构建一种新类型的电脑呢?

1.2 – 一种新的计算方式

相对于将0和1组成的比特流转换成其他比特流的传统计算操作,量子计算是一种截然不同的计算方式。在量子计算中,一切都是变化的,不管是从我们经常理解信息比特的物理层还是操作他们的设备都完全不同。我们制造这种设备的方法是不同的,需要新材料、新的设计规则和新的处理器架构。最终,我们编写这些系统的方法也完全不同。本文将揭露这些问题的源头,也就是如何将传统的二进制0和1的信息表达方式替换成新的信息表达方式“qubit”(Q比特),这样才能改变我们对计算本身的思考方式。

1.3 – 电灯开关游戏

在了解量子计算之前,我们需要深刻理解为什么我们不能用传统数字计算机去解决某些问题。让我们思考这样一个数学问题去勾勒这一点,我们称之为电灯开关游戏。

电灯开关游戏涉及试图在一堆开关中寻找最好的设置。这里的一张图举例介绍这个问题:

科普:量子计算机是这样计算的

图二,电灯开关游戏

让我们想象一下,每一个灯的开关有一个数字跟它紧密相关,是给你备选的的(你不要去改变这个)。我们叫这个数字是“偏差值”。你要做的是:对每一个灯的开关打开或者关闭进行选择。在我们的游戏中,打开表示1,关闭表示-1。我们紧接着把所有开关的偏差值乘以对应的打开/关闭的值。这将会产生一个结果。这个游戏的本意是设置所有开关打开关闭状态以求得最小值。在数学上,我们把每隔开关的偏差值定义为hi,开关设定称为Si

科普:量子计算机是这样计算的

图三,玩电灯开关游戏,把每个开关的偏差值乘以他们的设定值(你必须选)后加总。

根据哪个开关是打开以及哪个开关是关闭的,我们将得到不同的分数。您可以试一下这个游戏。希望您能很轻松地找到,因为这有一个简单规则可以成功:

科普:量子计算机是这样计算的

图四,请为这个开关设置的特殊“猜想”作答

我们发现如果我们设置所有带正偏差值的开关为关闭,将负偏差值的开关打开,然后再加总,我们将得到最小的一个值。容易吧?我可以给你无穷多个不同偏差值的开关,而你只用看把这些开关按这个规则打开关闭即可。

好,我们让这个问题更难一些。请想像一下有很多“对”开关有附加规则,这里的一是“一对”而不是一个开关。我们增加一个新的偏差值J,把两个开关的设定值相乘后与J相乘,我们把这样的规则用于每一对开关后的结果和之前的结果加总。还是一样,我们需要做的是,如何选择开关状态打开或关闭以适应这个新规则。

科普:量子计算机是这样计算的

图五,增加附加规则让开关游戏的难度取决于开关“对”数

但现在这个是非常、非常难以决定到底是哪个个开关应该打开或者关闭了,因为邻居会影响它。甚至简化到如前图只有两个开关的情况,您仍不能使用之前的规则,也就是根据偏差值设置他们为负数。(您试试)在所有开关都有邻居的复杂网络面前,这一下子要找出正确的组合让你得到最小值,就变得非常沮丧了。

科普:量子计算机是这样计算的

图六,电灯开关游戏,带有附加规则,产生一张互相作用的电灯开关网

1.4 – 那么量子机制怎么帮我们?

每一对开关你若尝试所有组合,有四种可能性:

[开,开],[开,关],[关,开],[关,关]。

但随着您增加越来越多的开关数量,这种可能性的数量将随着开关数量呈指数增长:

科普:量子计算机是这样计算的

图7,电灯开关游戏带来的指数问题

您应该明白为什么这个游戏不再好玩了。实际上这个问题甚至对于大多数强大的超级计算机来说都很困难。要把这么多可能的配置存进内存,并把他们送进传统处理器,去计算我们的猜测是否正确的话,那将花费非常长的时间。假设500个开关,宇宙都没有足够的时间去检查所有的配置。

量子机制可以给我们此问题的好帮手。量子计算机的基础计算能力来源于一种想法,也就是您可以将信息比特放进状态中的叠加态。您可以想象成这么一种情况,量子比特还没有决定它将成为那种状态。有人喜欢把这种叠加态看作“同时拥有两种状态”。或者你也可以把量子比特的状态看作未决定是选+1还是-1。这意味着如果使用量子计算机,我们的电灯开关将能同时打开和关闭。

科普:量子计算机是这样计算的

图8:量子机制的信息比特(Q比特)可以存在于已知的叠加态中,这个叠加态并没有选择到底是变成+1或是-1(换句话讲,您可以认为它即是+1又是-1)

现在来看一下和之前同样数目的开关群,但现在送入量子计算机的内存(注意那个偏差值还没有加上去)

科普:量子计算机是这样计算的

图9,一个由叠加态下的量子比特组成的网,答案就在这里的某处!

由于所有的电灯开关都是同时打开并且关闭,我们知道正确答案(正确的打开关闭每一个开关)就在什么地方摆着呢,它只是现在还躲着我们。但也没问题,因为量子机制将把它给我们找出来。D-Wave量子计算机允许您用一种这样的“量子表述”并提取出获得最小值的开关打开关闭的配置。下面就是它的工作原理:

科普:量子计算机是这样计算的

图10,计算机采用叠加态比特开始计算,结束时产生传统常态比特流,并沿此方式找到答案

你启动了如前所述的量子叠加态下的系统,您慢慢的调节量子计算机去关闭量子叠加效应。同时,你慢慢调高所有的偏差值(H,J的要先调)。当这个操作执行了,所有开关会慢慢跳出他们的叠加态并选择一个状态不管是打开还是关闭。当您把他们加总的时候,内部采用量子机制工作的电脑帮助开关设置到正确的状态以获得最小值。尽管N个开关可能产生2的N次方个可能性配置,它也能在结束的时候发现最小值,赢得电灯开关游戏。所以,我们可以知道量子计算机允许我们精简表达式,就像这种我们研究的:

\[ E(s) = \sum_i h_i s_i + J_{ij}s_i s_j \]

但对于传统计算机又是非常困难的(或者说不可能完成)

第二节

2.1 这是个数学公式,谁关心啊?

我们从来不会制造一个机器用来玩某种奇怪变态的电灯开关游戏。日常生活中,我们曾经遇到许多应用程式的核心问题,其本质是在一对变量中(比如开关)寻找一个最佳组合。一部分我们列举如下。甚至科学探索本身就是一种优化问题。(你们试图寻找最佳要素“配置”,以使得科学公式能够和真实世界的观测一致)

科普:量子计算机是这样计算的

图11,举的这些例子都是在寻找良好的“开关设置”,并可以非常有效的被量子计算机处理。

2.2 能量程序

为了理解这些问题是如何被映射成寻找开关设置的,让我们看看量子计算机是如何被编程的。回到前面的图1,在比特流通过逻辑程序的应用软件转换成其他比特流的那个过程,我们现在用一种不确定是“-1”还是“1”的东西去代替,因此计算方式从最基础的方式上就不一样了,如图12所示。在这种情况下,一组Q比特被初始化进入叠加态,此时“能量程序”(取代逻辑程序)开始作用于这组Q比特。Q比特在计算的开始时一种未决定的状态,在计算结束时所有的Q比特都已经做出了选择,不论这种选择是-1还是1。那么什么是能量程序呢?其实就是H和J的数值啦,我们之前说的偏移量设置。在电灯开关游戏中,我们说H和J是给定的。我们现在知道了,H和J其实是来自您想解决的问题,并因为问题不同而不同。

科普:量子计算机是这样计算的

图12,量子计算机最基础的操作就是支持能量程序(一组H和J的数字)

并让计算机寻找开关设置(+1和-1)

精巧制作一个能量程序或者说构造出一系列的H和J的值,用来解析您真正关心的实际问题,是极端困难和花费时间的。这基本上等同于在您的电脑内部通过发送机器码到微处理器给您的电脑编程一样!幸运的是,这有一个比较好的方式,即通过量子编译器去编写量子计算机程序。这种过程的细节解释,参见“Programming with D-Wave”白皮书。

2.3 量子计算机会学习

教会电脑知道现实问题的原因并从经验中学习的方法就叫做机器学习。这是人工智能的一个分支。我们所写的大部分代码都是完全静态的,也就是说,给定新的数据,它将不断地重复执行相同的计算并且犯同样的错误。使用机器学习,我们可以设计自我修正的程序。这种程序还可以学习采用新的方法去处理一小段数据,甚至这些数据机器从来就没见过。在D-Wave硬件上运行很好的程式都是需要在不确定条件下学习和做出决定的程序。举个例子,假设让电脑基于一组之前给它看过的相似物体的图片中识别某个物体。对于遵循严格逻辑原因设计的传统电脑架构来说,这个任务非常困难。如果系统被输入了一张新图,它就很难对这张图进行总体描述。比如“这看起来像个苹果”。D-Wave的处理器是被设计成支持那些拥有高级认知水平和决断能力的应用程序

我们怎样才能使用量子计算机去实现学习呢?举个例子,比如我们想让系统识别物体。为此编写能量程序也是非常困难的,甚至是使用量子编译器也是如此,因为我们不知道在细节上如何能抓住让系统必须认识的物体本质。幸运的是,我们还有另一种方法绕开这个问题。因为这里有一种模式可以让量子计算机根据新输入的数据片段来调整它自己的能量程序。这就允许机器做出比较好的去猜想这个物体到底是什么。甚至这个实例电脑从来没有见过。下面的章节给除了这个过程的大致框架。

2.4 一种可以自我编程的电脑

为了让系统可以改变自己的能量程序,你一开始给系统看很多很多的你想让它知道的概念实例。如图13的例子,这里是想让电脑学习不同类型水果的差异。为了达到这一点,我们展示很多不同的苹果、杨梅、瓜果的图片(或者其他,用数字代表这些图)给系统构思差异。同时,我们每次告诉系统“正确”答案,也就是告知它“开关设置”(标识)在每次量子计算完成后的设置。系统必须找出一个能量程序(我们一开始并不知道,再此显示一个问号),能让系统一看到所示图片,就能找到相关的标识。如果它答错了许多次,那么算法就知道应该需要更改能量程序了。

科普:量子计算机是这样计算的

图13,通过允许它自己改写能量程序教育量子芯片。系统调整能量程序直至每次都能答对。

这就是我们常说的培训或者学习阶段。

一开始系统随机选择一个能量程序(记得吗,就是一堆h和j的值)。他一开始可能选择了错误的标识,不过没关系,我们继续给它看样品,而且每次允许它调整能量程序。那么他将越来越会选择正确的标识(开关设置)。当系统基于之前的数据已经100%准确了,我们就保留最后的能量程序,并用这个能量程序作为我们的“学习”程序去识别一张新的从未见过的样品(图14)。在机器学习术语中,这就是称为强制学习算法。我们不断地示图和告诉正确答案的目的就是为了帮助它学习。当然系统还支持其它类型的学习算法,甚至某些可以在标识数据不可用的情况下使用。

科普:量子计算机是这样计算的

图14,在系统在训练期间发现一个好的能量程序后,它可以标识出从未见过的样品以帮助我们解决现实问题。这就是所谓的“测试”阶段。

2.5 不确定性是一个功能特性

另外有意思的一点就是量子计算机是概率论化的,意思就是它会给出很多个答案,某些是你在寻找的,而某些不是。一开始听到这个,恐怕不是件好事。就像你每次问计算机同一个问题,而计算机每次给你不同的答案一样,这应该是个Bug吧!但是,对于量子计算机来说,返回不同答案意味着我们得到了关于电脑的信心度重要信息。拿上面的水果例子。假设你问它100遍,计算机回答100遍苹果,那么计算机就是100%自信。但如果它回答50遍苹果,50遍杨梅,那就意味着电脑不确定你拿给他看的是什么。但如果你把苹果和杨梅的混合图片给电脑看而得到这种结果的话,那么这个就是完全正确的了。当你要设计一种能够做出复杂决定和从现实生活中学习的系统时,这种不确定性是非常有用的。

from:http://www.techug.com/quantum-computer