HTML 5 资源预处理 HINTS

Hints to the browser that might prime the pump for resources you will need. Preload is the only exception here, being more of an instruction than just a hint. AddyOsmani @ https://plus.google.com/+AddyOsmani/post/7JvGGPAAuCT 浏览器允我们在网页的 head 中添加特定的 link 标签,提示浏览器进行资源预处理,如资源预加载、域名预解析等等。 DNS 预解析(Preresolve DNS hostnames for assets) <link rel="dns-prefetch" href="http://my-site.com"> 预连接(Begin a connection handshake in the background) <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 脚本预加载(Declaratively fetch a resource without executing it) <link rel="preload" href="late-script.js" as="script"> 图片预加载(Prefetch a resource for a future navigation)

Thumbnail image

扫雷(二)排行榜(定义和使用函数、对象)

 第一章我们实现了最基本的游戏界面和游戏的简单入口,这一章,我们完善和制作 排行榜 功能,并为将来游戏结束时使用、记录排行榜提供支持。 在使用 互联网 的时候,我们基本上离不开浏览器 (browser) 。 浏览器其实可以看作一个 中间人,他将 用户无法理解、看不太懂的 脚本语言描述的程序,转换为 用户可以看得到的界面、接收用户的输入输出动作,并通过执行脚本程序给出对应的反馈。 一般,我们把前面的 “转换为界面” 过程称作 “渲染” (render)。 在[上一章][chapter-1]中,我们在 .html 文件中填写了代码,在浏览器中打开这个文件,看到了界面,我们姑且称这个“渲染”动作为“静态渲染”,那么这一章中,我们将会看到另外一种“动态渲染”。 接口 可以理解为能够让另外的代码、模块调用的函数、对象; 分装 即就是将可以重复使用或功能联系紧密的若干代码聚合在一个可以被 调用 或 访问的模块中; 在程序开发过程当中,我们一般会提到“接口”,“封装”等等概念。我理解,提出这些概念的目的,其实是在告诉我们,将程序写的更“清晰”一些。这个“清晰”一般可以描述为两方面: 功能完整 - 实现某个功能应该做些什么事情?如果要做这个事情,是不是可以有不同的做法? 分工明确 - 某个功能应该在哪里做?代码写在哪里? 定义“接口”,即就是将完整的、能够重复使用的“功能”包装(封装)成函数、对象,并供其他逻辑 或 在其他地方调用;使用者并不需要了解“接口”内部具体的实现逻辑,只需知道接口“形式”即可使用,完成对应的功能,同时使用者 不需要对其不需了解的事情加以干涉。我们下面也会封装、实现一些简单的接口来介绍上面的概念。 排行榜的结构 按照网页的开发方式,我一般习惯按照“基本结构”->“外观润色”->“行为功能”这个流程进行进行开发。首先,在排行榜([上一章][chapter-1]中 (3) 的位置)加入下面“基本结构”的 HTML 代码: <!-- 标题,可以使用 h1 ~ h5,大小、颜色稍有不同 --> <h4>排行榜</h4> <!-- table-striped 将会让表格内容变成深浅相间的行 --> <table class="table table-striped"> <!-- 表头 --> <thead class="thead-default"> <tr> <th>#</th> <th>姓名</th> <th>用时</th> </tr> </thead> <tbody id="rank_table"> <!-- 表格内容 --> </tbody> </table> 在 HTML 中描述一个表格,使用 <table> 标签,并用 <tr></tr> 来表示一行,<th></th> 或 <td></td> 分别来表达 表头和表体 中的单元格。 上面元素对应的属性 class 中使用的对应内容,可暂不关心(有兴趣的同学,可以 参看 中文 或 英文 的文档)

Thumbnail image

扫雷(一)游戏入口(概念及准备)

 记得我最开始接触编程就是父亲在“裕兴学习机”上开发了一款“扫雷”的游戏,从此开始喜欢上了计算机编程。作为纪念,也希望能给一些正在学习网页开发的同学一点点帮助,我这里也从头开始用“网页”技术开发一款“扫雷”的小游戏。 网页小游戏开发,顾名思义,首先我们是制作了一个网页。网页是互联网中与用户的交互的基本元素,并被浏览器“渲染”展示呈现给用户。从最早网页的开始,我们仅能呈现给用户“文本”,后来由于互联网的进步,我们能够支持呈献给用户“富文本”(即带有一定样式的文本,如大小不同、颜色不同等等),进而出现“多媒体”(图片、声音、视频等)甚至更多可能的交互形式(如 麦克风、摄像头、重力感应、震动等等)。在这个发展过程中,网页的开发技术逐渐定型,网页本身使用 HTML 文本进行基本界面的绘制,使用 CSS 文本描述各个元素的高级特征,如边框、偏移、位置、颜色、阴影等等,使用 JavaScript 脚本语言(文本形式,解释执行、不需要编译)进行交互、行为、功能开发。 我写的这个教程比较直接,可能会有很多没有“详细描述”的内容。刚刚入门的同学,建议去看看 w3school 整理的基础语言的教程和参考文档。不介意看英文的同学,可以参考 Mozilla 的开发者中心 https://developer.mozilla.org/en-US/docs/Web。 后者有一套不错的入门教程,而且他提供的参考文档是目前我看到最详细和完整的。 一些准备工作 首先,我们需要准备一些用于网页开发的编辑器工具软件。在若干年前,开发网页有“三剑客”之称的三款软件即 Dreamweaver / Flash / Firework (/Photoshop),分别负责 TML/CSS/JavaScript 、 动画、图片处理。从上面介绍的背景和我们将要进行的开发工作来看,我们只需要只涉及到 HTML/CSS/JavaScript 文本形式程序的开发(对多媒体,如图片,我们仅使用而不对这些资源进行修改、调整),所以我们仅需要 Dreamweaver 这款程序。当然,这是若干年前的选择,也可以说是“低端”的选择。在我实际工作中,仅需要一款 附带语法高亮功能的文本编辑器就足够了。除特殊情况外,我一般使用 SublimeText,附带各种强大插件的强大文本编辑器,大家可以尝试使用(程序员对编辑器的喜爱永恒是萝卜青菜的讨论,所以,仅供参考)。 其次,在开发调试网页的过程中,我推荐使用 Chrome 浏览器,相对调试方便,对相关技术标准的支持(在开发这个小游戏开发过程当中用到的技术,理论上在 IE9+ 的浏览器中都是可用的)。国内下载这款浏览器时可以去 https://api.shuax.com/tools/getchrome ,这里一般都能跟上官方更新,并且提供的是去除了国内根本不能用的更新服务的版本下载地址; 最后,需要注意一点,在整个调试过程当中,请保证您的设备连接在互联网上(由于直接引入了网络上一些成熟的JavaScript库 CSS 库,辅助、简化开发工作。当然这些库可以暂时不去详细学习,只需要按照教程能够看懂即可); 游戏的入口 目前我们暂时不进入到实际“扫雷”的开发中,我们把入口准备一下:进入游戏时,我们让用户输入自己的姓名(将来游戏结束时记录各个用户对应的成绩): <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>扫雷 - 网页小游戏</title> <!-- 这里引入的一个辅助库,帮助我们更好的定义网页和开发功能,可以暂不纠结具体 --> <link href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="styleSheet" /> <script src="http://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script> <!-- 下面文件用来定义我们 扫雷 游戏的外观样式(见下文) --> <link href="./minesweeper.css" rel="styleSheet" /> </head> <body> <div class="block entry"> <!-- (1) 用户登记 --> 你是谁? </div> <div class="block main"> 雷区 <!-- (2) 游戏主界面 --> </div> <div class="block rank"> 排行榜 <!-- (3) 游戏排行榜 --> </div> <!-- 我们的程序、逻辑、行为将在下面的 js 文件中定义 --> <script src="./minesweeper-entry.js"></script> <script src="./minesweeper-field.js"></script> <script src="./minesweeper-rank.js"></script> <script src="./minesweeper-main.js"></script> </body> </html> 把上面的代码放在一个文本文件中,并保存在后缀 .html 并在浏览器中打开就能看到下面的样子: 上面的代码即就是 HTML。使用 HTML 我们能够定义出网页的基本结构:

LINUX 下 GLIBC 内存回收的疑问

记得好早之前刚刚接触 Linux 下 C/C++ 开发的时候就有个疑问:在程序内 free 掉的空间没有立刻交换给操作系统,程序进程的内存没有减少。后来一度在开发各种长连接程序时 GOOGLE 各种资料,最近又偶尔遇到,借此机会把相关的说法整理如下。 其中两个重点内容如下: Freeing Memory Allocated with malloc: 注意这里的 “Occasionally” 用词; Occasionally, free can actually return memory to the operating system and make the process smaller. Usually, all it can do is allow a later call to malloc to reuse the space. In the meantime, the space remains in your program as part of a free-list used internally by malloc. Linux Programmer’s Manual - mallopt: 注意默认配置 128*1024 数值; M_TRIM_THRESHOLD When the amount of contiguous free memory at the top of the heap grows sufficiently large, free(3) employs sbrk(2) to release this memory back to the system. (This can be useful in programs that continue to execute for a long period after freeing a significant amount of memory.) The M_TRIM_THRESHOLD parameter specifies the minimum size (in bytes) that this block of memory must reach before sbrk(2) is used to trim the heap.

更新 GCC 后引起的 CLANG 安装问题

安装了新版本 GCC 后,附加 rpath 参数编译安装 CLANG 解决找不到对应新版本的 libstdc++.so 库的问题 首先我在 CentOS 7 上面编译安装了 GCC 5.2.0 到 /usr/local 然后删除了自带的 GCC: # gcc-5.2.0 ./contrib/download_prerequisites # gcc-stage ../gcc-5.2.0/configure --disable-mulitlib --enable-languages=c,c++,go make -j4 make install yum remove gcc gcc-c++ 安装 clang/llvm 大概需要下载这两个的包,让后把 clang 的包放进 llvm 的 tools 下面,然后: ../llvm-3.7.0.src/configure --enable-optimized --enable-targets=host-only --enable-cxx1y --with-gcc-toolchain=/usr/local make LDFLAGS+="-Wl,-rpath,/usr/local/lib64 -L/usr/local/lib64" 上面命令指定 rpath 为了解决一个跟 libstdc++ 版本有关的问题(编译时没有找到新版本 GCC 提供的 libstdc++.so 存在 /usr/local/lib64 中)。 编译安装 GCC 和 clang 非常耗费时间,得有心理准备。

SHELL 命令笔记

这里记录了一些挺实用的 Shell 命令,Windows 和 Linux 的都有一些,如启用 Wifi 热点,清理 DNS 缓存,挂载共享等。 Wifi HotSpot (Windows) netsh wlan set hostednetwork mode=allow ssid={NETWORK_NAME} key={NETWORK_PASS} netsh wlan start hostednetwork DNS flushCache (Windows) ipconfig /flushdns 挂载共享 sudo mount -t cifs -o username=xxxxxx,uid=2017,gid=2017,cache=none,noperm,_netdev //xx.xx.xx.xx/xxxxxx /xxxx/xxxxxx SSH 通道 plink -ssh {user}@{delegate_server_addr} -pw "{delegate_server_pass}" -P {delegate_server_port} -N -L {local_port}:{target_addr}:{target_port} 静态链接 C++ 标准库 clang++ -Wl,-Bstatic -lc++ -lc++abi -Wl,-Bdynamic -nostdlib++

折腾到 DIGITALOCEAN

blog.terrywh.net 迁移到 DigitalOcean 并重新部署,使用 Hugo 生成静态站点。 整个站点内容的 markdown 文件保存在 Git 仓库中。同时使用 Git 钩子自动更新,编写一个脚本文件 regenerate.sh: #!/bin/bash GIT_DIR=.git # 等待 Git 完成更新 sleep 3 # Git 拉取新内容 cd /data/htdocs/blog.terrywh.net/content git pull origin master git log --oneline > version cd /data/htdocs/blog.terrywh.net /data/server/hugo # 恢复 GIT_DIR=. 并在 git post-receive hook 中调用上述脚本文件: /data/htdocs/blog.terrywh.net/regenerate.sh &>/dev/null & echo hugo regenreate in 3...