浏览器知识总结~

  • 前言
    • 一、浏览器的存储
      • Cookie
      • session
      • storage
      • indexedDB
    • 二、浏览器的缓存
      • 浏览器缓存
      • 其它缓存
    • 三、浏览器同源策略和跨域
      • 同源策略
      • 跨域
    • 四、浏览器的渲染
    • 五、进程与线程
      • 1、进程与线程概念
      • 2、进程和线程之间的关系特点:
      • 3、**Chrome浏览器包括:**
      • 4、渲染进程(内核)
      • 5、**进程之前的通信方式**:
      • 6、**如何实现浏览器内多个标签页之间的通信?**
      • 7、对Service Worker的理解
    • 六、浏览器内核
    • 七、浏览器的兼容性问题

前言

本文整理了浏览器知识,如果有不一样见解或有更好的理解描述或更加详细的朋友欢迎评论区指出补充说明,谢谢~
喜欢本文或者你觉得它对你有用有帮助的话,少侠留个赞~

一、浏览器的存储

浏览器的存储包括cookie,session,LocalStorage,sessionStorage,indexedDB。

作用 cookie session sessionStorage LocalStorage indexedDB
储存时间 设置或不设置 默认30分 仅当前页面 永久 永久
储存大小 4k 无限制 5M 5M 无限制
储存形式 字符串 对象 字符串型的键/值对 字符串型的键/值对 类似于数据库表的形式
储存位置 浏览器端 服务器端 浏览器端 浏览器端 浏览器端
交互通信 与服务器交互通信 不交互 不交互 不交互 不交互

Cookie

因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么操作,为了辨别用户身份以及实现交互应用程序,就需要使用到Cookie。因此服务器才知道用户浏览了几个页面或者买了什么东西等。服务器可以设置或读取Cookies中包含信息,因此维护用户跟服务器会话中的状态。

主要包括名字、值、过期时间、路径和域。路径与域一起构成cookie的作用范围。Cookie是由服务器生成然后发送到浏览器的。与服务器通信时,每次请求都会携带在HTTP头中。

不设置时间,将被浏览器保存在内存中,关闭浏览器窗口,cookie就会消失。这个cookie的生命期为浏览器会话期间,这种生命期为浏览器会话期的cookie被称为会话cookie。
设置时间,将被浏览器保存在硬盘中,直到过期才消失。除非用户手动清理,不然硬盘Cookie不会被删除。

session

服务器状态管理技术,将状态信息保存在服务器端。用户第一次发送请求时,服务器生成session对象,并返回一个session_Id给浏览器作为cookie的value。再次请求时根据cookie也就是session_Id查询对应session对象,有就使用,无就创建session对象。

session没有大小限制,tomacat中默认的有效时间30分,当用户和服务器的交互时间超过默认时间后session就失效。

storage

localStorage和sessionStorage都是本地存储,不与服务器进行交互通信,减少不必要的请求,大小5M左右,因各浏览器的存储空间有差异
localStorage是永久保存在浏览器,除非用户主动清除。
sessionStorage仅仅存储在当前页面,关闭浏览器或关闭页面存储的数据就会销毁

indexedDB

indexedDB是浏览器提供的本地数据库,可储存大量的结构化数据(也包括文件/二进制大型对象(blobs))。IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。 然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象数据库。IndexedDB 允许您存储和检索用键索引的对象。使用 IndexedDB 执行的操作是异步执行的,以免阻塞应用程序。具体可以查看文档

二、浏览器的缓存

浏览器缓存

简单来说,浏览器缓存就是浏览器保存通过HTTP请求获取的所有资源。
优点:减少网络带宽消耗;降低服务器压力;减少网络延迟,加快页面打开速度

一·,使用HTML Meta 标签
  即在HTML页面的节点中加入标签,代码如下

 <meta http-equiv="Pragma" content="no-cache" >// Pragma是http1.0版本中给客户端设定缓存方式之一

上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。但是!事实上这种禁用缓存的形式用处很有限:
(a) 仅有IE才能识别这段meta标签含义,其它主流浏览器仅识别“Cache-Control: no-store”的meta标签。
(b) 在IE中识别到该meta标签含义,并不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求(仅限页面,页面上的资源则不受影响)。

二,使用缓存有关的HTTP消息报头

(1)强缓存
  浏览器发送请求前,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中,则直接从缓存中读取资源,不会去请求服务器。也就是不与服务器发生交互行为。

这里的响应 header 中的信息指的是 expires 和 cahe-control(优先级高)
(a)Expires:这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。

(b)Cache-Control :主要是利用该字段的 max-age 值来进行判断,例如 Cache-Control:max-age=3600;cache-control属性:
max-age: 设置缓存的最大的有效时间,单位为秒(s)。max-age会覆盖掉Expires
no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。
no-store:禁止使用缓存,每一次都要重新请求数据。
public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

(2) 协商缓存
  当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。

这里的 header 中的信息指的是 Last-Modify(响应)/If-Modify-Since(请求)和 ETag(响应)/If-None-Match(请求)
(a)Last-Modify是一个时间标识该资源的最后修改时间。If-Modify-Since其值为上次响应头的Last-Modify值,再次向web服务器请求时带上头If-Modify-Since,则与被请求资源的最后修改时间进行对比。若最后修改时间较新,说明资源又被改动过,则响应资源内容,包括更新Last-Modify的值,HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用本地的缓存
周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为,因此便有了 ETag。
(b)与 Last-Modify/If-Modify-Since 不同的是,Etag/If-None-Match 返回的是一个校验码。ETag 是一个资源的唯一标识符,资源变化都会导致 ETag 变化。服务器根据浏览器上送的 If-None-Match (ETag值)来判断是否命中缓存。

注:Last-Modify与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

其它缓存

(1) DNS缓存
 全称 Domain Name System ,即域名系统。
 万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。DNS协议运行在UDP协议之上,使用端口号53。
 DNS解析:例如:www.name.com (域名) 通过DNS解析为 111.222.33.444 (IP地址)
 DNS缓存:有dns的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存。

DNS查询过程
1、首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
2、如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
3、如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。
4、如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。

(2) CDN缓存
 全称 Content Delivery Network,即内容分发网络。相当于代理服务器,将资源缓存到离用户最近的服务器上加快请求速度,从而降低网络延迟。
 CDN节点缓存机制在不同服务商中是不同的,但一般都遵循HTTP协议,通过http响应头中的Cache-Control:max-age的字段来设置CDN节点文件缓存时间。
 若使用了CDN缓存,再次请求时若浏览器本地缓存失效后,浏览器会向离用户最近的服务器边缘节点CDN发起请求。若本地缓存过期,览器不是直接向源站点请求资源,而是向CDN边缘节点请求资源,若CDN中的缓存也过期,那就由CDN边缘节点向源站点发出回源请求来获取最新资源。CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。
 CDN优势
 1.CDN节点解决了跨运营商和跨地域访问的问题,访问延时大大降低。
 2.大部分请求在CND节点完成,CND起到分流作用,减轻源服务器负载。

三、浏览器同源策略和跨域

同源策略

同源策略/SOP是一种约定。是指协议、域名、端口(port默认是80)三者相同。它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略。如果缺少了同源策略,浏览器很容易受到 XSS、 CSFR 等攻击。

跨域

跨域的解决方法(具体描述请移步传送门)
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

传送门

四、浏览器的渲染

浏览器内核指支持浏览器运行的最核心程序,分别为渲染引擎和JS引擎。在不同浏览器中渲染引擎是不同的,比如在 Firefox 中叫做 Gecko,在 Chrome 和 Safari 中都是基于 WebKit 开发的。

浏览器会解析三个东西,分别是html、css、js。对HTML和CSS构建时,如果遇到JS,会阻塞HTML和CSS的构建,优先加载JS文件,加载完毕,再从未加载的HTML和CSS开始继续构建。

浏览器会遵守一套步骤将HTML 文件转换为 DOM 树。宏观上,可以分为几个步骤
字节数据 => 字符串 => Token => Node => DOM

1、HTML文档解析并构建成DOM树
2、CSS解析并构建成CSS规则树
3、渲染树(Rendering Tree)是由DOM Tree 和 CSS Rule Tree的合并;渲染树并不是必须等DOM树及CSSOM树加载完成后才开始合并构建渲染树。三者的构建并无先后条件,不是完全独立,而是会有交叉,并行构建。因此会形成一边加载,一边解析,一边渲染的工作现象。
4、布局(layout),对渲染树的根节点开始遍历,计算渲染树的每个节
5、绘制(painting),将渲染树的各个节点绘制到屏幕上
上图是webkit的流程

回流(reflow)和重绘(repaint)
(a)重绘:渲染树节点外观、风格发生改变,但不影响该节点在页面当中的空间位置及大小。如某个div节点的背景色、字体色等发生改变,但是该div节点的宽、高、内外边距没变化,则触发浏览器重绘,即屏幕的一部分要重画。
(b)回流:当渲染树节点发生改变,影响了节点的几何属性如宽、高、内边距、外边距、或是float、position、display:none;等,之后的所有节点位置都会发生改变,导致节点位置发生变化,此时触发浏览器重排(reflow),需要重新生成渲染树。此时浏览器需要重新生成渲染树,重新布局,即回流。
回流必定触发重绘,重绘不一定触发回流。

渲染阻塞
即执行JS脚本时,会导致DOM和CSSOM构建暂停,所以script标签位置很重要。JS阻塞了构建DOM树,也阻塞了其后的构建CSSOM规则树,整个解析进程必须等待JS的执行完成才能够继续,这就是所谓的JS阻塞页面。CSS阻塞渲染意味着,在CSSOM解析完前,页面将一直处理白屏状态,这就是为什么样式放在head中,仅仅是为了更快的解析CSS,保证更快的首次渲染。

默认情况下,浏览器是同步加载 JavaScript 脚本,即渲染引擎遇到script标签就会暂停,等到执行完脚本,才继续渲染。如果是外部脚本,还必须加入脚本下载的时间。下载和执行的时间就会很长,因此造成浏览器阻塞,用户会感觉到浏览器“卡死”了。

script标签使用defer或async属性,脚本就会异步加载。defer,加载完后等整个页面都解析完毕后才开始执行。async,加载完后就立即执行。两者的区别在于脚本加载完成之后何时执行。

五、进程与线程

1、进程与线程概念

从本质上说,进程和线程都是 CPU 工作时间片的一个描述:

  • 进程描述了 CPU 在运行指令及加载和保存上下文所需的时间,放在应用上来说就代表了一个程序。
  • 线程是进程中的更小单位,描述了执行一段指令所需的时间。

进程是资源分配的最小单位;线程是CPU调度的最小单位

一个进程就是一个程序的运行实例。详细解释就是,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程进程是运行在虚拟内存上的,虚拟内存是用来解决用户对硬件资源的无限需求和有限的硬件资源之间的矛盾的。从操作系统角度来看,虚拟内存即交换文件;从处理器角度看,虚拟内存即虚拟地址空间

如果程序很多时,内存可能会不够,操作系统为每个进程提供一套独立的虚拟地址空间,从而使得同一块物理内存在不同的进程中可以对应到不同或相同的虚拟地址,变相的增加了程序可以使用的内存。

2、进程和线程之间的关系特点:

(1)进程中的任意一线程执行出错,都会导致整个进程的崩溃。

(2)线程之间共享进程中的数据。

**(3)当一个进程关闭之后,操作系统会回收进程所占用的内存,**当一个进程退出时,操作系统会回收该进程所申请的所有资源;即使其中任意线程因为操作不当导致内存泄漏,当进程退出时,这些内存也会被正确回收。

**(4)进程之间的内容相互隔离。**进程隔离就是为了使操作系统中的进程互不干扰,每一个进程只能访问自己占有的数据,也就避免出现进程 A 写入数据到进程 B 的情况。正是因为进程之间的数据是严格隔离的,所以一个进程如果崩溃了,或者挂起了,是不会影响到其他进程的。如果进程之间需要进行数据的通信,这时候,就需要使用用于进程间通信的机制了。

3、Chrome浏览器包括:
  • 1 个浏览器主进程:

    主要负责界面显示、用户交互、子进程管理,同时提供存储等功能

  • 1 个 GPU 进程:

    GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。

  • 1 个网络进程:

    主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。

  • 多个渲染进程:

    核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。

  • 多个插件进程:

    主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

打开一个网页,最少需要四个进程:1 个网络进程、1 个浏览器进程、1 个 GPU 进程以及 1 个渲染进程。如果打开的页面有运行插件的话,还需要再加上 1 个插件进程。

虽然多进程模型提升了浏览器的稳定性、流畅性和安全性,但同样不可避免地带来了一些问题:

  • 更高的资源占用:因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏览器会消耗更多的内存资源。
  • 更复杂的体系架构:浏览器各模块之间耦合性高、扩展性差等问题,会导致现在的架构已经很难适应新的需求了。
4、渲染进程(内核)

浏览器的渲染进程(内核)是核心重点,其中线程总共有五种

(1)GUI渲染线程

负责渲染浏览器页面,解析HTML、CSS,构建DOM树、构建CSSOM树、构建渲染树和绘制页面;当界面需要重绘或由于某种操作引发回流时,该线程就会执行。

注意:GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

(2)JS引擎线程

JS引擎线程也称为JS内核,负责处理Javascript脚本程序,解析Javascript脚本,运行代码;JS引擎线程一直等待着任务队列中任务的到来,然后加以处理,一个Tab页中无论什么时候都只有一个JS引擎线程在运行JS程序;

注意:GUI渲染线程与JS引擎线程的互斥关系,所以如果JS执行的时间过长,会造成页面的渲染不连贯,导致页面渲染加载阻塞。

(3)时间触发线程

时间触发线程属于浏览器而不是JS引擎,用来控制事件循环;当JS引擎执行代码块如setTimeOut时(也可是来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件触发线程中;当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理;

注意:由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行);

(4)定时器触发进程

定时器触发进程即setInterval与setTimeout所在线程;浏览器定时计数器并不是由JS引擎计数的,因为JS引擎是单线程的,如果处于阻塞线程状态就会影响记计时的准确性;因此使用单独线程来计时并触发定时器,计时完毕后,添加到事件队列中,等待JS引擎空闲后执行,所以定时器中的任务在设定的时间点不一定能够准时执行,定时器只是在指定时间点将任务添加到事件队列中;

注意:W3C在HTML标准中规定,定时器的定时时间不能小于4ms,如果是小于4ms,则默认为4ms。

(5)异步http请求线程

  • XMLHttpRequest连接后通过浏览器新开一个线程请求;
  • 检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将回调函数放入事件队列中,等待JS引擎空闲后执行;
5、进程之前的通信方式

消息队列通信;管道通信;信号通信;共享内存通信等

6、如何实现浏览器内多个标签页之间的通信?

实现多个标签页之间的通信,本质上都是通过中介者模式来实现的。因为标签页之间没有办法直接通信,因此我们可以找一个中介者,让标签页和中介者进行通信,然后让这个中介者来进行消息的转发。通信方法如下:

  • 使用 websocket 协议,因为 websocket 协议可以实现服务器推送,所以服务器就可以用来当做这个中介者。标签页通过向服务器发送数据,然后由服务器向其他标签页推送转发。
  • 使用 postMessage 方法,如果我们能够获得对应标签页的引用,就可以使用postMessage 方法,进行通信。
  • 使用 localStorage 的方式,我们可以在一个标签页对 localStorage 的变化事件进行监听,然后当另一个标签页修改数据的时候,我们就可以通过这个监听事件来获取到数据。这个时候 localStorage 对象就是充当的中介者的角色。
  • 使用 ShareWorker 的方式,shareWorker 会在页面存在的生命周期内创建一个唯一的线程,并且开启多个页面也只会使用同一个线程。这个时候共享线程就可以充当中介者的角色。标签页间通过共享一个线程,然后通过这个共享的线程来实现数据的交换。
7、对Service Worker的理解

Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。

Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。

六、浏览器内核

不同浏览器的内核也不尽相同,内核可区分为渲染引擎和JS引擎,所以不同浏览器对代码的解析会存在差异,这就导致对页面渲染效果不统一的问题。

市场上常见的浏览器内核主要有四种:Webkit内核、Presto内核、Trident内核、Gecko内核。

浏览器 内核
Chorme Webkit,现在是 Blink(Webkit的分支内核)
Safari Webkit
Firefox Gecko
Opera 最初是自己的Presto,后来是Webkit,现在是Blink
IE Trident(俗称IE内核)
360、猎豹浏览器 IE + Chorme双内核
搜狗、遨游、UC、QQ浏览器 Trident(兼容模式)+ Webkit(高速模式)
百度浏览器 IE内核

七、浏览器的兼容性问题

常见的浏览器兼容性可分为三类
一、HTML兼容
这是由于低版本浏览器不能识别一些高版本浏览器使用的标签,从而导致不能解析,比如HTML5新增的标签

二、CSS兼容
浏览器CSS样式兼容:
浏览器的默认样式不同,通常可以把一些常用的标签统一设置下。

浏览器私有属性前缀样式兼容:
-moz-代表firefox
-ms-代表IE
-webkit-代表chrome、safari
-o-代表opera

CSS hack语法兼容:
大致可以分为 条件hack、属性级hack、选择符级hack。

三、JavaScript兼容
event事件问题。DOM节点相关的问题。阻止事件问题。鼠标滚轮滚动事件问题等

浏览器相关知识总结~相关推荐

  1. AI问答:浏览器相关知识

    一.浏览器的发展历史可以分成以下几个阶段 1. 单一线程浏览器时代:早期的浏览器如Mosaic.Netscape Navigator.Internet Explorer等都是单一线程的,无法同时处理多 ...

  2. 你应该掌握的浏览器相关知识

    文章目录 一.浏览器安全 1. XSS攻击 2. CSRF攻击 3.有哪些可能引起的前端安全的问题 二.浏览器缓存机制 1.对缓存的理解 2.浏览器缓存的分类 强缓存 协商缓存 3.浏览器的缓存机制的 ...

  3. VMware虚拟网络相关知识

    VMware虚拟网络相关知识 虚拟网桥         通过虚拟网桥把虚拟机的虚拟网卡连接到宿主机的物理网卡上.通过它可以将虚拟机连接到宿主机所在的外部网络.如果宿主机上不止是一个物理网卡时,采用定制 ...

  4. Next.js踩坑入门系列(七) —— 其他相关知识

    Next.js踩坑入门系列 (一) Hello Next.js (二) 添加Antd && CSS (三) 目录重构&&再谈路由 (四) Next.js中期填坑 (五) ...

  5. 【提高系列】webpack相关知识

    这次我们主要研究的是webpack框架的相关知识,webpack是一个打包构建的前端框架,用于解决前端开发的模块化问题. 应用场景和纵向比较 说到webpack,肯定你还会想到gulp和grunt这些 ...

  6. 浏览器缓存知识小结及应用

    器缓存,也就是客户端缓存,既是网页性能优化里面静态资源相关优化的一大利器,也是无数web开发人员在工作过程不可避免的一大问题,所以在产品开发的时候我们总是想办法避免缓存产生,而在产品发布之时又在想策略 ...

  7. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  8. Varnish的相关知识,varnish的简单应用

    Varnish是一款高性能的缓存加速器,具有稳定,且效率更高,资源占用更少等特点. 缓存存储的格式: key-value: key:访问路径,URL, hash value:web content 命 ...

  9. web端兼容性测试相关知识

    web兼容性测试相关知识 一.客户端兼容性 1.浏览器的兼容性测试 a.内核角度 Tridnt内核:代表作IE.腾讯.遨游.世界之窗等 Gecko内核:代表作Firefox webkit内核:代表作S ...

最新文章

  1. PyCaret-低代码ML库使用指南
  2. python DbUtils 使用教程
  3. 微信小程序--搭建linux服务器并部署java后端程序2021
  4. View和View的参数传递二
  5. 博士申请 | 瑞典皇家理工学院分布式计算研究组招收NLP/ML全奖博士生
  6. iOS之性能优化·优化App的启动速度
  7. 解决IE6下 position的fixed定位问题
  8. mysql英文介绍_每日科技英文48: MySQL C API简介
  9. 批量读入一个文件夹中文件的数据操作实例
  10. .Net Core下基于Emit的打造AOP
  11. 什么是eager loading
  12. C#中用WMI实现对驱动的查询
  13. 集合的洗牌,排序,拆分以及常用遍历方法
  14. 一句“哭什么哭”,说得好
  15. 【无标题】5 自用历程
  16. 用python做youtube自动化下载器 代码
  17. 恭喜宿主获得鸿蒙,我在混沌开学院
  18. 24微信小程序开发2
  19. SQL Sever数据库存储过程
  20. 微信公众号h5页面禁止用户调整字体大小

热门文章

  1. 用verilog 实现8bit数据的并串转换
  2. 如何设置浏览QQ空间时的默认浏览器
  3. 【AD错误】Could not find board outline using primitives...解决办法
  4. poj1011 stick 强力搜索剪枝
  5. jstl取整数,jstl
  6. Echarts实现空气质量仪表盘网页
  7. 商洛学院数学与计算机应用官网,应用数学系简介
  8. java实现用户每日签到功能
  9. windows连mac桌面_如何同步Mac和Windows桌面
  10. 【翻译】和麻美学姐一起的世界树(マミさんと世界樹スレ)第八话后篇