2017年12月

时钟不停歇 旧去新来
最冷的日子还没结束 却已经期待春暖花开
或许不应期待更多的阳光
现在还能享受冬日里的晴朗
只是一年年地去了又来
我奢望日子 还有很长很长

很长很长 很长很长
长长短短 短了不再长
长得已经看惯桑田沧海
长得已经看惯爱浓情殇
长得已经不敢奢望更长
活着一刹那 一刹那有多长

所有都好用, 自然是用库

推荐的库是iconv, iconv-lite.
不过就是临时转一下, 还需要建一个npm项目不成? 有简单的办法吗?下面讲.

先说一个node.js和chrome兼容的做法: charCodeAt

'中文'.charCodeAt(0).toString(16) // "4e2d"
'中文'.charCodeAt(1).toString(16) // "6587"
'abc'..charCodeAt(0).toString(16) // "61"

这种方法得一个一个去取, 当然有个for循环会更方便
这个方法的逆方法是String.fromCharCode(new Uint16Array([0x6587])) ,打印出
这儿奇怪的是上述内容都是双字节编码...

chrome和firefox等浏览器实现了一个TextEncoder的类

只是这个类现在只支持utf8编码, 不再支持其他类型,如gbk.

var x = new TextEncoder().encode('中文')
//输出 Uint8Array(6) [228, 184, 173, 230, 150, 135]
(new Array(...x)).map(v=>v.toString(16)).join()
//"e4,b8,ad,e6,96,87"  上面先转普通数组, TypedArray不能用map将数字转为字符串, 然后再转16进制表示的字符串,再连接

逆类是TextDecoder, 这个支持gbk

new TextDecoder().decode(new Uint8Array([228, 184, 173, 230, 150, 135]))
//输出 "中文"
new TextDecoder('gbk').decode(new Uint8Array([0xd6,0xd0, 0xce, 0xc4]))
//输出 "中文"
(new TextDecoder('gbk')).decode(new Uint16Array([0xd6d0, 0xcec4]))
// "兄奈", 字节序问题, 这儿应该是小端字节序, 将字节反过来就对了
(new TextDecoder('gbk')).decode(new Uint16Array([0xd0d6, 0xc4ce]))
// "中文"

既然JVM上面可以运行客体语言, 那么会不会有人在JVM上运行JavaScript? 还别说, 真有!

ringo.js

先说第一个项目,ringo,它在github上有600多的star数目.
解压缩放入path后运行ringo, 进入其REPL, 我试了一下, 下面的是可以运行的:

f = function(s){console.log(s)}
f('hello')

ringo有自己的包管理工具rp, 跟npm差不多. 不过需要安装:

ringo-admin install grob/rp

然而我在windows 10上安装却会报错:

Wrapped java.lang.UnsupportedOperationException
        at fs.js:1100 (changePermissions)
        at C:\l\tools\admin\install.js:86 (installPackage)
        at C:\l\tools\admin\install.js:156 (main)
        at C:\l\tools\admin\main.js:14 (main)
        at C:\l\tools\admin\main.js:30

哦...这就无法继续了...
一个语言的强大在于其库的强大,如果它能同时使用npm和java库,那就真的非常强大了,看来暂时是无法验证了.

java8 jjs: oracle nashorn

没错. Java8支持JavaScript, 这个运行工具就是jjs, 正式名字叫做Nashorn. Oracle官方的这篇文章 Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM有一些说明, 我查了一下我的java, 还真是8:

λ java -version                                                         
java version "1.8.0_111"                                                
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)                   
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)        

根据文章说, jjs和java在同一目录, 能运行java就意味着jjs也能运行, 先看看版本:

λ jjs -v                  
nashorn 1.8.0_111         
jjs>                      

果然进来了呢! 试了一下, 居然不支持console.log...
对应的打印命令,居然是print...
对此, 文章是这样解释的: 虽然我们兼容ECMA, 但是浏览器环境下的特有变量我们是不支持的,比如window, console这些.

好处呢? 一个是在Java中调用JavaScript代码,还能用到JavaScript的库, 恩,这个感觉比较符合oracle的思路...
文中举例了在Java中调用mustache.js库的方式.

package sample2;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

public class Mustache {

  public static void main(String... args) throws Throwable {
    ScriptEngineManager engineManager = 
new ScriptEngineManager();
    ScriptEngine engine = 
engineManager.getEngineByName("nashorn");
    engine.eval(new FileReader("src/sample2/mustache.js"));
    Invocable invocable = (Invocable) engine;

    String template = "Email addresses of {{contact.name}}:\n" +
        "{{#contact.emails}}\n" +
        "- {{.}}\n" +
        "{{/contact.emails}}";

    String contactJson = "{" +
        "\"contact\": {" +
        "\"name\": \"Mr A\", \"emails\": [" +
        "\"contact@some.tld\", \"sales@some.tld\"" +
        "]}}";
Object json = engine.eval("JSON");
    Object data = 
invocable.invokeMethod(json, "parse", contactJson);

    Object mustache = engine.eval("Mustache");
    System.out.println(invocable.invokeMethod(
mustache, "render", template, data));
  }
} 

另一个是在JavaScript中调用Java,这个我比较关心. 哦, 直接调用就好了, 很简单的样子:

print(java.lang.System.currentTimeMillis());

Java对象也可以使用new来实体化, 这个就酷了:

var file = 
new java.io.File("sample.js");
print(file.getAbsolutePath());
print(file.absolutePath); 

java.io.File虽然没有定义absolutePath,但是定义了getAbsolutePath(), jjs会自动增加absolutePath这个属性. 对set也是一样.
这样来看,nashorn很可能可以同时使用部分npm库和java库,看上去很强大的样子.
剩下一个问题就是速度了. nashorn和v8对比速度如何? 从这篇文章来说,还是要差一些的. 对ES的支持呢? 似乎是支持到ES5.1,还没有对新特性的支持. 试了一下ES6中的箭头函数, 果然是没有支持的. 这点上就远不如node.js那么积极啦.

jjs> var a = ()=>{print()}                                                    
ECMAScript Exception: SyntaxError: <shell>:1:9 Expected an operand but found )
var a = ()=>{print()}                                                         
         ^                                                                    

nashorn项目官网

rhino.js

哦, 这个就是被java8抛弃的那个, mozilla基金会的项目, 官网, github项目地址

显示CPU使用情况

其实很简单.在"开发者选项"中,倒数第7项左右,有个"显示CPU使用情况",打开即可.
显示信息的解释(转载自知乎):
三个数字代表在三个不同间隔下(1, 5, 15分钟)估算的平均负载(load average)
数字下面显示的就是正在运行的各种进程,包括系统和应用程序的执行序(process)。
一般都是看后面的两个数字,了解系统是否会有长时间处在高负载的状况下,
短暂、突发的高负载并不会造成问题,可忽略不管。
数字越小越好,数字较大就表示机器过载或有某种问题。
单核CPU ,全负载是1.0 ,超过1.0 就表示有执行序在排队等待。
双核CPU ,全负载是2.0 ,因为它可以同时运行两串执行序。
如想要进一步了解,可用Android Show CPU Usage 找看看。
三星、华为等机子显示的数字也许代表不同的用途和意义?
或许就跟一些app 显示CPU, memory, I/O的负载一样。
顺便提一下,数字行和各个执行序都会有蓝、绿、红色的底色条,
数字行的底色条是所有执行序的底色条的总和。

  • 蓝色呈现的是低优先度的执行序
  • 绿色呈现的是一般优先度的执行序
  • 红色呈现的是系统内核的执行序

android studio

另外,还可以使用android studio 3的Android Profiler来查看.位置在View->Tool Windows->Android Profiler中. 前提是要连接USB线.

Flyme OS的性能监视器

FlymeOS在开发者选项的最后一项是性能优化,其中有个性能监视器,可以对CPU进行监控

其他Tips

在拨号菜单输入*#*#4636#*#* 可以看到一些神秘内容:)

Java作为当年为解决C/C++问题出现的语言, 在当今快速开发的环境下,总觉得已经慢慢不合时宜.而JVM经过多年的优化,已经早已摆脱当年速度太慢的恶名.于是多种新的语言使用不同于Java的新的语法运行于JVM之上,提供更加现代化的语言特性.
知乎上有这个问答: Groovy,Clojure和Kotlin都是基于jvm的语言,那他们在实际项目中的运用场景有什么区别?
为什么很多语言选择在JVM上实现?
我觉得JVM仍然越来越流行的重要原因,是跨平台和速度.

  • 跨平台尤其重要. Javascript, Python如此流行的最重要原因可能也是如此. Java能超越C/C++, 我认为它是第一个提出跨平台概念,一次编码多处运行理念的语言,这其中,JVM功不可没.
  • 速度是另一个重要原因. node.js作为晚于python的后起之秀, 之所以比python有更多的实际应用, 是因为其在并发速度上面甚至超过了很多传统语言.
  • 丰富的库也是很必要的. Java多年积累,库是极其丰富的,JVM天生拥有这些库, 这一点常常是从头做起的新生语言难以做到的.
    另外, JVM上可以任一实现的客体语言(Guest),可以紧跟时代趋势,包含新的语言特性. 比如现在流行的动态化,脚本化,函数式编程等,这样,语言常新,而JVM将用不过时.

ANDROID studio 3.0.1版本默认新建项目下build.gradle如下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

增加了代理,又增加了aliyun的镜像后, 还是无法下载对应的包, 不知道是不是3.0.1太新了, 修改为2.3.3:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
    // maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
       // google()
       jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        // maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
       // google()
       jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

下载成功!又提示我gradle太旧,我的是3.1,它说至少得3.3以上. 它也不提示个升级方法...
升级gradle: 下载,解压,改路径到bin.

二  环  解  中  环  二
环  城  放  兴  城  环
|==|==|二环|=====|
|  |==|环城|==|  |
|==|==|胜利|==|==|
|  |  |劳动|==|  |
|  | 府|  |  |  |
|  |  |东街|==|云东|
|  |==|人民|==|==|
|  |==|鲁迅|==|  |
|  |  |延安|==|  |
|  |和畅|钱 |  |  |
|  |  |投醪|==|  |
|  |==|环城|==|  |
|  亭  |  |  会  |
|  山  |  |  稽  |
|  |==|城南|==|  |
|==|==|二环|==|==|

测试金字塔,TestPyramid,主要是说你应该运行更多的单元测试,因为它又便宜有全面, 并且所有你在上层GUI测试中遇到的问题, 都应该通过增加和修改单元测试来得到完全地覆盖.

对比Appium和Espressoappium-vs-espresso. Appium是GUI黑盒, Espresso也是GUI测试, 不过要有源码, 可以说是白盒.
溢栈网上对appium和Espresso的对比.appium-vs-espresso-for-automated-testing-framework.主要是说espresso有如下优点:

  • 可以直接测试Activity
  • 可以直接测试Toast
  • 可以看到测试覆盖率

robolectric也是白盒, 但据他所说, 他更接近于黑盒, 并且有如下优势:

  • 不需要启动模拟器,直接在JVM中运行,速度快
  • 模拟绝大多数真实设备行为
  • 不需要mockito这样的mock框架

谷歌官方的android APP测试指导

知乎上的这个回答很好,可以参考:如何让各大搜索引擎搜索收录到刚建的wordpress网站?
里面提到了两个提交单个页面的工具
Google 网站站长工具
Baidu url提交_站长工具
对于google提交站点地图,在google console页面可以先添加站点资源,然后在站点地图里面增加站点地图.
对百度提交,在这个页面下面选择自动提交-sitemap的方式来提交.

不过typecho默认是没有站点地图的, 可以通过插件添加.

添加xml格式的站点地图

这篇文章里面介绍了typecho的google站点地图插件,下载解压缩后,将其中的Sitemap目录上传到usr/plugins中.登录typecho后台的插件页面,然后访问http://your.site/index.php/sitemap/就能得到google想要的xml格式的站点地图.
由于百度也支持谷歌的xml格式的站点地图,尝试提高上述地址时,却发现百度不能正确识别,似乎站点地图后缀必须是.xml.
于是,将上述插件Sitemap/Plugin.php中做一下修改, 第29~32行改为:

    public static function activate()
    {
        Helper::addRoute('sitemap', '/sitemap.xml', 'Sitemap_Action', 'action');
    } // old: 'sitemap', '/sitemap/', 'Sitemap_Action', 'action'

重新上传并启用,新的地址变为http://your.site/index.php/sitemap.xml
再次加入百度的站点地图后成功了.

添加html格式的站点地图

在这篇文章:Typecho 无插件轻松实现html站点地图中,提供了无插件下载站点地图的方式. 将文章中的php上传到usr/themes/default/中, 再在typecho后台创建页面,将连接地址设置为sitemap.html, 选择自定义模板为Template Page Of Sitemap,公开度设置为隐藏, 访问http://your.site/index.php/sitemap.html即可.

node-serialport确实是一个非常麻烦的模块,相比来说,python的pyserial就要好用很多啊.
node升级后,到对应的项目目录中, 在node_modules\serialport下,运行node-gyp rebuild,可以重新编译serialport模块.

晴日携妻游方时,广场阔阔人如织。玻璃长廊场中现,凌空三米好景观。欲寻入口在场心,一无楼梯二无门。旁置梯子搭来使,梯短口高勉强支。妻子担忧手扶好,场工建议如此般。爬至梯顶手举直,撑开数块压口板。下宽上窄人难爬,思忖我上将妻拉。妻与场工多主意,我仍决定尊自意。方换一边爬上梯,一梦忽断续无期。

是在受不了grav的体积...已被撑爆...删除全站转typecho了.
grav号称宇宙最强flat cms,看来不适合我

互联网服务的本质是信息的服务.
信息服务的本质是解决两个问题: 信息的产生和信息的获得.
哪一个价值更大?如果从市值最高的这些互联网公司推断, 解决信息获得问题的价值更大, 可以排为互联网服务的第一本质. 换一个互联网的名词: 解决了入口问题,做的是平台的生意.
举例来说,百度,谷歌,不产生信息,而是为通过搜索引擎梳理和连接信息, 找出搜索关键词和目标信息的关联, 也就是解决用户信息获得的问题.淘宝网解决了商品信息的获得问题, 同时也为信息的产生提供了平台,并且它阻止百度从他那儿获取信息.为什么阿里不让百度替他解决信息获得的问题?这在淘宝之前的大多数电商网站都是巴不得的,因为带来的更多的流量!那就是因为,信息获得更有价值,产生的信息不让其流出,逼迫用户只能从他这儿获得信息,从而为他产生价值.
从信息产生和获得的人群来说,获得信息的人很多情况是比要产生信息的人要多.一个人花费在获得信息上的时间,也通常比产生信息的时间要多.一个人同样的时间内去获得信息和产生信息, 获得的信息也比产生的信息多得多.
网络游戏是信息产生和获得的一种升华,他提供了另一种娱乐体验,不由用户产生直接信息(可能只是终端发给服务器的二进制数据),和获得(消费)直接信息,如果计算利润, 互联网游戏也占比很高.但本质上其游戏体验的价值还是远超过信息的价值的,互联网在其中不可或缺,但不是主要价值提供者,游戏趣味本身才是.当然你也可以说游戏的整个安装包也是一个信息, 但这个信息不一定是通过网络获取(光盘U盘也可以), 其中的信息也是不可检索的.
从这个角度,进一步看互联网服务的本质,是可检索信息的服务.第一本质是可检索信息的获得.
如今日头条,在一开始也只是从各个网站抽取新闻才快速发展起来的.做起来的视频网站,一开始也只是搜集其他的个人上传视频,然后让用户可以观看,搜索,解决用户信息获得的问题.豆瓣,知乎主要解决了信息产生,但由于其向百度开放了搜索(大多数网站都是这样的),而百度上信息获取更容易,所以豆瓣知乎仍需要借助百度解决信息获得问题,本身价值就会下降.
当然,将信息截流在自己的服务器上,不许其他服务器爬取,听上去就违反互联网精神,但实际上很多互联网公司就是这么做的.阿里电商,京东电商,微信公众号文章,都是产生了信息之后截流在自己的服务器上.于是就有了爬虫和反爬虫的斗争.
对信息的截流可能有这些方式:

  • 版权的名义进行截流.如文学网站宣称对于在自己网站上发布的销售拥有版权,视频网站同样的方式或者通过购买正版版权,独占版权等进行信息截流. 建立了信息发布平台,购买了版权,就可以以此名义截流.
  • 流量的名义要求信息生产者发布独占信息或定制化信息. 如平台独占游戏, 渠道APP包, 平台独占文章(挖知乎达人要求只为自己生产内容), 双11要求商家二选一等. 形成平台效应,在某一领域有足够大的流量甚至是垄断流量,就可以这么做.
  • 技术上防止爬虫, 阻止信息外流.如将价格使用图片显示, 增加防爬虫的标识等.

在国内,大公司截流信息的情况应该是非常普遍的.