查看Linux发行版本的方法
- cat /etc/issue,适用于所有的发行版本
- lsb_release -a,也适用于所有的发行版本,但是有些发行版本(尤其是一些精简版的镜像)可能没有预置lsb_release,需要手动安装。
- cat /etc/redhat-release,这种方法只适合Redhat系的发行版本,包括CentOS
- cat /etc/centos-release,只适用于CentOS
查看Linux内核版本命令
- cat /proc/version
- uname -a
查看Linux发行版本的方法
查看Linux内核版本命令
最近被问到如下的一道题:
$x = false; $i = 9; for ($i = 9; $i > $x; $i -= 2) { echo $i . "\n"; } //请说出代码执行后的输出结果。
一般想到int类型$i和bool类型的$x比较,bool类型的false会被转换成int类型的0,所以代码块会有5次输出后停止结束。
那么实际执行结果是怎样的呢?
实际执行一次,就会发现,结果是无限循环输出:9,7,5,3,1,-1,-3,-5,……。
为什么呢?
仔细查看PHP文档:https://www.php.net/manual/en/language.operators.comparison.php
会发现有这样的描述:
Type of Operand 1 | Type of Operand 2 | Result |
---|---|---|
null or string | string | Convert null to “”, numerical or lexical comparison |
bool or null | anything | Convert both sides to bool, false < true |
object | object | Built-in classes can define its own comparison, different classes are uncomparable, same class see Object Comparison |
string, resource, int or float | string, resource, int or float | Translate strings and resources to numbers, usual math |
array | array | Array with fewer members is smaller, if key from operand 1 is not found in operand 2 then arrays are uncomparable, otherwise – compare value by value (see following example) |
object | anything | object is always greater |
array | anything | array is always greater |
其中第二行就有关于bool类型和其他类型的比较,有明确说明,会把其他类型转换成bool类型。那么上文中的这道题,$i总是不等于0,即意味着$i总是会被转换成bool类型的true,true永远大于false,所以会有无限循环的输出。
这两个概念单独解释其实很简单,但是混在一起可能会说不清。正好看到网上有人聊起了这个,我就做个整理,也当知识回顾。
问题:为什么要用 jwt token 来做身份认证,而不是使用session+cookie方式?
那么我们先看概念本身的解释:
JWT ——JSON Web Token
JWE——JSON Web Encryption
JWS——JSON Web Signature
Session,此处可以翻译为会话,指客户端和服务端维持有状态的一种通信机制。根据Session Data的存储位置,可以分为Server Side Session和 Client Side Session。一般说的session & cookie机制是指使用的Server Side Session。
所以JWT和Session不是同一个概念的东西,没法拿来比较。回头再看这个问题就发现有点意思了。我们使用jwt token来做身份认证,我们可以把jwt token(会含有一些用户信息)通过cookie、HTTP头,url参数等多种方式下发给客户端(Client Side Session)从而实现session机制;而传统的服务端session-data + session-id(by cookie)方式,session-id只是一串随机字符串,不用解析,在和服务端交互时直接原样传输就行了。所以原作者问题可能是Server Side Session和Client Side Session的区别!
References:
https://en.wikipedia.org/wiki/JSON_Web_Token
https://blog.by24.cn/archives/about-session.html
https://www.v2ex.com/t/774127
如题,这个问题第一感觉是1MB肯定等于1024KB,只有在硬盘生产厂商那里才会使用1000进制。事实是如此吗?最近被人补了一课,了解单位换算中的两种标准。
按照国际单位制的标准: 1MB=1000KB (1Megabyte = 1000Kilobyte)
按照IEC 60027-2标准: 1MiB=1024KiB (1Mebibyte = 1024 Kibibyte)
字节的次方单位 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
所以严格来说如果显示为1MB,则说明使用的是国际单位制标准,等于1000KB。1MiB说明是使用的IEC 60027-2标准,等于1024KiB。
References:
固态硬盘或固态驱动器(英语:Solid-state drive或Solid-state disk,简称SSD)是一种以集成电路制作的电脑存储设备。
最近如果你要买SSD,可能会频繁接触到M.2,NVMe,PCIe这几个名词。我上一次单独买SSD时,虽然已经是M.2接口了,但是当时没见NVMe协议,最近正好关心了SSD,就正好接机学习了解下。
下面这个短视频有很生动的介绍:
https://www.youtube.com/watch?v=alb6-zp52mA&t=505s
NVM Express(缩写NVMe),或称非易失性内存主机控制器接口规范(英语:Non-Volatile Memory Host Controller Interface Specification,缩写:NVMHCIS),是一个逻辑设备接口规范。它是基于设备逻辑接口的总线传输协议规范(相当于通讯协议中的应用层),用于访问通过PCI Express(PCIe)总线附加的非易失性存储器介质(例如采用闪存的固态硬盘驱动器),虽然理论上不一定要求PCIe总线协议。NVMe是一种协议,是一组允许SSD使用PCIe总线的软硬件标准;而PCIe是实际的物理连接通道。
所以当下性能最佳的SSD的技术方案组合应该是:M.2接口+NVMe+PCIe。早些年在NVMe普及之前,有M.2接口+AHCI+SATA的SSD。SATA接口+AHCI+SATA总线的SSD也有,估计都是没有M.2接口的老电脑升级用吧,现在京东上都还有卖的。
References:
https://zh.wikipedia.org/wiki/PCI_Express
https://zh.wikipedia.org/wiki/SATA
https://zh.wikipedia.org/wiki/SATA_Express
(SFFWG Renames PCIe SSD SFF-8639 Connector To U.2)
https://zh.wikipedia.org/wiki/NVM_Express
https://zh.wikipedia.org/wiki/M.2
《中国近代史》——蒋廷黻(著)
最后更新时间:2021-01-06
黻(fú)
- 古代礼服上黑与青相间的花纹:黼~。
- 同“韨”。
琦善
琦(qí)
- 美玉。
- 珍奇,美好:~玮(奇丽的意思)。瑰意~行。
马戛尔尼(乔治·马戛尔尼,George Macartney)
戛(jiá)
- 长矛。
- 敲,敲打。
- 常礼;常法。
- 刮。
- 象声词:~然长鸣。
恭亲王奕(yì)䜣(xīn)
郭嵩焘(guo song tao)
伊里布和耆英
耆(qí)
- 年老,六十岁以上的人:~老。~年。~绅。~宿(sù)(指在社会上有名望的老年人)。
- 强横。
端王载漪子溥(pǔ)隽(jùn)
漪(yī)
水波纹:~沦。~澜。清~。涟~(细小的波纹)。
隽(jùn)
古同“俊”。
《中国近代史》是蒋廷黻所著的,于1938年首次出版的中国近代史研究的重要著作。他作为一个“知外交”的学者和政客,从外交的角度讲述中国近代史以及从外交的角度分析近代历史事件发生的原因,背景。
在讲述鸦片战争爆发前后清政府(实际更多是地方官员自主决定)与英国(商人、政府代表)交涉的过程中,通过史料讲述了清政府官员对外的极其无知,从上到下不了解外面的世界,不愿意给外国平等交往的机会;在交涉的过程中,又极其自大,不守诚信,不主动了解敌人情况,很多事情都凭道听途说和意淫。战争失败后,不能接受失败思检讨问题,认清差距,反而对外争执一些无关紧要的内容,对关于主权的事情放任英国制定规则(当然作者也知道,我们是以后来着的角度来看待这个问题,觉得痛心棘手,当时人并不觉得)。
协定关税和治外法权是我们近些年所认为不平等条约的核心,可是当时的人却并不这样看治外法权,在道光时代的人的目光中,不过是“让夷人管夷人”。他们想那是最方便、最省事的办法。至于协定关税,他们觉得也是方便省事的办法。每种货物应该纳多少税都明白地载于条约,那就可以省去争执。负责交涉条约的人如伊里布、耆英、黄恩彤诸人知道战前广东地方官吏的苛捐杂税是引起战争原因之一,现在把收税标准明文规定岂不是一个釜底抽薪,一劳永逸的办法?而且,新的收税标准平均到5%,比旧日的自主关税还要略微高一点。负交涉责任者计算以后的海关收入比以前还要多,所以他们洋洋得意,以为他们的外交是成功的。其实,他们牺牲了国家的主权,贻害不少。总而言之,道光年间的中国人完全不懂国际公法和国际形势,所以他们争所不应争的,放弃所不应放弃的。
想起了书中关于海关税收的内容了。在下篇“外交策略不进反退“一节中,作者认为在康熙中后期的外交是积极的,对外平等的(在涉及和俄国签订尼布楚条约的章节有讲到)。之后的时间里基本都是开倒车。关于税收税率和规则有一段很深刻的描述:
清政府正式设海关监督,规定粤海关由内务府派,闽海关由福州将军兼,浙海关及江海关的由各省巡抚兼。按法律,中国旧关税制度完备极了、公道极了。康熙的训谕说:“各省关钞之设,原期通商利民以资国用”;“国家设关榷税,必征输无弊,出入有经,庶百物流通,民生饶裕”。世宗的旨趣相同:“国家之设关税,所以通商而非累商,所以便民而非病民也。”乾隆也说过:“朕思商民皆为赤子,轻徭薄赋,俾人民实沾惠泽,乃朕爱养黎庶之本怀。”户部颁有税则,其平均率不到百分之五,比《南京条约》以后的协定税则还要低廉。
……
很明显的,中国自十七世纪末年起,已有了法定的、公开的海关税则。
实际上,中国海关收税的情形不但离高尚道德甚远,且与法律绝不相符。直到鸦片战争,外商不知中国的税则的模样。历康雍乾嘉四朝,外人索看海关税则多次,每次概被衙门拒绝。关税分两种:船钞与货税。照户部的章程,船钞应丈量船的大小而定:大船约纳一千二百两,中船约九百六十两,小船约五百四十两。实际除船钞外,还须“官礼”。在十七世纪末年,官礼的多少,每次须讲价。到康熙末年,十八世纪初年,官礼渐成固定:不问船的大小,概须送一千九百五十两,比正钞还多。货税也有正税及“陋规”。陋规最初也是由收税者及纳税者临时去商议,到康熙末年,大约已达货价百分之六,比正税亦大。雍正初年,杨文乾以巡抚兼关监督的时候,官礼报部归公,于是官吏在货税上加了百分之十的陋规,名曰“缴送”。正税及各种陋规总起来约当百分之二十,这是中国实行的税则。
在讲曾国藩时,作者认为,曾国藩技术革新和思想守旧两条路一起走,在对抗太平天国过程中起到重要作用。但是对于一个国家、民族振兴而言是远远不够的,是必然会失败的。作者认为失败原因两点:曾国藩为代表的改革派本身由于成长经历,思想素质等原因不愿因全面改革(比如不赞同政体改革,……);另外一点就是反对者总舵,阻力太大。
作者虽然“知外交”,但却不是鼓吹外交决定一切的人。书里,作者有一句特别让我感慨:“在近代世界,败仗是千万不能打的。”。所以作者在讲到中日在朝鲜的争端时有说到:“近代战争固不是儿戏。不战而求和当然要吃亏……但战败以后而求和,吃亏之大远过于不战而和。”
总体而言我觉得这本书还是蛮好的。对于1840~1912年间,几个大事件和时人为之努力(改革)的分析很精彩。
名句摘录:
中西的关系是特别的。在鸦片战争以前,清政府不肯给外国平等待遇;在以后,西方国家不肯给清政府平等待遇。
在维持清政府作为政治中心的大前提之下,曾国藩的工作分两方面进行。一方面他要革新,那就是说,他要接受西洋文化的一部分;另一方面他要守旧,那就是说,恢复中国固有的美德。革新守旧同时举行,这是曾国藩对中国近代史的大贡献。
曾国藩及其他自强运动的领袖虽然走的路线不错,然而他们不能救国救民族。此其故何在?在于他们的不彻底。他们为什么不彻底呢?一部分因为他们自己不要彻底,大部分因为时代不容许他们彻底。我们试先研究领袖们的短处。
恭亲王奕、文祥、曾国藩、李鸿章、左宗棠这五个大领袖都出身于旧社会,受的都是旧教育。他们没有一个人能读外国书,除李鸿章以外,没有一个人到过外国。就是李鸿章的出洋尚在甲午战败以后,他的建设事业已经过去了。这种人能毅然决然推行新事业就了不得,他们不能完全了解西洋文化是自然的,很可原谅的。他们对于西洋的机械是十分佩服的,十分努力要接受的。他们对于西洋的科学也相当尊重,并且知道科学是机械的基础。但是,他们自己毫无专业的机械常识,此外更不必说了。他们觉得中国的政治制度及立国精神是至善至美,无须学西方的。事实上他们的建设事业就遭了旧的制度和旧的精神文化的阻碍。
总之,资本主义可变为帝国主义,也可以不变为帝国主义。未开发的国家容易受资本主义的国家的压迫和侵略,也可以利用外国的资本来开发自己的富源及利用国际的通商来提高人民的生活程度。资本主义如同水一样:水可以资灌溉,可以便利交通,也可以成灾,要看人怎样对付。
同时我们不要把帝国主义看得过于简单,以为世界上没有资本主义就没有帝国主义了。…… 据我们所知,历史上各种政体,君主也好,民主也好,各种社会经济制度,资本主义也好,封建主义也好,共产主义也好,都有行帝国主义的可能。
在近代世界,败仗是千万不能打的。
我们不要以为顽固分子不爱国,从鸦片战争起,他们是一贯的反对屈服,坚强的主张抗战。
近代战争固不是儿戏。不战而求和当然要吃亏……但战败以后而求和,吃亏之大远过于不战而和。
马戛尔尼的外交失败是由于中西方邦交观念之不相容。中国抱定“天朝统驭万国”的观念,不承认有所谓“国际”者存在;西方在近代则步步地推演出国际生活及其所需的惯例和公法。马戛尔尼的失败证明中国绝不愿意自动或和平地放弃这种传统观念。因此中国外交史有一大特点:除康熙亲政初年外,中外曾无平等邦交的日子。在鸦片战争以前,中国居上,外国居下;鸦片战争以后则相反。
UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式:从UTC 1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒。在多数Unix系统上Unix时间可以透过date +%s指令来检查。(Unix time (also known as Epoch time, POSIX time, seconds since the Epoch, or UNIX Epoch time) is a system for describing a point in time. It is the number of seconds that have elapsed since the Unix epoch.) (英 [ˈiːpɒk] 美 [ˈepək])
从这个解释可以看出来,同一时刻,在全世界任一时区,获取的Unix时间戳是相同的。
所以,针对PHP而言,time()函数获取的到时间戳与时区无关。
time ( ) : int
Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
那么,进一步延伸,对于一个给定的日期时间字符串,例如:2020-01-01 00:00:00,那么获取这个日期时间对应的时间戳就是与时区有关的。因为不同时区下的2020-01-01 00:00:00距离UTC的1970-01-01 00:00:00的时间间隔是不一样的。
strtotime ( string $datetime [, int $now = time() ] ) : int
对于PHP而言,在使用strtotime函数时,如果日期时间字符串中没有包含时区信息,那么会使用默认的时区date_default_timezone_get()。(Each parameter of this function uses the default time zone unless a time zone is specified in that parameter. Be careful not to use different time zones in each parameter unless that is intended. )
$dateStr = '2020-01-01 00:00:00'; $timezone = 'Asia/Shanghai'; date_default_timezone_set($timezone); echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStr, strtotime($dateStr)); $dateStrWithTimezone = '2020-01-01T00:00:00+08:00'; date_default_timezone_set($timezone);//优先读取日期时间字符串里的时区信息,此处单独设置的时区对下一行的strtotime无效 echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStrWithTimezone, strtotime($dateStrWithTimezone)); $timezone = 'UTC'; date_default_timezone_set($timezone); echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStr, strtotime($dateStr)); echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStrWithTimezone, strtotime($dateStrWithTimezone)); output: Asia/Shanghai)2020-01-01 00:00:00 ==> 1577808000 Asia/Shanghai)2020-01-01T00:00:00+08:00 ==> 1577808000 UTC)2020-01-01 00:00:00 ==> 1577836800 UTC)2020-01-01T00:00:00+08:00 ==> 1577808000 //优先读取日期时间字符串里的时区信息,runtime设置的时区对strtotime无效
date ( string $format [, int $timestamp = time() ] ) : string
Format a local time/date
同样的道理,同一个时间戳在不同的时区下,对应的日期时间字符串是不一样的。
date_default_timezone_set('UTC'); $timestamp = 1577836800;//UTC 2020-01-01 00:00:00 $sourceDatetime = new \DateTime(date('Y-m-d H:i:s', $timestamp)); echo sprintf("source datetime:%s(%s)\n", $sourceDatetime->format('Y-m-d H:i:s'), $sourceDatetime->getTimezone()->getName()); $timezone = 'Asia/Shanghai'; $targetDatetime = (new \DateTime(date('Y-m-d H:i:s', $timestamp))) ->setTimezone(new \DateTimeZone($timezone)); echo sprintf("target datetime:%s(%s)\n", $targetDatetime->format('Y-m-d H:i:s'), $targetDatetime->getTimezone()->getName()); output: source datetime:2020-01-01 00:00:00(UTC) target datetime:2020-01-01 08:00:00(Asia/Shanghai)
References:
https://zh.wikipedia.org/wiki/UNIX时间
最后更新时间:2021-04-22
重现步骤如下:
现有的目录结构:
├── source
│ └── source.txt
├── target
cp -r source target1 //target1 dir not exists
GUN/BSD |
├── source
│ └── source.txt ├── target └── target1 └── source.txt |
cp -r source target //target dir exists
GUN/Linux | BSD(MacOS) |
├── source
│ └── source.txt ├── target └── source └── source.txt |
├── source
│ └── source.txt ├── target │ └── source.txt |
测试环境:
GNU coreutils 8.22(CentOS)
GNU coreutils 8.30(Ubuntu 20.04)
BSD macOS Catalina 10.15.7
总结/Summary:
使用cp -r source target 复制目录时,如果目标目录不存在,则GUN/Linux&BSD(mac OS)的cp行为一致;如果目录已经存在,则BSD(mac OS)下会和目标目录不存在时行为一致,但是GUN的cp会创建在目标目录下创建子目录。
PS:
如果目标目录已经存在,可以使用 cp -r source/. target (GUN/Linux下target目录存在or不存在都支持,BSD(mac OS)下target目录存在or不存在都支持) or cp -r source/* target(仅适用于GUN/Linux下target目录存在的情况,BSD(mac OS)下语法错误)
所以简单起见:直接使用cp -r source/. target。GUN/Linux和BSD(mac OS)都支持,并且target目录存不存在都支持。
Console:
在早期的电脑上,往往具有带有大量开关和指示灯的面板,可以对电脑进行一些底层的操作,这个面板就叫做Console。其概念来自于管风琴的控制台。一台电脑通常只能有一个Console,很多时候是电脑主机的一部分,和CPU共享一个机柜。
Terminal and TTY(终端):
一台大型主机往往需要支持许多用户同时使用,每个用户所使用操作的设备,就叫做Terminal——终端,终端使用通信电缆与电脑主机连接,甚至可以通过电信网络(电话、电报线路等等)连接另一个城市的电脑。
TTY是电传打字机Teletypewriter的缩写,TTY曾经是最流行的终端设备。现在大多数场景TTY基本就是表示terminal。
Linux有7个TTY?
从控制台切换到 X 窗口,一般采用Ctrl+Alt+F7 ,为什么呢?因为系统默认定义了6个虚拟控制台(Ctrl+Alt+F1 ~ F6), 第7个用于x-windows。实际上,很多人一般不会需要这么多虚拟控制台的,关闭多余的控制台减少对系统资源的占用,可以自己更改配置文件减少它的数量(在支持systemd的系统里,配置文件位置:/etc/systemd/logind.conf, https://freedesktop.org/software/systemd/man/logind.conf.html,所以具体系统开启了多少个tty,要看配置文件,可能各个发行版本不一样,比如Ubuntu18.04/20.04就是默认6个,而且默认是把tty1留给了x-windows(Ctrl+Alt+F1))。
PTY(Pseudo Terminal, Pseudo TTY, or PTY, 虚拟终端/伪终端):
pts/ptmx(pts/ptmx结合使用,进而实现pty)
所谓伪终端是逻辑上的终端设备,多用于模拟终端程序。例如,我们在X Window下打开的终端,以及我们在Windows使用telnet 或ssh等方式登录Linux主机,此时均在使用pty设备(准确的说在使用pty从设备)
echo test > /dev/tty1会把单词test发送到连接在tty1的设备上。
1、/dev/pts0, /dev/pts1, …
2、/dev/tty0, …
3、/dev/console 表示物理终端(控制台)
4、/dev/ttyS0, … 表示串行终端
tty命令可以查看当前登录的终端类型,比如/dev/tty2,/dev/pts/0
什么是WebAssembly?
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
让我们用tinygo来写一个WebAssembly的模块,然后用js调用吧。首先下载TINYGO:(https://tinygo.org/,请下载对应版本的二进制文件)。然后将bin/tinygo(or tinygo.exe)加入到PATH路径。
然后先创建一个main.go文件(文件名必须是main.go,因为js里有用到文件名),文件内容如下:
package main // This calls a JS function from Go. func main() { println("Go: Hello World") // expecting 5 println("Go: add(2+3):", add(2, 3)) // expecting 5 println("Go: multiply(2*3):", multiply(2, 3)) // expecting 6 } // This function is imported from JavaScript, as it doesn't define a body. // You should define a function named 'main.add' in the WebAssembly 'env' // module from JavaScript. func add(x, y int) int // This function is exported to JavaScript, so can be called using // exports.multiply() in JavaScript. //go:export multiply func multiply(x, y int) int { return x * y; }
然后用tinygo编译这个go文件,生成wasm文件。
目前最新版的tinygo是0.12.0,最高只支持golang 1.13(目前最新版本的golang是1.14),编译的命令中文件名必须是main.go,不能写”./main.go”
tinygo build -o wasm.wasm -target wasm main.go
Error:
tinygo build -o wasm.wasm -target wasm ./main.go
然后用go写一个简单的文件服务器(用于启动http服务器,因为wasm加载必须在http/https的环境下),注意对于wasm文件,要设置Content-Type为application/wasm
package main import ( "log" "net/http" "strings" ) const dir = "./html" func main() { fs := http.FileServer(http.Dir(dir)) log.Print("Serving " + dir + " on http://localhost:8080") http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { resp.Header().Add("Cache-Control", "no-cache") if strings.HasSuffix(req.URL.Path, ".wasm") { resp.Header().Set("Content-Type", "application/wasm") } fs.ServeHTTP(resp, req) }))}
然后在服务器目录下创建html目录,目录里新建index.html文件(注意js代码中设置env的代码):
<html> <head> <title>WebAssembly</title> </head> <body> <script src="wasm_exec.js"></script> <script type="text/javascript"> const go = new Go(); // Defined in wasm_exec.js const WASM_URL = 'wasm.wasm'; go.importObject.env['main.go.add'] = function (x, y) { return x + y }; var wasm; console.log("'instantiateStreaming' in WebAssembly => " + ('instantiateStreaming' in WebAssembly ? "Y" : "N")); if ('instantiateStreaming' in WebAssembly) { WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) { wasm = obj.instance; go.run(wasm); console.log('JS: multiplied two numbers:', wasm.exports.multiply(5, 3)); }).catch((err) => { console.error(err); }); } else { fetch(WASM_URL).then(resp => resp.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, go.importObject).then(function (obj) { wasm = obj.instance; go.run(wasm); }) ) } </script> </body> </html>
index.html里面引用的wasm_exec.js文件就在tinygo下载包里,wasm.wasm就是我们刚刚编译生成的文件。
浏览器里打开这个网页 http://localhost:8080/index.html,发现控制台就能输出:
23:25:58.955 ‘instantiateStreaming’ in WebAssembly => Y
23:25:58.964 Go: Hello World
23:25:58.964 Go: add(2+3): 5
23:25:58.964 Go: multiply(2*3): 6
23:25:58.964 JS: multiplied two numbers: 15
23:25:58.966 Fetch finished loading: GET “http://localhost:8080/wasm.wasm”.
References:
https://webassembly.org/
https://tinygo.org/