这个仓库试图回答一个古老的面试问题:当你在浏览器中输入 google.com 并且按下回车之后发生了什么?
不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任何细节。
这将是一个协作的过程,所以深入挖掘吧,并且帮助我们一起完善它。仍然有大量的细节等待着你来添加,欢迎向我们发送 Pull Requset!
这些内容使用 Creative Commons Zero
_ 协议发布。
这个仓库试图回答一个古老的面试问题:当你在浏览器中输入 google.com 并且按下回车之后发生了什么?
不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任何细节。
这将是一个协作的过程,所以深入挖掘吧,并且帮助我们一起完善它。仍然有大量的细节等待着你来添加,欢迎向我们发送 Pull Requset!
这些内容使用 Creative Commons Zero
_ 协议发布。
像java、python这个可以具有多线程的语言。多线程同步模式是这样的,将cpu分成几个线程,每个线程同步运行。
而node.js采用单线程异步非阻塞模式,也就是说每一个计算独占cpu,遇到I/O请求不阻塞后面的计算,当I/O完成后,以事件的方式通知,继续执行计算2。
JavaScript是单线程执行【CPU单核】,根本不能进行同步IO操作,所以,JavaScript的这一“缺陷”导致了它只能使用异步IO。
JavaScript 的确是单线程的
异步是浏览器的 JavaScript 引擎做的工作
顺便回答标题nodejs真的是单线程吗?其实只有javascript执行是单线程,I/O显然是其它线程。
js执行线程是单线程,把需要做的I/O交给libuv,自己马上返回做别的事情,然后libuv在指定的时刻回调就行了。其实简化的流程就是这样子的!
细化一点,nodejs会先从js代码通过node-bindings调用到C/C++代码,然后通过C/C++代码封装一个叫 “请求对象” 的东西交给libuv,这个请求对象里面无非就是需要执行的功能+回调之类的东西,给libuv执行以及执行完实现回调。
总结来说,一个异步 I/O 的大致流程如下:
发起 I/O 调用
用户通过 Javascript 代码调用 Node 核心模块,将参数和回调函数传入到核心模块;
Node 核心模块会将传入的参数和回调函数封装成一个请求对象;
将这个请求对象推入到 I/O 线程池等待执行;
Javascript 发起的异步调用结束,Javascript 线程继续执行后续操作。
执行回调
I/O 操作完成后,会取出之前封装在请求对象中的回调函数,执行这个回调函数,以完成 Javascript 回调的目的。(这里回调的细节下面讲解)
从这里,我们可以看到,我们其实对 Node.js 的单线程一直有个误会。
事实上,它的单线程指的是自身 Javascript 运行环境的单线程,Node.js 并没有给 Javascript 执行时创建新线程的能力,最终的实际操作,还是通过 Libuv 以及它的事件循环来执行的。
这也就是为什么 Javascript 一个单线程的语言,能在 Node.js 里面实现异步操作的原因,两者并不冲突。
Node.js 通过 libuv 来处理与操作系统的交互,并且因此具备了异步、非阻塞、事件驱动的能力。因此,NodeJS能响应大量的并发请求。所以,NodeJS适合运用在高并发、I/O密集、少量业务逻辑的场景。
上面提到,如果是 I/O 任务,Node.js 就把任务交给线程池来异步处理,高效简单,因此 Node.js 适合处理I/O密集型任务。但不是所有的任务都是 I/O 密集型任务,当碰到CPU密集型任务时,即只用CPU计算的操作,比如要对数据加解密(node.bcrypt.js),数据压缩和解压(node-tar),这时 Node.js 就会亲自处理,一个一个的计算,前面的任务没有执行完,后面的任务就只能干等着 。
我们看如下代码:
1 | var start = Date.now();//获取当前时间戳 |
最终我们的打印结果是:(结果可能因为你的机器而不同)
1 | 1000 |
对于我们期望2秒后执行的setTimeout函数其实经过了3738毫秒之后才执行,换而言之,因为执行了一个很长的for循环,所以我们整个Node.js主线程被阻塞了,如果在我们处理100个用户请求中,其中第一个有需要这样大量的计算,那么其余99个就都会被延迟执行。如果操作系统本身就是单核,那也就算了,但现在大部分服务器都是多 CPU 或多核的,而 Node.js 只有一个 EventLoop,也就是只占用一个 CPU 内核,当 Node.js 被CPU 密集型任务占用,导致其他任务被阻塞时,却还有 CPU 内核处于闲置状态,造成资源浪费。
其实虽然Node.js可以处理数以千记的并发,但是一个Node.js进程在某一时刻其实只是在处理一个请求。
对于非阻塞的IO可以去看Unix网络编程里面定义的几种io模型。
因此,Node.js 并不适合 CPU 密集型任务。
参考:
前端模块化开发中webpack、npm、node、nodejs之间的关系
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
webpack是一个工具,这个工具可以帮你处理好各个包/模块之间的依赖关系(modules with dependencies),并将这些复杂依赖关系的静态文件打包成一个或很少的静态文件,提供给浏览器访问使用;除此之外,webpack因为可以提高兼容性,可以将一些浏览器尚不支持的新特性转换为可以支持格式,进而减少由新特性带来的浏览器的兼容性问题
好,我们通过介绍,我们有个概念,webpack是一个打包工具,可以帮你把你的项目这里的项目其实就是指通过模块化开发的项目 打包为简洁版的浏览器可识别的静态资源
介绍了webpack,我们可能会疑问,我的JS,CSS,HTML文件分开写,挺好的呀,为什么要使用webpack工具,进行复杂的各项配置。在传统前端开发模式下,我们确实是按照JS/CSS/HTML文件分开写的模式就可以,但是随着前端的发展,社区的壮大,各种前端的库和框架层出不穷,我们项目中可能会使用很多额外的库,如何有效管理这些引入的库文件是一个大问题,而且我们知道基于在HTML中使用<script>
引入的方式,有两个弊端,一个是会重复引入,二是当库文件数量很多时管理成为一个大难题。
面对这样的局面,为了简化开发的复杂度,前端社区涌现了很多实践方法。模块化就是其中一项成功实践,而npm就是这样在社区 其实就是node社区中产生的
npm 为你和你的团队打开了连接整个 JavaScript 天才世界的一扇大门。它是世界上最大的软件注册表,每星期大约有 30 亿次的下载量,包含超过 600000 个 包(package) (即,代码模块)。来自各大洲的开源软件开发者使用 npm 互相分享和借鉴。包的结构使您能够轻松跟踪依赖项和版本。
npm 由三个独立的部分组成:
- 网站
- 注册表(registry)
- 命令行工具 (CLI)
网站 是开发者查找包(package)、设置参数以及管理 npm 使用体验的主要途径。
注册表 是一个巨大的数据库,保存了每个包(package)的信息。
CLI 通过命令行或终端运行。开发者通过 CLI 与 npm 打交道。
这是npm的官方网站给出的介绍,一般来说提起npm有两个含义,一个是说npm官方网站,一个就是说npm包管理工具。npm社区或官网是一个巨大的Node生态系统,社区成员可以随意发布和安装npm生态中的包,也就是不用在重复造轮子了,别人造好了,你直接安装到你的项目中就可以使用,但是因为前面说了,当包引入数量很多时管理就成为了一个问题,这个就是npm为开发者行了方便之处,npm已经为你做好了依赖和版本的控制,也就是说使用npm可以让你从繁杂的依赖安装和版本冲突中解脱出来,进而关注你的业务而不是库的管理。
而webpack就是将你从npm中安装的包打包成更小的浏览器可读的静态资源,这里需要注意的是,webpack只是一个前端的打包工具,打包的是静态资源,和后台没有关系,虽然webpack依赖于node环境
其实node和nodejs两个概念没有太大差别,我个人认为唯一的区别就是,人们说起node的时候语境更多的是再说node环境,而说nodejs时更多的是在说node是一门可以提供后端能力的技术。本质上来说,node就是nodejs,nodejs就是node
简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行>Javascript的速度非常快,性能非常好。
node环境基于V8引擎提供了一种可以让JS代码跑在后端的能力,这就是node。其实这里的node本身和我们这篇讲的前端模块化没啥关系。但是因为npm是产生与node社区,node中也是通过npm来加载模块的,所以有必要说一下他们之间的关系。
npm 是 Node.js 官方提供的包管理工具,他已经成了 Node.js 包的标准发布平台,用于 Node.js 包的发布、传播、依赖控制
参考:
摘录:
Node.js介绍,摘自官网
1 | Node.js is an open-source and cross-platform JavaScript runtime environment. It is a popular tool for almost any kind of project! |
Introduction to npm
npm is the standard package manager for Node.js.In January 2017 over 350000 packages were reported being listed in >the npm registry, making it the biggest single language code >repository on Earth, and you can be sure there is a package for >(almost!) everything.
It started as a way to download and manage dependencies of Node.js >packages, but it has since become a tool used also in frontend >JavaScript.
There are many things that npm does.
Yarn and pnpm are alternatives to npm cli. You can check them out as >well.
安装方式:
1 | <!-- V2.x --> |
1 | V2.x最新稳定版 |
1 | npm install -g @vue/cli |
1 | 创建一个新项目,跳过 git 初始化 |
1 | vue create --help |
1 | vue ui |
Vue CLI >= 3 和旧版使用了相同的 vue 命令,所以 Vue CLI 2 (vue-cli) 被覆盖了。如果你仍然需要使用旧版本的 vue init 功能,你可以全局安装一个桥接工具:
1 | npm install -g @vue/cli-init |
在一个 Vue CLI 项目中,@vue/cli-service
安装了一个名为 vue-cli-service
的命令。你可以在 npm scripts 中以 vue-cli-service
、或者从终端中以 ./node_modules/.bin/vue-cli-service
访问这个命令。
这是你使用默认 preset 的项目的 package.json:
1 | { |
1 | npm run serve |
1 | vue-cli-service serve |
1 | vue-cli-service build |
片段代码笔记
1 | /// <summary> |
下载地址:https://github.com/tporadowski/redis
命令行进入安装目录/解压目录
安装服务: redis-server.exe –service-install redis.windows.conf –loglevel verbose
卸载服务:redis-server –service-uninstall
开启服务:redis-server –service-start
停止服务:redis-server –service-stop
重命名服务:redis-server –service-name name
以下将会安装并启动三个不同的Redis实例作服务:
1 | redis-server --service-install --service-name redisService1 --port 10001 |
参考:
SqlBulkCopy 类
http://raylei.cn/index.php/archives/74/
https://www.cxybb.com/article/weixin_30333885/96361368
来自数据源的 Decimal 类型的给定值不能转换为指定目标列的类型 datetime
实际情况可能很复杂,使用的是泛型进行实体类转DataTable,可能会出现各种类型错误提示。
自己使用的是调用Copy()方法。
demo:
1 | var TableStruct = dal.GetTableStruct(); |
1 | /// <summary> |
1 |
|
现有一文件,其扩展名未知或标记错误。假设它是一个正常的、非空的文件,且将扩展名更正后可以正常使用,那么,如何判断它是哪种类型的文件?
使用文件签名来判断实际文件类型,又称magic numbers
或 Magic Bytes
。关于文件签名介绍,参考List of file signatures
Magic Number:
1 | public class MimeType |
摘录部份常用文件HEX签名,来源GCK’S FILE SIGNATURES TABLE
十六进制签名 | ASCII 签名 | |
---|---|---|
文件扩展名 | 文件描述 | |
50 4B 03 04 | PK.. | |
ZIP | PKZIP archive file (Ref. 1 Ref. 2) Trailer: filename 50 4B 17 characters 00 00 00 Trailer: (filename PK 17 characters …) Note: PK are the initals of Phil Katz, co-creator of the ZIP file format and author of PKZIP. |
|
ZIP | Apple Mac OS X Dashboard Widget, Aston Shell theme, Oolite eXpansion Pack, Opera Widget, Pivot Style Template, Rockbox Theme package, Simple Machines Forums theme, SubEthaEdit Mode, Trillian zipped skin, Virtual Skipper skin |
|
APK | Android package | |
JAR | Java archive; compressed file package for classes and data | |
KMZ | Google Earth saved working session file | |
KWD | KWord document | |
ODT, ODP, OTT | OpenDocument text document, presentation, and text document template, respectively. | |
OXPS | Microsoft Open XML paper specification file | |
SXC, SXD, SXI, SXW | OpenOffice spreadsheet (Calc), drawing (Draw), presentation (Impress),and word processing (Writer) files, respectively. | |
SXC | StarOffice spreadsheet | |
WMZ | Windows Media compressed skin file | |
XPI | Mozilla Browser Archive | |
XPS | XML paper specification file | |
XPT | eXact Packager Models |
javascript在线计算:
文件签名表格:
GCK’S FILE SIGNATURES TABLE
参考资料:
Magic number
List of file signatures
拓展阅读:
byte为什么要与上0xff?
几乎所有 Markdown 应用程序都支持原始 Markdown 设计文档中概述的基本语法。Markdown 处理器之间存在细微的差异和差异 - 只要有可能,这些差异和差异都会内联注明。
要创建标题,请在单词或短语前面添加数字符号 (#)。您使用的数字符号的数量应与标题级别相对应。例如,要创建三级标题 ( <h3>
),请使用三个数字符号(例如### My Header)。
Markdown | HTML | Rendered Output |
---|---|---|
# Heading level 1 |
<h1>Heading level 1</h1> |
Heading level 1 |
## Heading level 2 |
<h2>Heading level 2</h2> |
Heading level 2 |
### Heading level 3 |
<h3>Heading level 3</h3> |
Heading level 3 |
#### Heading level 4 |
<h4>Heading level 4</h4> |
Heading level 4 |
##### Heading level 5 |
<h5>Heading level 5</h5> |
Heading level 5 |
###### Heading level 6 |
<h6>Heading level 6</h6> |
Heading level 6 |
或者,在文本下方的行中,添加任意数量的==标题级别 1 字符或–标题级别 2 字符。
Markdown | HTML | Rendered Output |
---|---|---|
Heading level 1 |
<h1>Heading level 1</h1> |
Heading level 1 |
Heading level 2 |
<h2>Heading level 2</h2> |
Heading level 2 |
Markdown 应用程序对于如何处理数字符号 (#) 和标题名称之间缺少的空格没有达成一致。为了兼容性,请始终在数字符号和标题名称之间添加空格。
✅ Do this | ❌ Don't do this |
---|---|
# Here's a Heading
|
#Here's a Heading
|
为了兼容性,您还应该在标题前后放置空行。
✅ Do this | ❌ Don't do this |
---|---|
Try to put a blank line before...
|
Without blank lines, this might not look right.
|
要创建段落,请使用空行分隔一行或多行文本。
Markdown | HTML | Rendered Output |
---|---|---|
I really like using Markdown.
|
<p>I really like using Markdown.</p>
|
I really like using Markdown. I think I'll use it to format all of my documents from now on. |
除非段落位于列表中,否则不要使用空格或制表符缩进段落。
注意:如果您需要在输出中缩进段落,请参阅有关如何缩进(制表符)的部分。
✅ Do this | ❌ Don't do this |
---|---|
Don't put tabs or spaces in front of your paragraphs.
|
This can result in unexpected
formatting problems.
|
要创建换行符或新行 ( <br>
),请以两个或多个空格结束一行,然后输入回车返回。
Markdown | HTML | Rendered Output |
---|---|---|
This is the first line.
|
<p>This is the first line.<br>
|
This is the first line. |
在几乎每个 Markdown 应用程序中,您都可以使用两个或多个空格(通常称为“尾随空白”)作为换行符,但这是有争议的。在编辑器中很难看到尾随空格,许多人无意或故意在每个句子后添加两个空格。因此,您可能需要使用尾随空格以外的其他内容作为换行符。如果您的 Markdown 应用程序支持 HTML,您可以使用<br>
HTML 标签。
为了兼容性,请在行尾使用尾随空格或HTML<br>
标记。
我不建议使用其他两个选项。CommonMark 和其他一些轻量级标记语言允许您在行尾键入反斜杠 (),但并非所有 Markdown 应用程序都支持此功能,因此从兼容性角度来看,这不是一个很好的选择。至少有一些轻量级标记语言不需要在行尾添加任何内容——只需键入返回,它们就会创建一个换行符。
✅ Do this | ❌ Don't do this |
---|---|
First line with two spaces after.
|
First line with a backslash after.\
|
您可以通过将文本设为粗体或斜体来强调。
要加粗文本,请在单词或短语前后添加两个星号或下划线。要加粗单词的中间以强调,请在字母周围添加两个星号,且字母周围不留空格。
Markdown | HTML | Rendered Output |
---|---|---|
I just love **bold text**. |
I just love <strong>bold text</strong>. |
I just love bold text. |
I just love __bold text__. |
I just love <strong>bold text</strong>. |
I just love bold text. |
Love**is**bold | Love<strong>is</strong>bold |
Loveisbold |
Markdown 应用程序对于如何处理单词中间的下划线没有达成一致。为了兼容性,请使用星号将单词中间加粗以示强调。
✅ Do this | ❌ Don't do this |
---|---|
Love**is**bold
|
Love__is__bold
|
要将文本设置为斜体,请在单词或短语之前和之后添加一个星号或下划线。要使单词的中间斜体以强调,请在字母周围添加一个星号,且字母周围不留空格。
Markdown | HTML | Rendered Output |
---|---|---|
Italicized text is the *cat's meow*. |
Italicized text is the <em>cat's meow</em>. |
Italicized text is the cat’s meow. |
Italicized text is the _cat's meow_. |
Italicized text is the <em>cat's meow</em>. |
Italicized text is the cat’s meow. |
A*cat*meow |
A<em>cat</em>meow |
Acatmeow |
Markdown 应用程序对于如何处理单词中间的下划线没有达成一致。为了兼容性,请使用星号将单词中间斜体化以强调。
✅ Do this | ❌ Don't do this |
---|---|
A*cat*meow
|
A_cat_meow
|
要同时用粗体和斜体强调文本,请在单词或短语前后添加三个星号或下划线。要将单词中间加粗和斜体以强调,请在字母周围添加三个星号,且字母周围不留空格。
Markdown | HTML | Rendered Output |
---|---|---|
This text is ***really important***. |
This text is <em><strong>really important</strong></em>. |
This text is really important. |
This text is ___really important___. |
This text is <em><strong>really important</strong></em>. |
This text is really important. |
This text is __*really important*__. |
This text is <em><strong>really important</strong></em>. |
This text is really important. |
This text is **_really important_**. |
This text is <em><strong>really important</strong></em>. |
This text is really important. |
This is really***very***important text. |
This is really<em><strong>very</strong></em>important text. |
This is reallyveryimportant text. |
注意:em和标签的顺序strong可能会颠倒,具体取决于您使用的 Markdown 处理器。
Markdown 应用程序对于如何处理单词中间的下划线没有达成一致。为了兼容性,请使用星号将单词中间加粗和斜体以强调。
✅ Do this | ❌ Don't do this |
---|---|
This is really***very***important text.
|
This is really___very___important text.
|
要创建块引用,请在段落前面添加>
。
1 | > Dorothy followed her through many of the beautiful rooms in her castle. |
渲染的输出如下所示:
Dorothy followed her through many of the beautiful rooms in her castle.
块引用可以包含多个段落。>
在段落之间的空白行上添加一个。
1 | >Dorothy followed her through many of the beautiful rooms in her castle. |
渲染的输出如下所示:
Dorothy followed her through many of the beautiful rooms in her castle.
The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
块引用可以嵌套。>>
在要嵌套的段落前面添加一个。
1 | > Dorothy followed her through many of the beautiful rooms in her castle. |
渲染的输出如下所示:
Dorothy followed her through many of the beautiful rooms in her castle.
The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
块引用可以包含其他 Markdown 格式的元素。并非所有元素都可以使用 - 您需要进行试验以了解哪些元素有效。
1 | > #### The quarterly results look great! |
渲染的输出如下所示:
The quarterly results look great!
- Revenue was off the chart.
- Profits were higher than ever.
Everything is going according to plan.
为了兼容性,请在块引号之前和之后放置空行。
✅ Do this | ❌ Don't do this |
---|---|
Try to put a blank line before...
|
Without blank lines, this might not look right.
|
您可以将项目组织到有序列表和无序列表中。
要创建有序列表,请添加带有数字和句点的行项目。数字不必按数字顺序排列,但列表应从数字 1 开始。
Markdown | HTML | Rendered Output |
---|---|---|
1. First item
|
<ol>
|
|
1. First item
|
<ol>
|
|
5. First item
|
<ol>
|
|
9. First item
|
<ol>
|
|
CommonMark 和其他一些轻量级标记语言允许您使用括号 ( )
) 作为分隔符(例如1) First item
),但并非所有 Markdown 应用程序都支持这一点,因此从兼容性角度来看,这不是一个很好的选择。为了兼容性,仅使用句点。
✅ Do this | ❌ Don't do this |
---|---|
1. First item
|
1) First item
|
要创建无序列表,请在行项目前面添加破折号 ( -)、星号 ( *) 或加号 (+ )。缩进一项或多项以创建嵌套列表。
Markdown | HTML | Rendered Output |
---|---|---|
- First item
|
<ul>
|
|
* First item
|
<ul>
|
|
+ First item
|
<ul>
|
|
- First item
|
<ul>
|
|
如果需要以数字后跟句点开头的无序列表项,可以使用反斜杠 ( \
)转义句点。
Markdown | HTML | Rendered Output |
---|---|---|
- 1968\. A great year!
|
<ul>
|
|
Markdown 应用程序对于如何处理同一列表中的不同分隔符并不一致。为了兼容性,不要在同一列表中混合和匹配分隔符 - 选择一个并坚持使用。
✅ Do this | ❌ Don't do this |
---|---|
- First item
|
+ First item
|
要在列表中添加另一个元素,同时保持列表的连续性,请将元素缩进四个空格或一个制表符,如以下示例所示。
提示:如果内容未按您预期的方式显示,请仔细检查是否已将列表中的元素缩进四个空格或一个制表符。
1 | * This is the first list item. |
渲染的输出如下所示:
This is the first list item.
Here’s the second list item.
I need to add another paragraph below the second list item.
And here’s the third list item.
1 | * This is the first list item. |
渲染的输出如下所示:
This is the first list item.
Here’s the second list item.
A blockquote would look great below the second list item.
And here’s the third list item.
代码块通常缩进四个空格或一个制表符。当它们位于列表中时,将它们缩进八个空格或两个制表符
1 | 1. Open the file. |
渲染的输出如下所示:
Open the file.
Find the following code block on line 21:
<head>
<title>Test</title>
</head>
Update the title to match the name of your website.
1 | 1. Open the file containing the Linux mascot. |
渲染的输出如下所示:
Open the file containing the Linux mascot.
Marvel at its beauty.
Close the file.
您可以将无序列表嵌套在有序列表中,反之亦然。
1 | 1. First item |
渲染的输出如下所示:
要将单词或短语表示为代码,请将其括在反引号 ( `) 中。
Markdown | HTML | Rendered Output |
---|---|---|
At the command prompt, type `nano`. |
At the command prompt, type <code>nano</code>. |
At the command prompt, type nano . |
如果您想要表示为代码的单词或短语包含一个或多个反引号,则可以通过将单词或短语括在双反引号 (``) 中来转义它。
Markdown | HTML | Rendered Output |
---|---|---|
``Use `code` in your Markdown file.`` |
<code>Use `code` in your Markdown file.</code> |
Use `code` in your Markdown file. |
要创建代码块,请将块的每一行缩进至少四个空格或一个制表符。
1 | <html> |
渲染的输出如下所示:
<html>
<head>
</head>
</html>
注意:要创建不缩进的代码块,请使用围栏代码块。
要创建水平线,请在一行上单独使用三个或更多星号 ( ***)、—破折号 ( ) 或下划线 ( )。___
1 | *** |
所有三个的渲染输出看起来相同:
为了兼容性,请在水平线之前和之后放置空行。
✅ Do this | ❌ Don't do this |
---|---|
Try to put a blank line before...
|
Without blank lines, this would be a heading.
|
要创建链接,请将链接文本括在方括号中(例如,[Duck Duck Go]),然后紧随其后,将 URL 放在括号中(例如,(https://duckduckgo.com))。
1 | My favorite search engine is [Duck Duck Go](https://duckduckgo.com). |
渲染的输出如下所示:
My favorite search engine is Duck Duck Go.
您可以选择为链接添加标题。当用户将鼠标悬停在链接上时,这将显示为工具提示。要添加标题,请将其放在 URL 后面的引号中。
1 | My favorite search engine is [Duck Duck Go](https://duckduckgo.com "The best search engine for privacy"). |
渲染的输出如下所示:
My favorite search engine is Duck Duck Go.
要快速将 URL 或电子邮件地址转换为链接,请将其括在尖括号中。
1 | <https://www.markdownguide.org> |
渲染的输出如下所示:
https://www.markdownguide.org
fake@example.com
要强调链接,请在方括号和括号前后添加星号。要将链接表示为code,请在括号中添加反引号。
1 | I love supporting the **[EFF](https://eff.org)**. |
渲染的输出如下所示:
I love supporting the EFF.
This is the Markdown Guide.
See the section on code
.
参考样式链接是一种特殊的链接,它使 URL 更容易在 Markdown 中显示和阅读。参考样式链接由两部分构成:与文本内联的部分和存储在文件中其他位置以使文本易于阅读的部分。
参考样式链接的第一部分采用两组括号格式化。第一组括号包围应显示为链接的文本。第二组括号显示一个标签,用于指向您存储在文档中其他位置的链接。
尽管不是必需的,但您可以在第一组和第二组括号之间包含一个空格。第二组括号中的标签不区分大小写,可以包含字母、数字、空格或标点符号。
这意味着以下示例格式与链接的第一部分大致相同:
1 | [hobbit-hole][1] |
引用样式链接的第二部分采用以下属性进行格式化:
这意味着以下示例格式对于链接的第二部分大致相同:
1 | [1]: https://en.wikipedia.org/wiki/Hobbit#Lifestyle |
您可以将链接的第二部分放置在 Markdown 文档中的任何位置。有些人将它们放在它们出现的段落之后,而另一些人将它们放在文档的末尾(如尾注或脚注)。
假设您将 URL 作为标准 URL 链接添加到段落中,它在 Markdown 中如下所示:
1 | In a hole in the ground there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends |
尽管它可能指向有趣的附加信息,但显示的 URL 除了使其更难以阅读之外,实际上并没有给现有的原始文本添加太多内容。要解决此问题,您可以像这样设置 URL 格式:
1 | In a hole in the ground there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends |
在上面的两个实例中,渲染的输出将是相同的:
In a hole in the ground there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends
of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to
eat: it was a hobbit-hole, and that means comfort.
链接的 HTML 为:
1 | <a href="https://en.wikipedia.org/wiki/Hobbit#Lifestyle" title="Hobbit lifestyles">hobbit-hole</a> |
Markdown 应用程序对于如何处理 URL 中间的空格并不一致。为了兼容性,请尝试对任何空格进行 URL 编码%20。或者,如果您的 Markdown 应用程序支持 HTML,您可以使用 HTML a
标签。
✅ Do this | ❌ Don't do this |
---|---|
[link](https://www.example.com/my%20great%20page)
|
[link](https://www.example.com/my great page)
|
URL 中间的括号也可能会出现问题。为了兼容性,请尝试对左括号 ( (
)进行 URL 编码%28
,对右括号 ( )
) 进行URL 编码%29
。或者,如果您的 Markdown 应用程序支持 HTML,您可以使用HTML a
标签。
✅ Do this | ❌ Don't do this |
---|---|
[a novel](https://en.wikipedia.org/wiki/The_Milagro_Beanfield_War_%28novel%29)
|
[a novel](https://en.wikipedia.org/wiki/The_Milagro_Beanfield_War_(novel))
|
要添加图像,请添加感叹号 ( !
),后跟括号中的替代文本,并在括号中添加图像资源的路径或 URL。您可以选择在路径或 URL 后面添加带引号的标题。
1 |  |
渲染的输出如下所示:
要添加图像链接,请将图像的 Markdown 括在括号中,然后在括号中添加链接。
1 | [](https://www.flickr.com/photos/beaurogers/31833779864/in/photolist-Qv3rFw-34mt9F-a9Cmfy-5Ha3Zi-9msKdv-o3hgjr-hWpUte-4WMsJ1-KUQ8N-deshUb-vssBD-6CQci6-8AFCiD-zsJWT-nNfsgB-dPDwZJ-bn9JGn-5HtSXY-6CUhAL-a4UTXB-ugPum-KUPSo-fBLNm-6CUmpy-4WMsc9-8a7D3T-83KJev-6CQ2bK-nNusHJ-a78rQH-nw3NvT-7aq2qf-8wwBso-3nNceh-ugSKP-4mh4kh-bbeeqH-a7biME-q3PtTf-brFpgb-cg38zw-bXMZc-nJPELD-f58Lmo-bXMYG-bz8AAi-bxNtNT-bXMYi-bXMY6-bXMYv) |
渲染的输出如下所示:
要显示原本用于格式化 Markdown 文档中文本的文字字符,请在该字符前面添加反斜杠 (\
)。
1 | \* 如果没有反斜杠,这将是无序列表中的项目符号。 |
渲染的输出如下所示:
* 如果没有反斜杠,这将是无序列表中的项目符号。
您可以使用反斜杠转义以下字符。
特点 | 姓名 |
---|---|
\ | 反斜杠 |
` | 反引号(另请参阅代码中转义反引号) |
* | 星号 |
_ | 下划线 |
{ } | 大括号 |
[ ] | 括号 |
< > | 尖括号 |
( ) | 括号 |
# | 英镑符号 |
+ | 加号 |
- | 减号(连字符) |
。 | 点 |
! | 感叹号 |
| | 管道(另请参阅表中的转义管道) |
许多 Markdown 应用程序允许您在 Markdown 格式的文本中使用 HTML 标签。如果您更喜欢某些 HTML 标签而不是 Markdown 语法,这会很有帮助。例如,有些人发现对图像使用 HTML 标签更容易。当您需要更改元素的属性(例如指定文本的颜色或更改图像的宽度)时,使用 HTML 也很有帮助。
要使用 HTML,请将标签放置在 Markdown 格式文件的文本中。
1 | This **word** is bold. This <em>word</em> is italic. |
渲染的输出如下所示:
This word is bold. This word is italic.
出于安全原因,并非所有 Markdown 应用程序都支持 Markdown 文档中的 HTML。如有疑问,请检查 Markdown 应用程序的文档。某些应用程序仅支持 HTML 标记的子集。
使用空行将块级 HTML 元素(如<div>
、<table>
、<pre>
和<p>
)与周围的内容分开。尽量不要用制表符或空格缩进标签——这可能会干扰格式。
您不能在块级 HTML 标记内使用 Markdown 语法。例如,<p>italic and **bold**</p>
不会起作用。
原始 Markdown 设计文档中概述的基本语法添加了日常所需的许多元素,但这对某些人来说还不够。这就是扩展语法的用武之地。
一些个人和组织自行扩展了基本语法,添加了表格、代码块、语法突出显示、URL 自动链接和脚注等附加元素。这些元素可以通过使用基于基本 Markdown 语法的轻量级标记语言或通过向兼容的 Markdown 处理器添加扩展来启用。
并非所有 Markdown 应用程序都支持扩展语法元素。您需要检查您的应用程序使用的轻量级标记语言是否支持您想要使用的扩展语法元素。如果没有,您仍然可以在 Markdown 处理器中启用扩展。
有几种轻量级标记语言是Markdown 的超集。它们包括基本语法,并在此基础上添加其他元素,如表格、代码块、语法突出显示、URL 自动链接和脚注。许多最流行的 Markdown 应用程序都使用以下轻量级标记语言之一:
有数十种 Markdown 处理器可用。其中许多允许您添加启用扩展语法元素的扩展。检查处理器的文档以获取更多信息。
要添加表,请使用三个或更多连字符 ( ---
) 创建每列的标题,并使用竖线 (|
) 分隔每列。为了兼容性,您还应该在行的两端添加管道。
1 | | Syntax | Description | |
渲染的输出如下所示:
Syntax | Description |
---|---|
Header | Title |
Paragraph | Text |
单元格宽度可能会有所不同,如下所示。渲染的输出看起来是一样的。
1 | | Syntax | Description | |
提示:创建带有连字符和竖线的表可能很乏味。要加快该过程,请尝试使用Markdown Tables Generator或AnyWayData Markdown Export。使用图形界面构建表格,然后将生成的 Markdown 格式文本复制到文件中。
您可以通过在标题行中连字符的左侧、右侧或两侧添加冒号 (:
),将列中的文本向左、向右或居中对齐。
1 | | Syntax | Description | Test Text | |
渲染的输出如下所示:
Syntax | Description | Test Text |
---|---|---|
Header | Title | Here’s this |
Paragraph | Text | And more |
您可以设置表格内文本的格式。例如,您可以添加链接、代码仅反引号(`) 中的单词或短语,而不是代码块。
您不能使用标题、块引用、列表、水平线、图像或大多数 HTML 标记。
提示:您可以使用 HTML 创建换行符并在表格单元格内添加列表。
你可以使用HTML字符代码 (|
)在表中显示竖线(|
)
The basic Markdown syntax allows you to create code blocks by indenting lines by four spaces or one tab. If you find that inconvenient, try using fenced code blocks. Depending on your Markdown processor or editor, you’ll use three backticks (```
) or three tildes (~~~
) on the lines before and after the code block. The best part? You don’t have to indent any lines!
基本的 Markdown 语法允许您通过将行缩进四个空格或一个制表符来创建代码块。如果您发现这不方便,请尝试使用受隔离的代码块。根据您的 Markdown 处理器或编辑器,您将在代码块之前和之后的行上使用三个反引号 ( ```) 或三个波形符 ( ~~~)。最好的部分?您不必缩进任何行!
1 | ``` |
渲染的输出如下所示:
1 | { |
提示:需要在代码块内显示反引号吗?请参阅本节以了解如何逃避它们。
许多 Markdown 处理器支持围栏代码块的语法突出显示。此功能允许您为编写代码所用的任何语言添加颜色突出显示。要添加语法突出显示,请在受隔离的代码块之前的反引号旁边指定一种语言。
1 | ```json |
渲染的输出如下所示:
1 | { "firstName": "John", "lastName": "Smith", "age": 25 } |
脚注允许您添加注释和参考文献,而不会弄乱文档的正文。创建脚注时,您添加脚注引用的位置会出现带有链接的上标编号。读者可以点击链接跳转至页面底部脚注内容。
要创建脚注引用,请在方括号 ([^1]
) 内添加插入符号和标识符。标识符可以是数字或单词,但不能包含空格或制表符。标识符仅将脚注引用与脚注本身相关联 - 在输出中,脚注按顺序编号。
使用另一个插入符号和括号内的数字以及冒号和文本 ([^1]: 脚注笔记xxx.
) 添加脚注。您不必在文档末尾添加脚注。您可以将它们放在除列表、块引用和表格等其他元素内之外的任何位置。
1 | 这是一个简单的脚注,[^1] 这是另一个更长的脚注.[^bignote] |
渲染的输出如下所示:
这是一个简单的脚注,^1 这是另一个更长的脚注.^bignote
缩进段落以将其置于脚注内。
`{ test code }`
添加任意数量段落。
许多 Markdown 处理器支持自定义标题ID——一些 Markdown 处理器会自动添加它们。添加自定义 ID 允许您直接链接到标题并使用 CSS 修改它们。要添加自定义标题 ID,请将自定义 ID 括在与标题同一行的大括号中。
1 | ### My Great Heading {#custom-id} |
HTML 看起来像这样:
1 | <h3 id="custom-id">My Great Heading</h3> |
您可以通过创建一个带有数字符号 (#)后跟自定义标题ID 的标准链接来链接到文件中具有自定义 ID 的标题。这些通常称为锚链接。
Markdown | HTML | Rendered Output |
---|---|---|
[标题ID](#标题ID) |
<a href="#标题ID">标题ID</a> |
Heading IDs |
其他网站可以通过将自定义标题 ID 添加到网页的完整 URL 来链接到该标题(例如,标题 ID)。
某些 Markdown 处理器允许您创建术语及其相应定义的定义列表。要创建定义列表,请在第一行键入术语。在下一行中,键入冒号,后跟空格和定义。
1 | First Term |
HTML 看起来像这样:
1 | <dl> |
渲染的输出如下所示:
您可以通过在单词中心划一条水平线来删除单词。结果看起来像这样。此功能允许您指出某些单词是错误的,不应包含在文档中。要删除单词,请在单词前后使用两个波浪号 (~~)。
1 | ~~The world is flat.~~ We now know that the world is round. |
渲染的输出如下所示:
The world is flat. We now know that the world is round.
任务列表(也称为清单和待办事项列表)允许您创建带有复选框的项目列表。在支持任务列表的 Markdown 应用程序中,复选框将显示在内容旁边。要创建任务列表,请在任务列表项前面添加破折号 (-) 和方括号以及空格 ([ ])。要选择复选框,请在方括号 ([x]) 之间添加 x。
1 | - [x] Write the press release |
渲染的输出如下所示:
有两种方法可以将表情符号添加到 Markdown 文件中:将表情符号复制并粘贴到 Markdown 格式的文本中,或者输入表情符号简码。
在大多数情况下,您只需从Emojipedia等来源复制表情符号并将其粘贴到文档中即可。许多 Markdown 应用程序会自动以 Markdown 格式的文本显示表情符号。从 Markdown 应用程序导出的 HTML 和 PDF 文件应显示表情符号。
提示:如果您使用静态站点生成器,请确保将HTML页面编码为 UTF-8。
某些 Markdown 应用程序允许您通过输入表情符号短代码来插入表情符号。它们以冒号开头和结尾,并包含表情符号的名称。
1 | Gone camping! :tent: Be back soon. |
渲染的输出如下所示:
Gone camping! ⛺ Be back soon.
That is so funny! 😂
注意:您可以使用此表情符号短代码列表,但请记住,表情符号短代码因应用程序而异。有关详细信息,请参阅 Markdown 应用程序的文档。
这并不常见,但某些 Markdown 处理器允许您突出显示文本。结果看起来像这样。要突出显示单词,请在单词前后使用两个等号 (==
)。
1 | I need to highlight these ==very important words==. |
渲染的输出如下所示:
I need to highlight these ==very important words==.
或者,如果您的 Markdown 应用程序支持 HTML,您可以使用 mark
HTML 标签
1 | I need to highlight these <mark>very important words</mark>. |
这并不常见,但某些 Markdown 处理器允许您使用下标将一个或多个字符定位在略低于正常类型行的位置。要创建下标,请在字符前后使用一个波浪号 (~
)。
1 | H~2~O |
渲染的输出如下所示:
H2O
提示: 使用之前,请务必在 Markdown 应用程序中对其进行测试。某些 Markdown 应用程序在单词前后使用一个波形符,不是用于下标,而是用于删除线。
或者,如果您的 Markdown 应用程序支持 HTML,您可以使用 sub
HTML 标签。
1 | H<sub>2</sub>O |
这并不常见,但某些 Markdown 处理器允许您使用上标将一个或多个字符放置在稍高于正常类型行的位置。要创建上标,请在字符前后使用一个插入符号 (^
)。
1 | X^2^ |
渲染的输出如下所示:
X^2^
或者,如果您的 Markdown 应用程序支持 HTML,您可以使用sup HTML 标签。
1 | X<sup>2</sup> |
许多 Markdown 处理器会自动将 URL 转换为链接。这意味着,如果您输入 http://www.example.com
,即使您没有使用括号,您的 Markdown 处理器也会自动将其转换为链接。
1 | http://www.example.com |
渲染的输出如下所示:
如果您不希望自动链接某个 URL,则可以通过将 URL 表示为带反引号的代码来删除该链接。
渲染的输出如下所示:
http://www.example.com
Two Simple Multi-Statement Functions
If you search the web, there is no end of functions to split strings into table format. Here, I will present two simple functions that run on SQL 2008 or later, one for a list of integers and one for a list of strings. I should immediately warn you that these functions are not the most efficient and therefore not suitable if you have long lists with thousands of elements. But they are perfectly adequate if you are passing the contents of a multi-choice checkbox from a client where you would rarely have as many as 50 elements.
I opted to share these functions because they are simple and you can easily adapt them if you want different behaviour with regards to the choices that I have made. In my long article, I describe methods that are faster, but they all require extra setup than just a function.
Below is a function to split a delimited list of integers. The function accepts a parameter for the delimiter which can be up to 10 characters long. The function returns the list positions for the elements. An empty element is returned as NULL. If there is a non-numeric value in the list, there will be a conversion error.
1 | CREATE FUNCTION intlist_to_tbl (@list nvarchar(MAX), |
You are likely to be puzzled by the COLLATE clause. This is a small speed booster. By forcing a binary collation, we avoid that SQL Server employs the full Unicode rules when searching for the delimiter. This pays off when scanning long strings. Why Czech? The language does not matter here, so I just picked one with a short name.
And why datalength divided by 2 and not len? datalength returns the length in bytes, whence the division. len does not count trailing spaces, so it does not work if the delimiter is a space.
Here are two examples:
1 | SELECT * FROM intlist_to_tbl('1,2,3, 677,7 , ,-1', ',') |
Since the values are the same in both lists, the output is the same:
listpos | n |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
4 | 677 |
5 | 7 |
6 | NULL |
7 | -1 |
Here is an example of how you would use it in a simple query:
1 | SELECT ... |
If you find that you are only using comma-separated lists, you may grow tired of having to specify the delimiter every time. To that end, this wrapper can be handy:
1 | CREATE FUNCTION intlisttotbl (@list nvarchar(MAX)) RETURNS TABLE AS |
I leave it as an exercise to the reader to come up with a better name.
Here is a function for a list of strings. It accepts an input parameter of the type nvarchar(MAX), but the return table has both a varchar and an nvarchar column. I will return to why in a second. Like intlist_to_tbl it returns the list position. It trims leading and trailing spaces. In difference to intlist_to_tbl, empty elements are returned as empty strings and not as NULL.
1 | CREATE FUNCTION strlist_to_tbl (@list nvarchar(MAX), |
Here are two examples:
1 | SELECT * FROM strlist_to_tbl(N'Alpha (α) | Beta (β)|Gamma (γ)|Delta (δ)|', '|') |
Here is the output:
listpos | str | nstr
|:–:|:–:|:–:|
1 | Alpha (a)| Alpha (α)
2 | Beta (ß) | Beta (β)
3 | Gamma (?)| Gamma (γ)
4 | Delta (d)| Delta (δ)
5 | | |
listpos | str | nstr
|:–:|:–:|:–:|
1 | a | a
2 | b | b
3 | c | c
4 | v | v
5 | x | x
Note in the first result set that the Greek characters has been replaced by fallback characters in the str column. They are unchanged in the nstr column. (If you have a Greek or a UTF-8 collation, the two columns will be identical, though.)
Here are two examples of using this function:
1 | SELECT ... |
These examples illustrate why there are two columns. If you are going to use the list against a varchar column, you need to use the str column. This is important because of the type-conversion rules in SQL Server. If you mistakenly compare varcharcol to nstr, varcharcol will be converted to nvarchar, and this can render any index on varcharcol ineligible for the query, leading to a performance disaster as the table must be scanned. And conversely, if you have an nvarchar column, you need to compare it to the nvarchar value, since else the result can be incorrect because of the character replacement with the conversion to varchar.
I like to point out that these functions are by no means cast in stone, but see them as suggestions. Feel free to modify them according to your preferences and needs.
Update your browser to view this website correctly.&npsb;Update my browser now