<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>计算机知识 on lategege 的技术博客</title><link>https://lategege.com/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%9F%A5%E8%AF%86/</link><description>Recent content in 计算机知识 on lategege 的技术博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 08 Apr 2024 03:05:20 +0000</lastBuildDate><atom:link href="https://lategege.com/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%9F%A5%E8%AF%86/index.xml" rel="self" type="application/rss+xml"/><item><title>Next.js 三种网页处理方式</title><link>https://lategege.com/p/next-js-%E4%B8%89%E7%A7%8D%E7%BD%91%E9%A1%B5%E5%A4%84%E7%90%86%E6%96%B9%E5%BC%8F/</link><pubDate>Mon, 08 Apr 2024 03:05:20 +0000</pubDate><guid>https://lategege.com/p/next-js-%E4%B8%89%E7%A7%8D%E7%BD%91%E9%A1%B5%E5%A4%84%E7%90%86%E6%96%B9%E5%BC%8F/</guid><description>&lt;p&gt;我看到很多文章提到Next.js的三种所谓渲染方式，如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;客户端渲染 BSR (Broswer Side Render)&lt;/li&gt;
&lt;li&gt;静态页面生成 SSG (Static Site Generation)&lt;/li&gt;
&lt;li&gt;服务端渲染 SSR (Server Side Render)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我对此不敢苟同，渲染一词随意滥用分明在误导初学者，我们所认知的那个渲染是将图形信息展示到屏幕上，所以何来服务器渲染一说？服务器能控制客户端的GPU、CPU来进行图形绘制？简直瞎搞! Render一词在React框架中根本不是这个意思。React或者Next.js所谓的Render只不过是生成html标记语言，而不是所谓中文意义上的渲染，虽然Render翻译过来是渲染，但是此Render并非GPU那个Render，这一点很重要。如果简单理解为服务器渲染会让初学者觉得非常困惑。&lt;/p&gt;
&lt;p&gt;所以渲染从来都是客户端的事情，和服务端没有任何关系。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;客户端渲染，BSR，它的意思就是客户端自己执行JS去处理完善html,然后由引擎根据html、css来生成dom树，css树，接着才是由cpu或者gpu根据dom树来渲染到屏幕，所谓白屏就是指客户端在载入不完整的带有js脚本的html文件时，下载和加载js所需要的时间，在这段时间内数据还没到达所引发的页面空白，所以&lt;del&gt;客户端渲染&lt;/del&gt;我觉得应该改为客户端加载比较恰当。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;静态页面生成，就是字面意思，客户端请求完整的不带动态请求数据js的静态页面，当然一些交互肯定需要js来处理，所以这里是不带动态请求数据的js。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;del&gt;服务端渲染&lt;/del&gt; 服务器无法渲染页面到屏幕，这个说法严重误导初学者，这里改为服务器加载比较贴切，所谓服务器加载，就是把本来客户端js要干的事情放在了服务端，本来客户端向服务端请求一个不完整的html页面和带有动态请求数据的js，然后加载js请求数据形成完整的html页面，然后渲染。服务器加载就是客户端直接向服务端请求一个完整的html页面，不需要在客户端本地执行js来异步获取数据，相当于html是一步到位的，所谓没有白屏就是因为一步到位而非多次获取带来的效率上面的提升。绝对没有白屏是不现实的，网络必然会有延迟，当你请求html慢的时候你页面必然会loading。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以没有所谓的服务器渲染，如果生成html叫做渲染的话那就太可笑了，html只是一种标记语言，它离渲染差十万八千里！&lt;/p&gt;</description></item><item><title>https协议为什么安全？</title><link>https://lategege.com/p/https%E5%8D%8F%E8%AE%AE%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AE%89%E5%85%A8/</link><pubDate>Sat, 04 Nov 2023 17:07:25 +0000</pubDate><guid>https://lategege.com/p/https%E5%8D%8F%E8%AE%AE%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AE%89%E5%85%A8/</guid><description>&lt;p&gt;现在网络上使用http的网站越来越少了，这很大部分原因要归功于浏览器的强制要求，浏览器强制用户使用https而非http，人们的安全意识也逐渐增强了。&lt;/p&gt;
&lt;p&gt;那么为什么使用https协议是足够安全的呢？&lt;/p&gt;
&lt;p&gt;首先协议的本质，至少站在程序员角度去看，就是一段按照协议要求编写的程序，而且必然是供两端或者多端使用的，要不然不可能会被定义为协议，比如TCP协议，IP协议，ICMP协议，ARP协议等网络相关协议，协议所要解决的本质诉求必然是通信。哪怕是电子电路中的协议也一样，CAN,SPI,I2C,UART,USB等都是解决电路之间通信问题， 蓝牙、wifi、星闪、nfc协议都是解决无线通信问题，http(https)、ftp、smb、ssh等是为了更方便的解决网络通信问题而生。它们的诞生本质就是为了方便，如果把IP,ARP等协议比作钻木取火，那么http(https)就是打火机。&lt;/p&gt;
&lt;p&gt;越原始的协议构造越简单，无论怎么变化，怎么定义，它们都是为了传输数据，既然是传输，就势必会有安全问题，网际传输会经过无数路由和交换机，它们一个个都是快递转运站，谁能保证快递员不拆开包裹来瞧一瞧？http对快递员来说就是一个使用了透明盒子的协议，你里边的数据完全公开，但是用http传输也可以是安全的，那就需要程序员把数据加密后再丢给http协议，对端收到后再解密。那么问题来了，谁能保证密钥安全，加密算法安全，这两个东西泄漏了就和透明没啥两样，特别是CS架构下，客户端若去解密，相当于明文了，代码一览无余。&lt;/p&gt;
&lt;p&gt;https就是为了解决上面的问题而生，其本质就是在数据按照http协议加工之后，在http数据传输之前将数据加密，然后发送，对端在接收之后解密，然后按照http协议解包还原。&lt;/p&gt;
&lt;p&gt;那么加密后一定安全吗？密钥和算法被攻破怎么办？网景公司软件工程师设计https之初肯定也想到了，它们想着只要密钥不被攻破，那么传输就是安全的，还好数学上有一个叫做非对称加密的东西，即使我算法摆给你看，只要你拿不到我的私钥，我们之间的通信就是安全的。&lt;/p&gt;
&lt;p&gt;https最核心的安全实现就是利用了非对称加密，非对称加密的本质是大质数极难分解。由两个因子产生一个公钥和一个私钥，而且他们其中一个加密，另一个可以解密，它们的诞生全都源于这两个因子，你无法从公钥私钥反推两个因子，因为分解难度极高。之所以一个加密，另一个能解密是由于它们具备某些数学特性，可以看做一个黑盒，就是这么神奇地被发现了，没有什么理由，这背后说不定和造物主有关。&lt;/p&gt;
&lt;p&gt;我们把公钥加密，私钥解密称之为对数据进行了非对称加密，而用私钥加密，公钥解密称之为签名验证，这是非对称加密的两种应用。&lt;/p&gt;
&lt;p&gt;https 有了非对称加密后，数据安全是有保证了，但是还要解决一个传输效率问题，因为非对称加密时间复杂度很高，如果传输数据都要使用非对称加密，那https的延迟高的没法用了，所以https采用的办法是引入对称加密，非对称加密RSA只对 对称加密的密钥进行加密，没人能解出对称加密的密钥，那不就是最安全的吗？&lt;/p&gt;
&lt;p&gt;https解决了效率问题，又有一个问题产生了，我作为服务器，我假冒一个银行系统，你登录我的网站，你全程都是用我的公钥和我来通信，你输入的密码在最终会被我的私钥进行解密，虽然互联网上别人没法获取，但是我获取到了，我再利用这个密码去真的银行把钱转走，这就是信任危机。客户端怎么来信任你，这就是签名技术，客户端需要信任这个公钥就是来自官方，怎么做呢？找第三方权威机构呗，权威机构使用它们的私钥对官方的公钥进行加密，也就是签名，我们拿权威机构的公钥来验证官方的公钥，也就是解密。解密失败就是该公钥非法，权威机构的公钥怎么信任呢？那只能信任，权威机构的公钥以证书的形式内置在操作系统中，不信任都没办法。实际的公钥是以证书的形式发送的，证书包含了公钥以及官方的域名、主机、签发时间、有效期等信息，也包含了权威机构的签名信息。&lt;/p&gt;
&lt;p&gt;https解决了信任问题，又产生新问题了，虽然我不知道你的数据是什么，但是我可以修改，当我中间将密文修改再转发给目标，此时服务端必然解密失败，面对这种捣乱的行为确实无解，但这对攻击者也没啥好处，我们假设攻击者恰巧伪造了一段居然能被解开的数据，但却不是原数据，整个事情就是这么凑巧，那面对这种情况需要引入防篡改机制，哈希就是这个用途，在对数据进行对称加密的同时，原数据会做一次哈希摘要，这个摘要连同密文一并发给对端，对端在解密后，还要对原文做一次哈希摘要来和对端发过来的对比是否原文被篡改过，这在安全层面上又添上了一大保障，哈希算法的本质就是将大区间的数据映射到小范围的数，它不可还原，但不同数据所映射形成的数几乎不可能是同一个，因为https所使用的哈希是带密钥的哈希，每次安全链接的哈希密钥都是协商出来的而且不是同一个，这种概率极低极低。如果奇迹真发生了，不同数据产生了同样的哈希值，并且还是同一次连接，那我们说发生了哈希碰撞，但从https应用的角度讲，没有任何影响。&lt;/p&gt;
&lt;p&gt;解决完上述问题后，https诞生了，其流程如下：&lt;/p&gt;
&lt;p&gt;1.客户端和服务端建立TLS连接(期间协商了使用的加密算法，还互送了两个随机数给对方)
2.服务器将证书(包含了公钥、签名、有效期、域名、主机等信息)发给了客户端
3.客户端用系统证书来验证该证书的合法性和有效性。
4.客户端生成一个前置加密密钥，使用商定好的RSA算法对该密钥加密，并将该密钥传给服务器。
5.服务器收到后，解密得到前置加密密钥。两端各自使用该密钥配合前面的随机数生成一个实际密钥，该密钥不是一个，而是四个，分别是客户端加密密钥，服务端加密密钥，客户端哈希密钥钥和服务端哈希密钥。因为两端信息对等，所以算出来的都是一致的。
6.客户端使用客户端对称密钥对原文进行加密，同时对原文进行哈希摘要，将密文和哈希摘要发送给服务端。
7.服务端收到后用用客户端对称密钥进行解密，然后对解密后的数据也做一个哈希摘要，进行比对，来验证来源的可靠性。
8.服务端向客户端通信则使用服务端的密钥，方式同客户端加密一致。&lt;/p&gt;
&lt;p&gt;上述流程保证了https的安全性，在私钥不泄漏的情况下，即使试出了对称密钥和哈希密钥，你也不可能同时算出客户端的和服务端的，就算都算出来，每一次安全通信，随机数不同，密钥也完全不同，你解出来的信息是过时的，所以https的安全性得到了最大的保障。&lt;/p&gt;</description></item><item><title>arm32位指令和芯片外设控制器知识总结</title><link>https://lategege.com/p/arm32%E4%BD%8D%E6%8C%87%E4%BB%A4%E5%92%8C%E8%8A%AF%E7%89%87%E5%A4%96%E8%AE%BE%E6%8E%A7%E5%88%B6%E5%99%A8%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/</link><pubDate>Fri, 25 Nov 2022 09:04:05 +0000</pubDate><guid>https://lategege.com/p/arm32%E4%BD%8D%E6%8C%87%E4%BB%A4%E5%92%8C%E8%8A%AF%E7%89%87%E5%A4%96%E8%AE%BE%E6%8E%A7%E5%88%B6%E5%99%A8%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;32位arm cpu采用流水线设计，分为取址、译码、执行，一条汇编指令对应一条机器码，占用32位 4个字节。32位cpu最大寻址空间为4g，上电默认从0x00000000地址执行。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;一般而言，该地址存放芯片厂商的BL0程序，固化在芯片内部的irom中，一般大小只有几十KB，同时芯片内部还有一个较小的iram内存以供该段程序执行。BL0会获取开发板上的拨码开关状态来决定从SD卡还是EMMC运行，它其实是一条跳转指令B 地址，在SD卡中刷入uboot引导，uboot是二进制程序，是cpu能够直接运行的一个精简系统，它支持用户终端输入、文件系统、多种网络协议。由于它支持终端输入，所以可配置环境变量来引导linux内核，linux内核也是一段二进制程序，它通过和设备树结合来运行，运行后挂载根文件系统进入shell环境。根文件系统是一个包含很多工具已经内核配置以及众多库的一个文件列表。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;ARM 处理器共有 7 种不同的处理器模式：&lt;br/&gt;（1）USR（10000）：正常用户模式，程序正常执行模式。&lt;br/&gt;（2）FIQ（10001）：快速中断模式，以处理快速情况，支持高速数据传输或通道处理。&lt;br/&gt;（3）IRQ（10010）：外部中断模式，普通中断处理&lt;br/&gt;（4）SVC（10011）：操作系统保护模式（管理模式），即操作系统使用的特权模式（内核），处理软件中断swi reset&lt;br/&gt;（5）abt（10111）：数据访问中止模式，用于 虚拟存储器 和 存储器 保护&lt;br/&gt;（6）und（11011）：未定义指令终止模式，用于支持通过软件仿真硬件的协处理器&lt;br/&gt;（7）sys（11111）：系统模式，用于运行特权级的操作系统任务（ armv4 以上版本才具有）&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;在不同模式下，寄存器有的共用，有的有独立寄存器，见下图。&lt;br/&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large"&gt;&lt;img alt="" src="https://img.lategege.com:30443/images/web/2022/11-25/1.png"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;CPSR寄存器前面几位记录了cpu运算过程中发生溢出等，后面几位代表IRQ、FIQ中断的开启与否，指令集状态为thumb还是arm状态，以及arm处于具体的工作模式。IRQ和FIQ都是硬件中断，不过它们的优先级不同，SWI为软中断。当中断发生时，cpu会跳转到异常向量表，这个向量表默认为0x00 -0xXX ，每一种模式占向量表中的4个字节，只能包含一条跳转指令，硬件与cpu之间是通过中断控制器来处理中断的，中断控制器中有一个中断队列，负责管理中断，同时中断控制器包含所有外设的中断ID,当发生中断后，cpu处理中断过程中可以通过读取中断控制器中的id获知是哪个硬件产生的中断，从来处理逻辑。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;R15也就是PC寄存器，PC寄存器永远指向当前要执行的指令，R13也就是LR寄存器，指向跳转后返回需要执行的指令。如果有多级跳转，那么需要将数值压栈。指令的跳转一般伴随着寄存器存储值的入栈和出栈，当返回后不至于数据丢失。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;当CPU处于用户模式下，没有权限修改CPSR，所以CPU改变模式意味着发生中断，或者发生错误。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;FIQ的优先级优于IRQ，同时FIQ在异常向量表中的地址处于最末尾，后面可以紧跟一段程序，免去了跳转指令，同时FIQ模式下R8-R12都有它独立的寄存器，使用这些寄存器不需要出入栈，使得FIQ的运行速度更快。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;ARM最常用汇编指令：MOV 将值移入寄存器， LD开头 从内存载入寄存器 ST开头 从寄存器存入内存 B开头 跳转 SUB 减法 ADD 加法 M开头 协处理器 SWI 软中断指令 &lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;片内外设控制器：&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;GPIO 负责通用的输入输出，UART 串口 一般由两个线(TD、RD）它用来点对点通信，串口通过波特率来保证两段同步，串口最多每次发5-8位数据，发送之前要发送开始信号，结束要发送结束信号。WDT 开门狗 :本质是一个倒计时硬件，倒计时结束(意味着发生cpu错误)产生cpu复位，cpu需要时不时通知修改WDT的倒计时保证不归零，开门狗也可用来作为定时器，ADC 模数转换器，可用来监测电压的变化，RTC 时钟：一个具备统计当前时间的控制器，以BCD格式存储，一般由备用电池供电来保证断电后时间的准确性，PWM：能发出脉冲信号的控制器，用于无源蜂鸣器发声。IIC总线，芯片级通信协议，由SCL\SDA两条线构成，IIC默认情况下两条线都是高电平，SCL下降沿代表发送，上升沿代表结束。IIC是主从结构，初次发送一位开启位占领总线，然后发送7位地址信息以及发送方向，接收方发送应答，发送方发送数据，接收方发应答，发送方发结束信号，IIC是半双工通信协议。SPI: spi也是一种总线协议，它由多条线组成，时钟线、主-从线，从-主线、CS线，CS线有多少个从设备，主设备就要引出多少条CS线，CS线同一时间只有一条线的电平保持通信中该有的电平，时钟线保证数据同步收发，它是全双工的通信，所以它比IIC速度快。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item><item><title>音视频知识总结</title><link>https://lategege.com/p/%E9%9F%B3%E8%A7%86%E9%A2%91%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/</link><pubDate>Sat, 02 Apr 2022 04:29:52 +0000</pubDate><guid>https://lategege.com/p/%E9%9F%B3%E8%A7%86%E9%A2%91%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;一、常见的流媒体文件.mp4 .mkv .avi .flv都是音视频封装格式，这些封装格式由视频流、音频流、参数信息组成。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;二、原始音频数据是PCM数据，音频原始数据在计算机中的计算方式为采样率*位深*声道数，采样率单位赫兹(HZ)，指每秒钟对声音的采集次数，位深表示单个采样声音的精度或者声音强度范围，当位深作为一个值存在的时候所表示的是精度，而作为位深这个概念本身存在的时候表示的是声音的强度范围，比如16bit位深是16个二进制位能表示65535个不同强度的声音信息，就像标尺上有65535个刻度，如果提升到20bit，意味着刻度数增加。刻度数增加意味着可以使原有的刻度更精确，或者让刻度的范围变的更广。声道数这个概念本质就是多份声音采集，如果录音时声道数为2，那么录制时就有采集两份音频数据，由此得出PCM原始音频数据占用的内存大小。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;音频压缩分有损压缩和无损压缩，无论哪种压缩方式，最终大小肯定比PCM数据小，无损有AAL、APE、FLAC等，有损压缩有mp3、aac、ogg等。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;其中mp3压缩在高码率128kbps以上的音频中还原度更好，码率是指一秒钟声音的大小是多少位二进制，由于位深和声道基本都是固定的，相当于常量，由此得出，码率越高也意味着采样率越高，码率越低意味着采样率越低，mp3的适合场景是普通音乐文件。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;aac压缩在低码率下表现较好，在视频文件中大多采用这种格式，视频的音频流对声音的要求没有比纯音乐那么高。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;ogg在各种范围的码率下表现都非常好，缺点就是普及度不够，兼容性不行，常用语音视频通话中。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;三、原始视频数据格式为YUV格式，也称YCrCb，Y是亮度分量，U和V是色度分量，Cr表示红色分量与亮度分量的差异，Cb表示蓝色分量与亮度分量的差异，对计算机中对视频数据的算法处理大多都是基于YUV的，诸如H264、H265都是在处理YUV数据，如果要在显示器中显示，必须要转换为RGB数据，因为显示器只认RGB，显示器中一个像素有三个发光点，分别表示红、绿、蓝三种颜色，所有颜色都由这三种颜色组成。从YUV数据转RGB不是固定的算法，而是有多套标准，这也是为什么opengl在将YUV数据渲染到屏幕中需要一个矩阵信息，这个矩阵就是这套标准。YUV有很多名称，如YUV420\YUV420P\YUV444\YUV422\I420\NV21\NV12，无论怎么变化，这些名称都只表示两个维度上YUV数据在计算机中的区别，其中一个维度是YUV三个分量的比例信息，420、21、12字眼的代表4个Y分量共用一个UV分量，422代表两个 Y分量共用一个UV分量，444就表示一个Y使用一个U、一个V，有点类似RGB，但是YUV和RGB不是一个概念，但是他们都是表达的单个像素信息，另一个维度是YUV数据在计算机中的排列方式，其中后面不代P的，在计算机中YUV数值交错存储，带P或者NV开头的表示的是水平存储，意味着计算机中Y先存储，后面放U和V,NV21和NV12的区别就是U在前还是V在前。&lt;strong&gt;&lt;mark class="has-inline-color has-accent-color" style="background-color:rgba(0, 0, 0, 0)"&gt;不管怎么样，他们的区别就是在计算机中的个数比例和数值排列顺序的差异。&lt;/mark&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;大多数视频都是采用420格式数据，也就是YUV比例4:1:1，也就是1个字节的Y+四分之1个字节的U和四分之1字节的V，也就是1.5个字节就表示了一个像素，而对应的RGB数据需要3个字节表示，所以RBG大小是YUV420数据的两倍，相当于YUV舍弃了人眼不敏感的色度信息来"压缩"了像素数据，对于这种"压缩"，因为人眼是感知是弱的，相当于就是变相的无损压缩，但这也不能称之为压缩，因为图像采集的原始数据本身就是YUV格式。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;四、常见的视频压缩算法为h264、h265，谷歌的vp8，vp9，微软的av1，最为常用的是h264、h265压缩算法，h264在软件中的名称为mpeg4/avc，简称avc，h265简称hevc。h264、h265它们是一种标准，是一套算法的集合，因为这些算法比较固定，所以在计算机中设计了独立的芯片dsp，dsp芯片专门负责编码或者解码h264\h265格式的视频，这种解码方式称为硬件解码，黑苹果、黑群晖jellyfin中所谓的硬件加速其实就是调用专用dsp芯片对音视频进行编解码处理，从而不占用cpu资源，除了硬件解码外，h264\h265算法本质就是计算，交给cpu计算称为软解码，软解码会耗费cpu资源，不过cpu性能过剩的今天也变得无所谓了，至于dsp芯片内部工作原理就是编码算法的具体实现，内部就是对一帧一帧的数据进行编码，它编码输出和解码输入的单位为一帧数据。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;h264压缩方式分为帧内压缩和帧间压缩，帧内压缩原理来源于渐变，科学家发现一幅图像相邻像素之间的差异不会很大，也就是相邻像素之间有一定的连续性，它们大多是线性的关系。所以科学家们将一张图片像素进行分组，拆分为一个个小单元，其中有4*4，16*16等像素单元，这些单元称为宏块，基于像素之间色值的连续性，它们将宏块的第一行和第一列像素值保留，宏块其他的值舍弃，同时记录一个向量，向量具有方向，根据向量的方向和第一行第一列的像素值就能推倒出其他像素的信息，这就是基于宏块的帧内压缩原理。也就是一帧可以分为很多个宏块。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;帧间压缩就是在视频中连续的画面中，前一帧和后一帧的宏块大多都是相同的，唯一不同的区别是宏块的位置，所以h264将帧分为i、b、p三种类型的帧，i帧为关键帧，保留了完整的宏块信息，而b帧既要参考前面的i帧，又要参考后面的p帧，它保存的大部分是宏块的位移信息，但也有少部分是宏块的完整信息，而p帧参考的是前面的i帧，也是保存了宏块的唯一信息，从而达到了帧间压缩的效果。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;h264在计算机中编码后的数据除了帧数据还有对帧和视频的描述信息，这些信息也以一帧的形式出现，称为sps和pps，每一个网络帧称之为一个NAL，NAL之间以0x0000001分隔，后面一个字节是NAL的类型，后面就是具体的NAL数据了，由于NAL之间大多数是像素数据，像素数据范围是0-255，所以这种小而多的数据非常适合采用哥伦布编码，哥伦比编码的原理就是在前面补0，前面有几个零表示后面的数据是多少位的，它是一种变长的编码方式。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;h265和h264的有相同的地方，也有不同的地方，相同的是它们都是采用了帧内、帧间预测方式，只不过具体的方式有差异，h265的宏块最大是64*64，所以更具压缩比，但h265同时能保证视频细节更好，h265对色彩差异大和色彩差异小的像素区域分别对待，像素差异大的区域会继续将大的宏块切分，直到最小切分位4*4，同时增加预测方向数目，这样保证了细节又保证了压缩比，帧间预测和h264相同。因为h265对于i帧需要更多的配置信息，所以h265的i帧比h264大，b帧和p帧会比h264小非常多，同样的，h265的网络帧NAL，如sps\pps和h264有很大不同。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;四、音视频通信解决方案主要有两种，一种是以延迟性较高但是支持并发数高的直播技术，以RTMP协议为主，另一种是延迟较低的音视频通话或者音视频会议，以webrtc为主。之所以出现这两种方案，是因为需求不一样，直播面对的是一对N的场景，画面的要求也不高，这种场景适合采用服务器转发技术，而音视频会议是一对一或者几个对几个的问题，注重实时性，所以需要客户端直接连接，采用p2p技术。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;rtmp本身是一个协议，它支持h264\h265\aac等视频编码协议，在其数据上增加了一些协议定义的字节，经服务器流转到各终端，来实现直播，rtmp直播过程为:&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:group --&gt;
&lt;div class="wp-block-group"&gt;&lt;!-- wp:paragraph {"textColor":"accent","fontSize":"small"} --&gt;
&lt;p class="has-accent-color has-text-color has-small-font-size"&gt;1、服务端开启RTMP服务&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph {"textColor":"accent","fontSize":"small"} --&gt;
&lt;p class="has-accent-color has-text-color has-small-font-size"&gt;2、直播推流客户端采集音视频数据--&amp;gt;编码成h264\aac数据--&amp;gt;本地预览的同时编码成RTMP包数据--&amp;gt;发送给RTMP服务器&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph {"textColor":"accent","fontSize":"small"} --&gt;
&lt;p class="has-accent-color has-text-color has-small-font-size"&gt;3、直播拉流客户端--&amp;gt;拉取RTMP数据-&amp;gt;解成H264数据和aac数据--&amp;gt;解码成YUV和PCM数据--&amp;gt;渲染和播放声音。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;&lt;/div&gt;
&lt;!-- /wp:group --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;webrtc解决方案的核心是p2p互联，所以这种架构下的服务端有两个角色，一个角色是负责前期沟通的信令服务器，还有一个角色是负责打通两端的ice服务器，信令服务器负责房间的创建、负责各端进入离开房间的消息通知，也负责各端之间媒体协商信息的传递(sdp传递)，也就是在媒体协商阶段，各端是没有直接连接的，媒体协商主要对音视频编解码的各种参数达成一致，为后面互通做准备，ice服务器主要负责建立通道，建立通道有前期的各端nat信息的获取(candidate)，通过信令服务器转发，然后建立连接后，通过RTP/RTCP来传输流媒体数据，其中rtcp是控制协议，因为RTP主要基于udp协议，udp协议是不可靠的，所以要rtcp来控制。一个简单的webrtc的流程为:&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:group --&gt;
&lt;div class="wp-block-group"&gt;&lt;!-- wp:paragraph {"textColor":"accent","fontSize":"small"} --&gt;
&lt;p class="has-accent-color has-text-color has-small-font-size"&gt;1、服务端开启信令服务器、ICE服务器&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph {"textColor":"accent","fontSize":"small"} --&gt;
&lt;p class="has-accent-color has-text-color has-small-font-size"&gt;2、客户端A发送加入房间信息到信令服务器--&amp;gt;信令服务器返回加入成功--&amp;gt;客户端创建RTCPeerConnection大总管--&amp;gt;在大总管下配置音视频源信息、音视频编解码器、开启本地预览、配置本地媒体参数信息等--&amp;gt;成功后发送SDP数据--&amp;gt;等待接收其他客户端SDP数据- &amp;gt;收到客户端B的SDP数据--&amp;gt;协商完毕&amp;lt;---&amp;gt;协商过程中通过ice服务器得到icecadiate数据通过信令服务器交换icecadiate--&amp;gt; 建立p2p通道--&amp;gt;通过p2p通道使用rtp\rtcp协议实现音视频通话&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph {"textColor":"accent","fontSize":"small"} --&gt;
&lt;p class="has-accent-color has-text-color has-small-font-size"&gt;3、客户端A发送加入房间信息到信令服务器--&amp;gt;信令服务器返回加入成功--&amp;gt;客户端创建RTCPeerConnection大总管--&amp;gt;在大总管下配置音视频源信息、音视频编解码器、开启本地预览、配置本地媒体参数信息等--&amp;gt;成功后发送SDP数据--&amp;gt;收到客户端A的SDP数据--&amp;gt;协商完毕&amp;lt;---&amp;gt;协商过程中通过ice服务器得到icecadiate数据通过信令服务器交换icecadiate--&amp;gt; 建立p2p通道--&amp;gt;通过p2p通道使用rtp\rtcp协议实现音视频通话&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;&lt;/div&gt;
&lt;!-- /wp:group --&gt;</description></item><item><title>Linux系统各目录说明</title><link>https://lategege.com/p/linux%E7%B3%BB%E7%BB%9F%E5%90%84%E7%9B%AE%E5%BD%95%E8%AF%B4%E6%98%8E/</link><pubDate>Sat, 09 Oct 2021 01:15:43 +0000</pubDate><guid>https://lategege.com/p/linux%E7%B3%BB%E7%BB%9F%E5%90%84%E7%9B%AE%E5%BD%95%E8%AF%B4%E6%98%8E/</guid><description>&lt;!-- wp:image {"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large"&gt;&lt;img alt="" src="https://img.lategege.com:30443/images/web/2022/1-10/1.png"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;/bin,/sbin,/usr/bin,/usr/sbin区别&lt;br/&gt;/ : this is root directory root 用户根目录&lt;br/&gt;/bin : commandsin this dir are all system installed user commands 系统的一些指令&lt;br/&gt;/sbin: commands in this dir are all system installedsuper user commands 超级用户指令系统管理命令，这里存放的是系统管理员使用的管理程序&lt;br/&gt;/usr/bin: usercommands for applications 后期安装的一些软件的运行脚本&lt;br/&gt;/usr/sbin:super user commands for applications 超级用户的一些管理程序&lt;br/&gt;/usr/X11R6/bin: X application user commands&lt;br/&gt;/usr/X11R6/sbin: X application super usercommands&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;Linux中的某些重要的目录：&lt;br/&gt;•主目录：/root、/home/username&lt;br/&gt;•用户可执行文件：/bin、/usr/bin、/usr/local/bin&lt;br/&gt;•系统可执行文件：/sbin、/usr/sbin、/usr/local/sbin&lt;br/&gt;•其他挂载点：/media、/mnt&lt;br/&gt;•配置：/etc&lt;br/&gt;•临时文件：/tmp&lt;br/&gt;•内核和Bootloader：/boot&lt;br/&gt;•服务器数据：/var、/srv&lt;br/&gt;•系统信息：/proc、/sys&lt;br/&gt;•共享库：/lib、/usr/lib、/usr/local/lib&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:code --&gt;
&lt;pre class="wp-block-code"&gt;&lt;code&gt; 每个用户都拥有一个主目录。所有用户的个人文件（配置、数据甚至应用程序）都放在其中。根的主目录为/root。大多数非根主目录包含在/home 树中，通常以用户命名。 重要的二进制位于 /bin（用户二进制）以及 /sbin（系统二进制）中。 不重要的二进制（如图形环境或Office 工具）安装在/usr/bin 和 /usr/sbin中。 进行这种分隔是为了尽可能地缩小根分区。 使用源代码编译的软件通常位于 /usr/local/bin 和/usr/local/sbin中。&lt;/code&gt;&lt;/pre&gt;
&lt;!-- /wp:code --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;/lib&lt;br/&gt;最基本的共享库和内核模块。存放用于启动系统和执行root文件系统的命令的如/bin /sbin的二进制文件的共享库，或者存放32位，或者64位(file命令查看)。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;/lib、 /usr/lib、/usr/local/lib&lt;br/&gt;就是为了隔离32位和64位而设置的不同目录，这种情况下/lib有可能是其符号链接。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;/usr/lib、/usr/local/lib&lt;br/&gt;程序和安装包的库路径。不依赖特定架构的库应该放到/usr/share中而不是这里。应用程序可以自己创建一个单独的子目录并把自己的库放在其中。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;总结&lt;br/&gt;一般情况下，系统自己会匹配应用程序与其应该调用的位数的库。&lt;br/&gt;如果是用于/bin /sbin的库，放置到/lib之中。&lt;br/&gt;如果是用于用户程序或安装包的，放置到/usr/lib或/usr/local/lib*之中。&lt;br/&gt;如果某个库只是特别的用了某个专用程序，而这个程序但并不打算直接被用户或者root调用，应放置到/usr/libexec中。&lt;br/&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item><item><title>Java类加载机制的本质</title><link>https://lategege.com/p/java%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6%E7%9A%84%E6%9C%AC%E8%B4%A8/</link><pubDate>Tue, 17 Aug 2021 06:33:51 +0000</pubDate><guid>https://lategege.com/p/java%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6%E7%9A%84%E6%9C%AC%E8%B4%A8/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;在编程领域，很多名词都非常奇怪，这就非常容易造成软件工程师不少困惑与不解，就像java中的类加载机制，网上成篇大论都谈到一个名词-----双亲委派机制，下面就是类加载的最关键代码。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:preformatted --&gt;
&lt;pre class="wp-block-preformatted"&gt;&lt;code&gt;protected Class&amp;lt;?&amp;gt; loadClass(String name, boolean resolve)
 throws ClassNotFoundException
{
 // First, check if the class has already been loaded
 Class&amp;lt;?&amp;gt; c = findLoadedClass(name);
 if (c == null) {
 try {
 if (parent != null) {
 c = parent.loadClass(name, false);
 } else {
 c = findBootstrapClassOrNull(name);
 }
 } catch (ClassNotFoundException e) {
 // ClassNotFoundException thrown if class not found
 // from the non-null parent class loader
 }
&lt;pre&gt;&lt;code&gt; if (c == null) {
 // If still not found, then invoke findClass in order
 // to find the class.
 c = findClass(name);
 }
 }
 return c;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;!-- /wp:preformatted --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;看到上面的代码，我会想双亲是谁？委派又从何而来？中文虽然博大精深，但是要将双亲委派和这段代码联系起来，未免太牵强。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;这段代码我用一个例子来说明：&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-cyan-blue-color"&gt;一、儿子在家找身份证，先看了看自己周围有没有，如果没有，就打电话找他爸问问。&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-cyan-blue-color"&gt;二、儿子发现他周围没有，然后打电话问他爸爸，说爸爸，看见我的身份证了吗？&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-cyan-blue-color"&gt;三、爸爸在他自己周边找了一圈，没有发现，爸爸就打电话给了爷爷。&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-cyan-blue-color"&gt;四、爷爷在他边上翻找了一圈，也没有发现，爷爷觉得这可不行，我得仔细找找，爷爷去自己的房间找了一圈没有发现，他就只能和孙子的爸爸说没找到。&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-cyan-blue-color"&gt;五、无奈的爸爸只能去他自己的房间找了一圈，最终也没找到，他就训斥孩子，身份证是你自己的，又不是别人的，你自己想办法。&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-cyan-blue-color"&gt;六、儿子无奈地回了房间，发现身份证就在他自己的房间。&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;strong&gt;这个故事虽然有点假，但是已经将java类加载机制通过叙事的手段说清楚了。&lt;/strong&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;儿子就是AppClassLoader. 爸爸就是ExtClassLoader 爷爷就是BootStrapClassLoader&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;身份证就是要加载的类，儿子的周边就是他自己的缓存空间，儿子的房间是属于他管理类加载路径&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;爸爸的周边就是爸爸的缓存空间，爸爸的房间是属于爸爸所管理的类加载路径&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;爷爷的周边就是爷爷的缓存空间，爷爷的房间是属于爷爷所管理的类加载路径&lt;/span&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;这个故事核心就是找东西，至于怎么找，先找离自己最近范围的，没有就打电话给亲人，让他们帮忙找找，最后这么一圈下来，如果最终都没找到，就报一个类未找到异常，故事中找的是儿子的身份证，那多半是在儿子自己的生活圈中，但是儿子记不清了，就像程序一样，谁都不知道哪些类是谁加载的一样。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;如果是爷爷的身份证，那就好比java中的String类一样，属于爷爷的生活范围，也只有爷爷能找到，爸爸和儿子不可能找得到，假如爷爷的东西都是非常贵重的，就像java中的核心包一样。如果有人要弄个赝品给到儿子手里，依照这个流程，只要爷爷手中的是真的，那这个赝品不会被找到，因为爷爷优先查找。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;所以java类加载机制---双亲委托机制这个说法站不住脚，但是我也没能找到一个很好的词汇来描述这套机制，因为它和我们的生活不太一样，所以我只能以上面的一个故事来讲明白这套机制。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item><item><title>句柄的最正确解释(来源知乎)</title><link>https://lategege.com/p/%E5%8F%A5%E6%9F%84%E7%9A%84%E6%9C%80%E6%AD%A3%E7%A1%AE%E8%A7%A3%E9%87%8A-%E6%9D%A5%E6%BA%90%E7%9F%A5%E4%B9%8E/</link><pubDate>Thu, 09 Jul 2020 03:11:57 +0000</pubDate><guid>https://lategege.com/p/%E5%8F%A5%E6%9F%84%E7%9A%84%E6%9C%80%E6%AD%A3%E7%A1%AE%E8%A7%A3%E9%87%8A-%E6%9D%A5%E6%BA%90%E7%9F%A5%E4%B9%8E/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;作者：黄兢成&lt;br/&gt;链接：https://www.zhihu.com/question/27656256/answer/943130123&lt;br/&gt;来源：知乎&lt;br/&gt;著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;句柄的英文是 handle。在英文中，有操作、处理、控制之类的意义。作为一个名词时，是指某个中间媒介，通过这个中间媒介可控制、操作某样东西。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;这样说有点抽象，举个例子。door handle 是指门把手，通过门把手可以去控制门，但 door handle 并非 door 本身，只是一个中间媒介。又比如 knife handle 是刀柄，通过刀柄可以使用刀。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;跟 door handle 类似，我们可以用 file handle 去操作 file, 但 file handle 并非 file 本身。这个 file handle 就被翻译成文件句柄，同理还有各种资源句柄。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;计算机领域很多英文词，直接从日常词中引申而来。比如 fork，日常用词就是个叉子，在 unix 中引申成创建新进程（进程分叉了）。socket 日常用词是插座（连起来用于通电），引申成联网的标记信息（连起来用于通信）。英文是很日常，很容易理解的词，有时翻译成中文反而难以理解了。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;---------------------------------&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;句柄这个翻译有点奇怪。据维基百科，&lt;a href="https://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/%25E5%258F%25A5%25E6%259F%2584" rel="noreferrer noopener" target="_blank"&gt;句柄&lt;/a&gt; 的条目。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;David Gries所著的《Compiler Construction for Digital Computer》（1971）有句话&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:quote --&gt;
&lt;blockquote class="wp-block-quote"&gt;&lt;p&gt;A handle of any sentential form is a leftmost simple phrase.&lt;/p&gt;&lt;/blockquote&gt;
&lt;!-- /wp:quote --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;该书中译本，《数字计算机的编译程序构造》(仲萃豪译, 1976 版）翻译成&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:quote --&gt;
&lt;blockquote class="wp-block-quote"&gt;&lt;p&gt;任一句型的句柄就是此句型的最左简单短语。&lt;/p&gt;&lt;/blockquote&gt;
&lt;!-- /wp:quote --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;这可能是句柄一词最早的出处。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;这里确实是在讨论句子。在这里句柄是个意译的合成词，两个字分拆开，“句柄”中的“柄”，用法就类似于，“刀柄”中的“柄”。用在此处是适当的。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;但以后将各种资源 handle, 都翻译成句柄时，就有点滥用了。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;---------------------------------&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;具体到代码实现，handle 通常是某个数字标记，通过标记操作资源。这个标记在不同的场合有不同的叫法，有时叫 ID，有时叫描述符(descriptor)。在 Windows 平台，就叫各种 handle 了。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;不要将 handle 简单地理解成编号、索引。比如分配 16 位的索引，再用 8 位密码将 16 位索引加密。之后将 4 位类型、4 位权限、8 位密码、16 位加密索引打包成一个 32 位的整数作为 handle。这时说这个 handle 是索引就有点不适当了。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;用 handle 如何操作真正的资源，是实现的细节。handle 通常被实现为整数，也可以被实现成其他类型。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;广义来说，指针也是某种 handle，可以操作对象。但实际语境中，指针跟句柄是有区别的。初次接触到 handle (或者 id)，很多人会有迷惑，为什么要用 handle，而不直接用指针呢？&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:list {"ordered":true} --&gt;
&lt;ol&gt;&lt;li&gt;指针作用太强，可做的事情太多。可做的事情越多，就会越危险。接口设计中，功能刚刚好就够了，并非越多权限越好的。&lt;/li&gt;&lt;li&gt;handle 通常只是个整数，实现被隐藏起来，假如直接暴露了指针，也就暴露了指针类型（有时也可以暴露 void* 指针作为某种 handle）。用户看到越多细节，其代码就越有可能依赖这些细节。将来情况有变，但又要兼容用户代码，库内部改起来就更麻烦。&lt;/li&gt;&lt;li&gt;资源在内部管理，通过 handle 作为中间层，可以有效判断 handle 是否合法，也可以通过权限检查防止某种危险操作。&lt;/li&gt;&lt;li&gt;handle 通常只是个整数，所有的语言都有整数这种类型，但并非所有语言都有指针。接口只出现整数，方便同一实现绑定到各种语言。&lt;/li&gt;&lt;/ol&gt;
&lt;!-- /wp:list --&gt;</description></item><item><title>编程语言为什么用0x来表示十六进制数</title><link>https://lategege.com/p/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A80x%E6%9D%A5%E8%A1%A8%E7%A4%BA%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E6%95%B0/</link><pubDate>Thu, 09 Jul 2020 02:22:54 +0000</pubDate><guid>https://lategege.com/p/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A80x%E6%9D%A5%E8%A1%A8%E7%A4%BA%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E6%95%B0/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;我们想象下如果不使用0x来表示十六进制,我们有哪些选择？&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;比如一句赋值语句 int a = 0xB3; 我们将0x去掉 int a =B3; 这个时候如果右侧有字母我们大致能判断这是十六进制，但是如果B3换成13呢？就不确定13是什么进制了。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;假设我们使用一个后缀来代替0x，将上面的例子换成int a =B3g ，这会使编译器很难理解B3g究竟是个变量还是一个值。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;0x其实是从8进制表示进化而来的，数字前面出现0，不会对值产生影响，那就可以借助这一点来表示8进制01，那遇到16进制，我们在0后面加一个字母就行0x就成了十六进制的表示方法。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item><item><title>“云计算”、“人工智能”、“机器学习”、“深度学习”的本质</title><link>https://lategege.com/p/%E4%BA%91%E8%AE%A1%E7%AE%97-%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD-%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0-%E7%9A%84%E6%9C%AC%E8%B4%A8/</link><pubDate>Tue, 07 Jul 2020 07:05:42 +0000</pubDate><guid>https://lategege.com/p/%E4%BA%91%E8%AE%A1%E7%AE%97-%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD-%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0-%E7%9A%84%E6%9C%AC%E8%B4%A8/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;随着互联网的蓬勃发展，很多科技企业、新闻媒体都喜欢使用一些高大上的词，如“云”、“云计算”、”人工智能“、“机器学习”、“深度学习”。在很多人心中，一看到这些词就觉得高深莫测，其实没有这个必要。无论科技怎么发展，名词怎么新颖，本质都还是很早就有的东西，一个人不会因为穿了一件最时髦的衣服成为仙人，下面让我们脱下这件最时髦的衣服看看这个人是什么样的。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;所谓“云“，其实就是一群计算机的组合。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;所谓“云计算”，其实就是这群计算机组合起来做计算。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;所谓“人工智能”就是出一个问题让计算机回答。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;所谓“机器学习”就是让计算机把问题合集记录好。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;所谓“深度学习”就是让“机器学习”做的更好一些。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;以上就是这些新概念的本质，云计算就是很简单的多计算机并行计算，在家里可以使用自己的电脑装几台虚拟机，在每个虚拟机上装一个联网计算程序，这个程序有同步、自主发现、自主选举老大主机等功能，那我向任意一台计算机发送计算命令，那我完全可以说我进行了云计算。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;人工智能包含了机器学习，机器学习又包含了深度学习。我们围绕人工智能来探讨其本质，我们都知道电脑不是人脑，电脑没有思想，你问电脑问一个问题，电脑真的会思考吗？答案是不会，电脑底层永远只有两个选择，是与不是，0或者1，多个0，多个1就能代表不同的意思，这就是道生一，一生二，二生三，三生万物的老子思想。电脑的智能都是看上去智能，所以你问电脑一个问题，电脑可以做的，无非就两种情况：第一种是电脑会比对这个问题与电脑中已经存在的问题并给出此问题相应的答案。第二种是电脑会让你这个问题进入一个已经存在的模型，一步步判断，最终得出一个结论反馈出来。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;针对第一种，比对问题给出答案是最简单的人工智能，如下图：&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":171,"width":479,"height":392,"sizeSlug":"large","className":"is-style-default"} --&gt;
&lt;figure class="wp-block-image size-large is-resized is-style-default"&gt;&lt;img alt="" class="wp-image-171" height="392" src="https://img.lategege.com:30443/images/web/uploads/2020/07/1.png" width="479"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;你能说它不是人工智能吗？很显然，它就是人工智能。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;针对第二种，把问题输入一个已经存在的模型，模型会一步步判断，最终得出结论反馈出来。机器学习、深度学习就是为了制作这个模型。当然这个模型并非真实模型，而是为了看起来直观所列举出的一个抽象模型，实际的模型可能会非常复杂，也正因为模型的复杂，现实中机器学习模型的每一个节点全都是使用数值来表示的。人工智能所解决的问题在计算机中全都会映射成为数学运算问题，所有的问题相关的属性、节点等都被看作是一个数值。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":172,"width":674,"height":569,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large is-resized"&gt;&lt;img alt="" class="wp-image-172" height="569" src="https://img.lategege.com:30443/images/web/uploads/2020/07/12.png" width="674"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;其实还有一种，是真真切切的人工智能。如下图所示，电脑背后是一群人脑，某大厂的语音机器人就这么干过。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":173,"width":443,"height":377,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large is-resized"&gt;&lt;img alt="" class="wp-image-173" height="377" src="https://img.lategege.com:30443/images/web/uploads/2020/07/3.png" width="443"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;当然“人工智能”、“机器学习”、“深度学习”在实际情况下会运用到很多数学知识，统计学、概率论、回归、KVM、神经网络，但这些都是数学问题，并非真正的智能。我们继续探讨人工智能的三大算法，比邻算法、决策树、神经网络。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;一、比邻算法：&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;我们运用一个例子来介绍这个算法，我们假设有一系列实时数据，这系列数据分别是一些城市的某些地点的位置信息，还有这个地点所对应的天气情况，我们可以将这些信息转换为平面坐标上的一个个点。得到下图，那我给出一个未知天气的地理位置坐标，我通过这个坐标模型就能获知这个地方最有可能的天气情况吗？答案是肯定的，谁都知道只要比对这个位置离已经位置最近的点，那最近的点的天气就是该点的天气。事实上，只要模型足够完善，平面中的点够多，那这个问题的答案也就越准确。这其实就是分类问题，我们将已有数据归类，对于未知的点，我们靠计算这个点在模型中最接近的一个点或多个点的位置来得出答案。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":174,"width":516,"height":338,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large is-resized"&gt;&lt;img alt="" class="wp-image-174" height="338" src="https://img.lategege.com:30443/images/web/uploads/2020/07/223.png" width="516"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;二、决策树：&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;决策树可以让一个问题得出一个结论，这个结论非正即负。例如下图这个传染病例子中，结论只有两个，隔离和不隔离，要让机器做出决断，机器需要有这么一颗决策树，这个决策树就是模型，可以通过特定算法训练得出，当所有计算的值都有精确的答案时，要么就是隔离，要么就是不隔离，这个模型的训练就结束，这也被搜索引擎公司用来识别垃圾网站，垃圾网站为了增加权重，喜欢在网站中加入很多超链接，并且在网站中加入大量热门词汇，那通过分析垃圾网站的这些特性来训练出一个决策树模型，就能大概率判断该网站是否是垃圾网站。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":176,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large"&gt;&lt;img alt="" class="wp-image-176" src="https://img.lategege.com:30443/images/web/uploads/2020/07/12323.png"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;三、神经网络&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;神经网络所解决的问题是现实中某个答案的准确率，比如小王是学霸，最后得出的会是小王考上清华的概率是多少，这个概率的准确程度也取决于这个神经网络模型，要训练这个模型，我们需要往届清华大学学生的数据，将这些学生的关键特质列举出来，如上了哪所高中，哪个老师教的，家庭情况怎么样，学生健康情况，高考当天天气，饮食习惯等等等等，这些都是神经网络中的一个节点，我们告诉计算机，具有这些特质的考生考上了清华大学，计算机运用特定的算法训练出来这个神经网络模型，模型的每一条分支都有权重，下一个节点数值是上面所有节点数值乘以对应路径上的权重再相加而来，最终输出一个最大不超过1的数值。那预测一个人是否能考上清华，只要将这个人的这些特质输入这个模型，得出最终的数值就是这个人能考上清华的概率，当然这只是神经网络的一个例子，至于他自己意愿我们不予考虑。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":177,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large"&gt;&lt;img alt="" class="wp-image-177" src="https://img.lategege.com:30443/images/web/uploads/2020/07/34234.png"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;其实很多高大上的概念一层层拨开，本质的东西很简单，我们觉得复杂是因为简单的组合多了，自然而然就成了复杂，所谓三生万物就是这个道理。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item><item><title>搜索引擎如何检索排名？</title><link>https://lategege.com/p/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E5%A6%82%E4%BD%95%E6%A3%80%E7%B4%A2%E6%8E%92%E5%90%8D/</link><pubDate>Thu, 02 Jul 2020 02:59:23 +0000</pubDate><guid>https://lategege.com/p/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E5%A6%82%E4%BD%95%E6%A3%80%E7%B4%A2%E6%8E%92%E5%90%8D/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;写这篇文章的目的是因为最近看了一些算法书籍，对搜索引擎核心算法有了个大致的了解，就当做个笔记吧。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;搜索引擎的核心思想就是索引，类似书籍的目录，索引技术其实最早起源于古巴比伦图书馆，这个伟大的发明不是现在计算机科学的产物，如果没有索引，想象一下在一本书中查找想要的内容，就需要一页一页的查询，运气好的很快能找到，运气不好在最后一页出现的话，前面所有的时间都白白浪费了，索引就很好的解决了这个问题，因为索引信息量少，很精简，基本上几页就能描述整本书的大体内容结构。举个例子，我们在词典上查询一个词“乘风破浪“，那我们肯定会翻到字母c开头的目录页查找这个词所在的页码，然后翻到对应页面查看具体这个词是什么意思。搜索也是一样的，我们在搜索引擎搜索“乘风破浪”，搜索引擎会有一个索引数据库，这个数据库中存放了“乘风破浪”---第5页，然后展示出来，当然还有一些第五页这个网页的一些描述信息。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;除了简单的索引，还有一个问题急需解决，那就是我搜索多词的时候，搜索引擎怎么处理，比如我搜“屋子 草莓”，我们知道“屋子“、“草莓“在第一页、第二页都出现，但是两个词出现的位置相邻距离不同，那“屋子 草莓”搜出来的页面怎么排序？很显然，两个词距离相近应该排在前面，所以在索引信息中只记录一个词出现的页数是不够的，还需要记录这个词出现的位置，比如屋子----1-2 2-10 代表第一页的第二个位置，第二页的第十个位置，草莓----1-3 2-16代表第一页的第三个位置，第二页的第十六个位置。很明显第一页两个词相邻近就应该排在前面。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;网页中除了正文，其实还有用户在浏览器上看不到的标签数据，如&amp;lt;title&amp;gt; &amp;lt;/title&amp;gt; &amp;lt;body&amp;gt;&amp;lt;/body&amp;gt; 搜索引擎一般也将标签数据记录在索引中，如&amp;lt;title&amp;gt; 2-10 &amp;lt;/title&amp;gt; 2-50 记录后搜索引擎就能满足一些特殊搜索，如用户搜索在网页title标签中的关键字 由于关键字在索引中也有记录位置 所以在title标签中的位置就变成了简单的数学比较运算。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;搜索引擎的核心排名机制是什么样的？这要追溯到谷歌创始人发表的pageRank论文中的排名算法。一开始搜索引擎根据超链接来决定一个网页的权重，比如a-&amp;gt;b ,c-&amp;gt;b 那a的权重是1，c的权重是1，b的权重是1+1=2，所以哪个网页的超链接多，哪个网页的权重值就大，但是这会造成一个严重的问题，比如 a-&amp;gt;b ,c-&amp;gt;b,b-&amp;gt;a 这种循环链接的方式就会让网页的权重一直增加，于是pageRank论文中就提出了一种随机访问思想，模拟用户访问网页形式，从一个网页随机访问超链接，跳入下一个网页，再随机访问超链接，这样执行几万百万次，得出访问过程中网页被访问的概率就是这个网页的权重，这种方式可以很好和超链接方式获取的权重相结合。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;现代搜索引擎除了上述这些核心算法外，还做了很多很多事情，其复杂程度非常高，比如搜索引擎需要解决人为故意增加一些垃圾超链接来提升权重，还有一些关键字与网页相关度优化等。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item><item><title>详解DDNS以及具体应用</title><link>https://lategege.com/p/%E8%AF%A6%E8%A7%A3ddns%E4%BB%A5%E5%8F%8A%E5%85%B7%E4%BD%93%E5%BA%94%E7%94%A8/</link><pubDate>Mon, 15 Jun 2020 01:39:41 +0000</pubDate><guid>https://lategege.com/p/%E8%AF%A6%E8%A7%A3ddns%E4%BB%A5%E5%8F%8A%E5%85%B7%E4%BD%93%E5%BA%94%E7%94%A8/</guid><description>&lt;!-- wp:paragraph --&gt;
&lt;p&gt;一、什么是DDNS? DDNS英文名是 Dynamic Domain Name Server,字面解释是动态域名服务，我用一句直白的话概括下DDNS是什么？DDNS就是能把你家宽带的ip地址绑定到一个固定域名下的一个程序，这样家里的网络就可以通过这个固定域名访问了，既然是程序，那这个程序放在哪里？当然放在家庭的网络的设备上，因为只有内部设备才能获取到家庭网络的ip地址，常见的设备如路由器、电脑主机等。&lt;br/&gt;二、具体工作细节？DDNS工作细节主要有两部分:一个是获取家庭网络的ip地址，一个是向你的域名注册商上报家庭ip地址。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":138,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large"&gt;&lt;img alt="" class="wp-image-138" src="https://img.lategege.com:30443/images/web/uploads/2020/06/image-18.png"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;程序其实相当简单:每隔一定时间，获取到宽带的ip地址，通过域名商提供的api 上报给域名商完成解析服务。&lt;br/&gt;获取ip:这一步有多种方式，如果DDNS放在路由器，那路由器系统本身就知道拨号获得的ip地址，直接读取这个ip就可以了。如果部署在电脑主机上，技术上有几种方式，一种是访问ip138.com这类能获取自身宽带ip的网站，然后从网站html数据中提取ip地址，还有一种是询问路由器的某个服务，路由器告知它获取的ip地址。&lt;br/&gt;上报ip:这一步需要你购买的域名商提供接口，程序通过这个接口上报。如阿里就提供了一个上报接口，只不过安全起见，同时也给每个人分配了一把钥匙和一个密码。通过这个钥匙和密码访问接口就可以完成上报。&lt;br/&gt;三、DDNS的作用和具体应用一切的原因都归结于宽带进行拨号的时候获取到的ip地址不是固定的，一旦家里停电或者长时间运行后，宽带的ip都会发生变化，假设将没变化之前的ip绑定到域名上，一旦ip发生变化，该域名却还绑定着之前的旧ip地址，那这个域名所有的访问都将失效。DDNS的存在就是为了解决这种问题，DDNS程序不关心路由器ip什么时候发生变化，它只会每隔一段时间去获取一次ip地址并通过域名上报接口上报。优化版的程序可能会在每次网络重新联通后也获取一次，并且和之前上报的进行比对，甚至不是通过间隔获取方式，如果路由器ip地址变化会有主动性的广播，那程序可不通过间隔获取，只要监听这个变化广播提取广播中的ip信息就行了，这样程序就能达到最大的优化。&lt;br/&gt;那面对DDNS程序，其实不需要自己开发，别人已经做好这些工作了，我们只需要去找到这些程序执行就可以了。比如群晖中，我们就可以运用docker技术执行阿里云DDNS服务，镜像叫chenhw2/aliyun-ddns-cli&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;
&lt;!-- wp:image {"id":139,"sizeSlug":"large"} --&gt;
&lt;figure class="wp-block-image size-large"&gt;&lt;img alt="" class="wp-image-139" src="https://img.lategege.com:30443/images/web/uploads/2020/06/image-19-1024x395.png"/&gt;&lt;/figure&gt;
&lt;!-- /wp:image --&gt;
&lt;!-- wp:paragraph --&gt;
&lt;p&gt;使用的时候只要修改环境变量AKID、AKSCT和DOMAIN几项就可以了。AKID、AKSCT是阿里云提供的，可在阿里云后台获取，DOMAIN是你需要解析的域名，IPAPI可以修改，如果不修改就会使用默认的获取方式，REDO获取ip的间隔时间,单位为秒。300就是5分钟。以上只是DDNS应用的一个小例子，我并没有去看这个镜像中具体的代码实现，因为实现原理细节已经在本文第二项中描述的很清楚了，不管使用何种编程语言都能实现。&lt;/p&gt;
&lt;!-- /wp:paragraph --&gt;</description></item></channel></rss>