本站提倡有节制游戏,合理安排游戏时间,注意劳逸结合。

【libubox源码分析】【拓荒神器源码】【源码之家网址】gocache源码

2024-11-26 20:01:54 来源:焦点 分类:焦点

1.BoltDB源码解析(七)Put和Delete操作
2.Mac搭建grafana二次开发环境操作教程(图文详解)
3.html简单网页代码?
4.沉浸式go-cache源码阅读!

gocache源码

BoltDB源码解析(七)Put和Delete操作

       Put和Delete的实现

       上一篇文章我们了解了BoltDB的Get API的实现。现在,我们来探讨Put和Delete API的实现:

       Put API的主要功能是将一对键值对插入到Bucket中,如果键已经存在,则更新对应的libubox源码分析值。首先,进行一些限制条件的检查,例如Put操作是否由写事务发起的,因为Put只能由写事务调用。此外,还需要检查键和值的大小是否符合限制条件。需要注意的是,Put操作和Get操作一样,这里也使用了Cursor来定位键应该放置的位置。

       在实际的Put操作中,会调用Cursor的一个不显眼的方法:

       这个方法实际上非常有用,它从当前Bucket的B-tree的根节点开始,一直到Cursor定位到的leaf page,为每个page创建一个对应的node结构。当然,如果一个page已经有对应的node,就直接使用它。

       为什么要这么做呢?这是因为事务篇中提到的修改操作具有“传染性”,修改B-tree的leaf节点会导致从root到leaf的所有page都需要修改,而BoltDB的修改操作都是在page对应的node里进行的,不是直接在page上修改,因此需要为这些page建立node结构。具体建立node结构的是Bucket的node方法:

       Bucket的node方法有两处需要注意,一个是新建的node会被追加到parent node的children中,记录下这些修改的node之间的关系,这个children在node持久化时会有用(node.spill方法)。另一个是node的数据是如何从page中读取的,这是由node的read方法完成的。

       node建立好之后,就在要修改的拓荒神器源码leaf对应的node上调用put方法:

       node的put方法相对简单,它是在inodes数组上查找对应的位置,如果exact为true,表示找到了相同的key,直接更新value;如果exact为false,相当于找到了应该插入的位置,然后在对应的inode上记录数据。我们来看一下inodes数组的定义:

       inodes数组是node实际存储数据的地方,由多个inode组成,每个不同的key对应一个不同的inode,inode之间是按key排序的。对于leaf节点来说,inode里使用key和value;对于branch节点来说,inode里使用key和pgid,pgid代表一个child page的id。value和pgid不会同时使用。

       put方法结束后,当前的Put操作也就结束了。也就是说,Put操作所做的仅仅是把新增或修改的数据放入到它所在的page对应的node内存中。

       顺便提一下Delete操作,它和Put操作非常类似,在建立起node结构之后,在对应的node的inodes数组中删除找到的key相等的inode就完成了,这里不再展开。

       那么,什么时候会把这些node里的数据持久化到DB文件里呢?是在整个写事务commit的时候。

       事务的Commit实现

       下面是事务commit的代码简化,保留了重要部分:

       Commit的整体流程比较长,下面一点一点进行说明。

       tx.root.rebalance(),这个root是root Bucket,rebalance是对root Bucket下所有子Bucket的所有node进行rebalance。这是什么意思?注意node的初始数据虽然来自一个page,但在经历了一些Delete操作后,有些node里面的源码之家网址数据可能过少,这时会先把这个node和它的左兄弟或右兄弟node合并(node的rebalance方法),合并后node数会减少,但不存在node里数据过少的情况。这个操作对应于B-tree的merge操作,只不过这些node都是Go的内存结构,合并起来非常简单。当然,合并后把这些node spill到page的操作,需要的page总数也会减少。

       tx.root.spill(),这个方法是把root Bucket下所有子Bucket的所有node的内容都写入这个事务分配的dirty page里。注意这些dirty page是这个事务临时分配在内存里的,结构和DB文件的page完全一样,但还不是mmap映射的DB的page。

       刚开始看到spill这个方法时,感觉它代价有些高,感觉像是把整个B-tree都走了一遍。后来仔细看才发现不是这么回事。这个spill只对有node结构的节点进行处理,那些没修改过的page没有对应的node,根本不会处理。

       注意在经过多次Put操作后,node里存放的数据可能出现一个page写不下的情况,比如insert了几千个key value。spill会先把这样的node split成多个大小合适的node(node的split方法),然后把这些node分别写入不同的page中。这个操作对应于B-tree的split操作。和rebalance方法类似的道理,因为这些node都是Go的内存结构,split起来非常容易。

       if tx.meta.pgid > opgid,这个判断是看当前事务需要的page数是否大于事务执行前DB文件有的page数,如果大于,说明DB文件放不下了,就调用db.grow增大文件,get指标源码以容纳新增的page。

       紧接着是freelist的持久化操作,因为写事务可能使用了freelist里的一些page,同时也可能释放了一些page到freelist里,所以freelist很可能发生了变化,需要持久化。

       tx.write(),这个方法就是把所有的临时分配的dirty page都写入DB文件对应的page里。

       tx.writeMeta(),这个方法是把这个tx里的meta写到meta0或者meta1里面(写事务会交替写这两个meta page,这也是个常用技术,叫ping-pong buffer)。它的代码值得看一下:

       首先把meta写到临时分配的buf里,然后用文件IO写到DB文件里,最后调用fdatasync,把OS文件的buffer cache持久化到磁盘上。至此,写事务的所有数据都已经落盘完毕。后面新开启的事务会因为这个meta的txid是最大的,而选择使用这个最新的meta page。而这个meta page包括最新的root bucket,最新的freelist,最新的pgid,这些总体构成了一个DB的最新版本,保证新开启的事务读到最新版本的数据。

       看tx.write()和tx.writeMeta()的实现可以发现,写入数据用的是db.ops.writeAt,而这个方法默认值就是File.WriteAt方法,所以实际写入文件用的是文件IO,而不是直接写mmap内存。而BoltDB使用mmap一开始就把mmap映射的内存标记为只读的,压根不允许直接写mmap内存。为什么要这么做呢?

       猜测可能是为了安全。前面讲到Get操作为了性能是zero copy的,发现Get返回来的dogs网站源码value是mmap上数据的指针,如果mmap设置为可读写的,应用程序代码五花八门,可能会通过指针一不小心修改了mmap上的数据,这样的修改因为走的不是API是无法保证事务的。把mmap设置为只读的消除了这种可能性。反过来说,如果mmap设置为可读写的,Get就不能返回mmap上的指针了,为了安全一定要copy一份数据出来才行,降低了Get的性能。

       这里还有个很自然而且很重要的问题是,如果事务commit失败了呢,BoltDB如何保证事务的原子性(ACID的A),确保这个写事务的所有操作,不论是落盘的,还是没落盘的,都不会生效?

       原子性要求,不管是commit走到哪一步,哪怕是已经把修改的数据,甚至包括修改的freelist已经落盘,只要最终事务commit失败,都不能对正确性产生任何影响。这里的正确性是指,数据库的状态(有实际的key value数据,freelist, pgid等共同构成)必须是在这个写事务运行之前的状态,数据不能被破坏,这个写事务也不能留下可被后续事务读到的任何更新。

       要做到原子性貌似挺难的,因为事务的commit里包括很多步骤,这些步骤都不是原子性的。不过重要的一点是,不论commit运行到哪一步,因为tx.writeMeta是最后一步,只有这一步运行成功commit才算成功,如果说commit失败了,那么tx.writeMeta一定是没运行,或者运行了半截,这个meta page没写完整,机器断电了。总之,这些情况下我们不会得到一个合法的新的meta page(这种情况下meta的validate方法会失败,因为meta的checksum不对)。这时候ping-pong buffer的meta page就起重要的作用了,因为交替写meta page的原因,即使这个写事务新的meta page没写成功,这个写事务运行前版本的meta page还在,而这个meta page包括这个写事务运行前的DB版本所有的状态(kv数据,freelist,pgid等)。这个meta page会被后续事务使用,就像那个失败的写事务从来没有运行过一样。而那个写事务留下的kv数据的page,freelist的page,即使是持久化了,也因为没有写成新的meta,没有机会被用到。

       还有个自然的疑问,即使这个失败的写事务写的page因为没有合法的meta无法被引用,不会影响正确性,但无法被引用是不是也意味着这些page无法被回收,浪费了磁盘空间?

       答案是也不会。在原来版本的meta里的free list和pgid的共同作用下,这些page会被视为free的,还可以使用,不会出现无法回收这些page的情况。

       还有个疑问,既然BoltDB交替写meta0和meta1,是不是连续两个事务commit正好在写meta时失败,数据库就废了?

       仔细研究发现,还是没事!因为写事务的txid也是meta的一部分,一个写事务失败,导致txid不会增长,下一次写事务的txid还是一样,meta的交替写是因为txid的变化引起的,既然没变化,就不交替了。所以下一个写事务即使写meta还失败了,也还是写的上一个写事务写的那个meta,不会把两个meta都写坏。

       总结一下,ping-pong buffer的meta page真是设计得精巧,是BoltDB达到原子性的关键!

Mac搭建grafana二次开发环境操作教程(图文详解)

       Grafana是开源的图表数据展示系统,可以配置很多的dashboard,还可以下载别人已经配置好的dashboard。

       这篇博客介绍下如何在mac下搭建grafana的二次开发环境。

一、安装grafana

       首先,我们可以通过brew把grafana安装到系统里,来看一看这个开源系统的功能。

       如果你的brew是直接可用的,就在terminal中直接运行下面的命令,否则,需要先brewupdate一下。

brewinstallgrafana

       装好以后,通过如下命令可以启动grafana

brewservicesstartgrafana

       然后打开localhost:,看到下面的图,就可以了。

       初始账号密码是admin/admin。

       通过下面的命令可以关闭和重启grafana

brewservicesstopgrafanabrewservicesrestartgrafana二、搭建grafana的开发环境

       grafana依赖node和go,需要先安装好node和go。

1、安装node

       我这里的grafana是7.3,需要版本的node

       安装node有两种方式

       如果之前没有装过,直接brewinstallnode就可以了,这样安装的node默认是最新版本,如果需要指定版本,可以在node后通过@来指定安装某个版本。

       通过版本管理神器n来升级

npmin-g//安装node版本管理神器n-V//安装后查看n的版本nlatest//使用或安装最新的官方发布:nstable//使用或安装稳定的正式版本:nlts//使用或安装最新的LTS正式版本:

       安装好node后顺便升级下npm

npminpm@latest-g2、安装golang

       依然通过brew安装go

brewinstallgo//安装golang

       然后查看go的环境变量配置

goenv

       上面的命令默认得到如下信息

GOMODULE=""GOARCH="amd"GOBIN=""GOCACHE="/Users/XXXXX/Library/Caches/go-build"GOENV="/Users/XXXXX/Library/ApplicationSupport/go/env"GOEXE=""GOFLAGS=""GOHOSTARCH="amd"GOHOSTOS="darwin"GOINSECURE=""GOMODCACHE="/Users/XXXXX/go/pkg/mod"GONOPROXY=""GONOSUMDB=""GOOS="darwin"GOPATH="/Users/XXXXX/go"GOPRIVATE=""GOPROXY=""GOROOT="/usr/local/go"GOSUMDB="sum.golang.org"GOTMPDIR=""GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd"GCCGO="gccgo"AR="ar"CC="clang"CXX="clang++"CGO_ENABLED="1"GOMOD=""CGO_CFLAGS="-g-O2"CGO_CPPFLAGS=""CGO_CXXFLAGS="-g-O2"CGO_FFLAGS="-g-O2"CGO_LDFLAGS="-g-O2"PKG_CONFIG="pkg-config"GOGCCFLAGS="-fPIC-m-pthread-fno-caret-diagnostics-Qunused-arguments-fmessage-length=0-fdebug-prefix-map=/var/folders/3m/xp_vx4jj3lh8chqq5tq_dwgn/T/go-build=/tmp/go-build-gno-record-gcc-switches-fno-common"

       注意GOPATH地址,在"/Users/XXXXX/go"下,其中XXXXX是我的用户名。但是在XXXXX下是没有go这个文件夹,需要我们自己建立。

       假如我们想写一个go的helloworld,就需要把这个程序放到go目录下。

       假如想要修改GOPATH也是可以的。用如下命令:

vim~/.bash_profile

       添加如下代码:exportGOPATH="XXXXXXXXXX"然后快捷键shift+zz关闭文件

       这时候,在terminal中输入echo$GOPATH,就可以看到刚刚设置的GOPATH了。

       到这一步,go就算安装到我们的电脑里了。

3、下载grafana的源代码

       由于grafana是开源的,因此代码托管在github上,地址:makerun

       到这里,grafana的二次开发环境就搭建好了。

作者:晴天同学

html简单网页代码?

       HTML做一个打开网页代码

       html的head区域中加上scriptlanguage="javascript"location.replace("")/script即可html

       html代码如下:

       head

       title页面跳转/title

       scriptlanguage="javascript"location.replace("")/script

       /head

       body

       /body

       /html

       

扩展资料:

       网页HTML代码大全

       文件类型HTML/HTML(放在档案的开头与结尾)

       文件主题TITLE/TITLE(必须放在「文头」区块内)

       文头HEAD/HEAD(描述性资料,像是「主题」)

       文体BODY/BODY(文件本体)

       (由浏览器控制的显示风格)

       标题H?/H?(从1到6,有六层选择)

       标题的对齐H?ALIGN=LEFT|CENTER|RIGHT/H?

       区分DIV/DIV

       区分的对齐DIVALIGN=LEFT|RIGHT|CENTER|JUSTIFY/DIV

       引文区块BLOCKQUOTE/BLOCKQUOTE(通常会内缩)

       强调EM/EM(通常会以斜体显示)

       特别强调STRONG/STRONG(通常会以加粗显示)

       引文CITE/CITE(通常会以斜体显示)

       码CODE/CODE(显示原始码之用)

       样本SAMP/SAMP

       键盘输入KBD/KBD

       变数VAR/VAR

       定义DFN/DFN(有些浏览器不提供)

       地址ADDRESS/ADDRESS

       大字BIG/BIG

       小字SMALL/SMALL

       与外观相关的标签(作者自订的表现方式)

       加粗B/B

       斜体I/I

       底线U/U(尚有些浏览器不提供)

       删除线S/S(尚有些浏览器不提供)

       下标SUB/SUB

       上标SUP/SUP

       打字机体TT/TT(用单空格字型显示)

       预定格式PRE/PRE(保留文件中空格的大小)

       预定格式的宽度PREWIDTH=?/PRE(以字元计算)

       向中看齐CENTER/CENTER(文字与都可以)

       网页设计常用HTML代码

       网页设计常用HTML代码大全

       HTML是用来描述网页的一种语言。下面我为大家分享HTML代码,希望对大家学习html代码有帮助!

       忽视右键

       bodyoncontextmenu="returnfalse"

       或

       bodystyle="overflow-y:hidden"

       1.如何几秒后转到别的页面?

       METAHTTP-EQUIV="Refresh"CONTENT="时间;URL=地址"

       2.点击关闭窗口

       ahref="javascript:top.window.close();"点击关闭窗口/a!

       3.请问如何去掉主页右面的滚动条?

       bodyscroll="no"

       bodystyle="overflow-y:hidden"

       4.请问如何做到让一个网页自动关闭.

       html

       head

       OBJECTid=closestype="application/x-oleobject"classid="clsid:adba6-d8ff-cf--aab7a"

       paramname="Command"value="Close"

       /object

       /head

       bodyonload="window.setTimeout(‘‘‘‘closes.Click()‘‘‘‘,)"

       这个窗口会在秒过后自动关闭,而且不会出现提示./body

       如何在不刷新页面的情况下刷新css?

       style

       button{ color:#;}

       /style

       buttononclick=document.styleSheets[0].rules[0].style.color=‘‘‘‘red‘‘‘‘点击按钮直接修改style标签里button选择符使按钮改为红色/button

       请问如何让网页自动刷新?

       在head部记入METAHTTP-EQUIV="Refresh"content=""其中为秒后自动刷新,你可以更改为任意值。

       5.如何让页面自动刷新?

       方法一,用refresh

       HTML代码片段如下:

       head

       metahttp-equiv="refresh"content="5"

       /head

       5表示刷新时间

       [Ctrl+A全部选择提示:你可先修改部分代码,再按运行]

       方法二,使用setTimeout控制

       imgsrc=/logo.gif

       script

       functionrl(){

       document.location.reload()

       }

       setTimeout(rl,)

       /script

       6.如何让超链接没有下划线

       在源代码中的HEAD…/HEAD之间输入如下代码:

       styletype="text/css"!--

       a{ text-decoration:none}

       --/style

       7.请问如何去掉IE的上下滚动条?

       bodystyle=‘‘‘‘overflow:scroll;overflow-y:hidden‘‘‘‘

       /body

       8.怎样才能把RealPlayer文件在网页做一个试听连接?

       embedheight=src=js.rmtype=audio/x-pn-realaudio-pluginwidth=autostart="false"controls="PlayButton"

       9.如何用html实现浏览器上后退按钮的功能?

       ahref="javascript:history.go(-1)"点击后退/a

       或者

       scripthistory.back()/script

       .请问怎么在网页中改变鼠标的箭头形状?

       HTML代码片段如下:

       body

       ahref="#"style="cursor:auto;"auto/abr

       ahref="#"style="cursor:crosshair"crosshair/abr

       ahref="#"style="cursor:default"default/abr

       ahref="#"style="cursor:hand"hand/abr

       ahref="#"style="cursor:move"move/abr

       ahref="#"style="cursor:e-resize"e-resize/abr

       ahref="#"style="cursor:ne-resize"ne-resize/abr

       ahref="#"style="cursor:nw-resize"nw-resize/abr

       ahref="#"style="cursor:n-resize"n-resize/abr

       ahref="#"style="cursor:se-resize"se-resize/abr

       ahref="#"style="cursor:sw-resize"sw-resize/abr

       ahref="#"style="cursor:s-resize"s-resize/abr

       ahref="#"style="cursor:w-resize"w-resize/abr

       ahref="#"style="cursor:text"text/abr

       ahref="#"style="cursor:wait"wait/abr

       ahref="#"style="cursor:help"help/abr

       /body

       .怎样不使用页面的缓存?即每一次打开页面时不是调用缓存中的东西

       METAHTTP-EQUIV="Pragma"CONTENT="no-cache"

       .页面打开时自动弹出一个窗口的代码怎么写?

       HTML代码片段如下:

       html

       head

       titleUntitledDocument/title

       metahttp-equiv="Content-Type"content="text/html;charset=gb"

       scriptlanguage="Bstyle="color:black;background-color:#A0FFFF"javascript/B"

       !--

       functionMM_openBrWindow(theURL,winName,features){ //v2.0

       window.open(theURL,winName,features);

       }

       //--

       /script

       /head

       bodybgcolor="#FFFFFF"text="#"onLoad="MM_openBrWindow(‘‘‘‘‘‘‘‘,‘‘‘‘,‘‘‘‘width=,height=‘‘‘‘)"

       /body

       /html

       .如何让我的页面出现一个会讲话的小人?Merlin

       HTML代码片段如下:

       HTML

       HEAD

       TITLE默林/TITLE

       METAhttp-equiv=Content-Typecontent="text/html;charset=gb"

       /HEAD

       BODY

       pOBJECTid=simsclassid=CLSID:DFDB-5C6E-D1-9EC1-CFDF

       /OBJECT

       SCRIPT

       varMerlinID;

       varMerlinACS;

       sims.Connected=true;

       MerlinLoaded=LoadLocalAgent(MerlinID,MerlinACS);

       Merlin=sims.Characters.Character(MerlinID);

       Merlin.Show();

       Merlin.Play("Surprised");

       Merlin.Speak("大家好");

       Merlin.Play("GestureLeft");

       Merlin.Think("我是默林!");

       Merlin.Play("Pleased");

       Merlin.Think("可爱吗?");

       Merlin.Play("GestureDown");

       Merlin.Speak("哈哈!");

       Merlin.Hide();

       functionLoadLocalAgent(CharID,CharACS){

       LoadReq=sims.Characters.Load(CharID,CharACS);

       return(true);

       }

       /SCRIPT

       /p

       p/p

       p看此效果必须装有office!!!/p

       /BODY

       /HTML

       .在页面中如何加入不是满铺的背景,拉动页面时背景图不动

       HTML代码片段如下:

       htmlhead

       STYLE

       body{ background-image:url(logo.gif);

       background-repeat:no-repeat;background-position:center}

       /STYLE

       /head

       bodybgproperties="fixed"

       /body

       /html

       [Ctrl+A全部选择提示:你可先修改部分代码,再按运行]

       background-repeat:no-repeat;是让背景图不占满整个页面

       bodybgproperties="fixed"是拉动scroll时背景图不动

       .文本输入框什么属性能实现不可输入?

       HTML代码片段如下:

       inputtype="text"name="textfield"disabled

       或者

       inputtype="text"name="textfield"readonly

       .如何禁止自己的页面在别人的框架里打开?

       把以下代码加至你的head区

       script

       if(window.top!=self){

       window.top.location=self.location

       }

       /script

       .如何实现首页全屏幕显示?

       HTML代码片段如下:

       html

       bodyscriptlanguage="Bstyle="color:black;background-color:#A0FFFF"javascript/B"

       varcoolw=

       varcoolh=

       varcoolhuang=window.open("","coolhuang","width="+coolw+",height="+coolh+",

       fullscreen=1,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=0")

       window.close()

       /script/body/html

       .如何监听一个窗口被关闭了?

       HTML代码片段如下:

       bodyonunload="alert(‘‘‘‘你关闭了这个窗口‘‘‘‘)"

       .如何禁止Ctrl+N?

       HTML代码片段如下:

       bodyonkeydown=return(!(event.keyCode==event.ctrlKey))

       如何把页面加入用户的收藏夹?

       HTML代码片段如下:

       ahref="Bstyle="color:black;background-color:#A0FFFF"javascript/B:window.external.AddFavorite(‘‘‘‘‘‘‘‘,‘‘‘‘无忧脚本‘‘‘‘)"收藏无忧脚本/a

       如何在我的'页面中加入背景音乐?

       IE:bgsoundsrc="*.mid"loop=infinite

       NS:embedsrc="*.mid"autostart=truehidden=trueloop=true

       *.mid你的背景音乐的midi格式文件

       关于页面转换效果

       metahttp-equiv="page-enter"content="revealTrans(Duration=4,Transition=)"

       或

       metahttp-equiv="page-exit"content="revealTrans(Duration=4,Transition=)"

       说明:Transition=是随机效果,另可以选0-任一数字固定某个效果

       如何设定打开页面的大小

       HTML代码片段如下:

       bodyonload="top.resizeTo(,);"!--(width,height)--

       怎样双击滚屏,单击停止?

       HTML代码片段如下:

       html

       head

       title新网页1/title

       /head

       body

       scriptlanguage"Bstyle="color:black;background-color:#A0FFFF"javascript/B"

       varcurrentpos,timer;

       functioninitialize()

       {

       timer=setInterval("scrollwindow()",);

       }

       functionsc(){

       clearInterval(timer);

       }

       functionscrollwindow()

       {

       currentpos=document.body.scrollTop;

       window.scroll(0,++currentpos);

       if(currentpos!=document.body.scrollTop)

       sc();

       }

       document.onmousedown=sc

       document.ondblclick=initialize

       /script

       pa/ppa/ppa/ppaa/ppaa/ppaa/p

       paa/ppaa/ppaa/ppaa/ppaa/ppaa/p

       paa/ppaa/ppaa/ppaa/ppaa/ppaa/p

       paa/ppaa/ppaa/ppaa/ppa/p

       /body

       /html

       如何让body中的文字不被选中?

       HTML代码片段如下:

       bodyonselectstart="returnfalse"aaa/body

       如何让弹出的窗口不能关闭?

       在新开的窗口中加入如下代码

       bodyonunload=open(location.href)

       /body

       如何让浏览器在保存页面时保存失败?

       HTML代码片段如下:

       NOSCRIPT

       Bstyle="color:black;background-color:#ffff"IFRAME/BSRC="*.html"

       /Bstyle="color:black;background-color:#ffff"IFRAME/B

       /NOSCRIPT

       表单中如何用按钮实现reset?

       html

       head

       script

       functionaaa(){

       document.forms[0].reset()

       }

       /script

       /head

       body

       form

       textarearows="2"name="S1"cols=""/textarea

       inputtype="submit"values="提交"name="B1"

       imagesrc="logo.gif"onclick=aaa()

       /form

       /body/html

       进入网页时弹出的信息对话框

       bodyonLoad="window.alert(‘‘‘‘欢迎光临本站‘‘‘‘)"

       关闭窗口后弹出对话框

       bodyonUnload="window.alert(‘‘‘‘谢谢你的光临!欢迎下次再来!‘‘‘‘)"

       告别提示

       bodyonUnload=alert("再见,感谢你的访问!")

       右键菜单的制作

       OBJECTid=menutype="application/x-oleobject"classid="clsid:adba6-d8ff-cf--aab7a"

       PARAMname="Command"value="RelatedTopics,menu"

       PARAMname="Item1"value="动易;"

       PARAMname="Item2"value="搜狐;"

       PARAMname="Item3"value="新浪;"

       PARAMname="Item4"value="网易;"

       PARAMname="Item5"value="互动学院;"

       /OBJECTscriptif(document.all)document.body.onmousedown=newFunction("if(event.button==2)menu.Click();")/script

       下拉菜单

       objectid=HHCtrltype="application/x-oleobject"classid="clsid:adba6-d8ff-cf--aab7a"PARAMname="Command"value="RelatedTopics,Menu"PARAMname="Item1"value="aspease;"PARAMname="Item2"value="byhu;"PARAMname="Item3"value="lzz;"/objectahref=javascript:HHCtrl.Click()title="下拉菜单"下拉菜单/a

html简单网页代码怎么写?

       1、在电脑桌面空白处单击右键,新建一个记事本并打开

       2、在新建文件中输入如下代码。html语言都是以htmlheadtitlebody等标签开始,以/html/head/title/body标签作为结束。

       3、接下来要在title/title标签中间输入标题(如个人网页)在body/body中输入“自己做的第一个网页,厉害吧!”完成后点击保存

沉浸式go-cache源码阅读!

       大家好,我是豆小匠,这期将带领大家探索go-cache的内部实现,深入理解本地缓存机制,并分享一些阅读源码的实用技巧。

       首先,我们从源码入手,Goland中仅需关注cache.go和sharded.go两个文件,总共行代码,是不错的学习资源。通过README.md,可以了解到包的使用方法。

       创建缓存实例时,我们注意到它依赖于清理间隔,而非实时过期删除。这引出了一个问题:如何在逻辑上处理过期缓存?我们开始在cache.go中寻找答案。

       首先,我们关注Cache结构体,它定义了整个缓存的框架。接下来,重点阅读New函数,这里使用了runtime.SetFinalizer来确保即使对象被设置为nil,清理协程的GC回收也受到影响。

       通过源码解析,我们明白,如果清理协程与Cache对象关联,即使对象不再活跃,GC仍无法立即回收。再深入Get方法,你会发现,缓存失效并非通过key是否存在,而是通过item中的过期时间判断,定时清理主要为了释放存储空间。

       最后,我们对常用的方法进行挑选,梳理cache类的成员变量和功能,通过创建图示的方式,来帮助我们更好地理解和记忆。值得注意的是,onEvicted是删除key的回调函数,而sharded.go是未公开的分片缓存实验代码。

相关推荐
一周热点