MQTT,全称Message Queue Telemetry Transport消息队列遥测传输,是一种开销较小的、使用订阅机制传输信息的协议。
协议中两种设备,Broker和client,broker相当于服务器的角色。
例如,Client B, C是两个显示屏,向Broker订阅(Subscribe)温度主题(topic)。
温度传感器为client A,向broker发布(Publish)一个温度主题。此时,broker向已订阅温度的client B、C发送温度信息。
协议原文

VBA学习最好使用Excel VBA中的对象浏览器, 在视图菜单中(F2)
Application和Window类默认似乎是不需要写, 就可以引用他们下面的属性和方法.
最常用的类是Range, Cell
Application.Evaluate是将名称管理器中的名称或者单元格名称转换为Range. 简易写法是中括号[]
定义函数

Public Function FunctionName(args...)
End Function

赋值和逻辑比较.. 在条件里面就是比较, 否则是赋值.
打印输出: Debug.Print
字符串合并 "a" & "b"
定义全局变量要写在最前面

Public VarName As Type

返回应用程序完整路径
Application.Path

返回当前工作薄的路径
ThisWorkbook.Path

返回当前默认文件路径:
Application.DefaultFilePath

Application.ActiveWorkbook.Path 只返回路径
Application.ActiveWorkbook.FullName 返回路径及工作簿文件名
Application.ActiveWorkbook.Name 返回工作簿文件名

VB的一些基础

For ...Next循环,跳出方式为Exit For,似乎没有跳过本次到下次循环的方式,只能用IF判断体包裹。
If ...Then ...Else ... End If 判断,其中的“=”为判断,不是赋值。VB根据上下文判断等于号是赋值还是判断。不等于是“<>”。

VBA打开其他工作簿

两种方式:
Workbooks.Open Filename:="D:\r\可视化单簿合多表\test测试.xlsx"
或者
Dim wb As Workbook Set wb = GetObject("D:\r\可视化单簿合多表\test测试.xlsx")
区别在于,GetObject是隐藏方式打开的。并且这个隐藏属性是可以保存的,如果保存了, 下次打开就无论如何都看不到了。
如果要显示,可以在excel的“视图-取消隐藏”中取消,或者使用
wb.Windows(1).Visible = True
记得要保存。

jekyll基于ruby做静态站点的生成.哦, 服务器端还是需要跑ruby才行的...
另外千万不要看中文站点, 文档有错误, 最大错误就是, 除了装ruby和rubygems以外还要装bundler, 中文站却没有提. 还是要阅读英文原站的文档.

移动端vue的ui组件最著名的应该是vux, 基于Wechat的官方ui weui.

现在pc端也有一个UI标准称之为 Ant Design, 是阿里主导设计的, 基于ant design的一种Vue实现, 是 iview

我们常用的云平台类SaaS系统一般都是有个后台管理界面,英文称之为admin或者dashboard, 有很多这种的后台都是基于bootstrap实现的, 并且一般都自动适配PC端和移动端.

在Github上适配vue的admin模板有 vue-admincoreUI.
其中vue-admin是比较深度的使用了vue的特性, 同时可以兼容在electron中使用. 而coreUI对vue的使用较简单, 但却做到了多种框架的适配, 如angular, react等. 这两个功能上都欠缺的一点是table上进行增删改的操作, 这是其他大型admin模板一般都具有的.

github上搜索admin, 排在前面的admin 模板有2013年12月开始的adminLTE, 2015年5月开始的gentelella, 2015年9月开始的blur admin, 2016年4月开始的ng2-admin.

其中, blur admin使用的是加载结束才显示的方式, 每次加载的时间有数秒钟, 似乎有些太久, 不过加载完后体验比较好, 很多动画效果, 也不卡, 类似于gmail的体验, 有smart table功能, 支持增删改. gentella加载很快, 内容也比较丰富.

这儿有个博客大前端工具集搜集了很多很全面的前端工具, 值得参考.

emacs tutorial前半段讲的几个命令,如下
上下左右一个字符: c-pnbf
左右一个词 m-bf
行首尾 c-ae
句首尾 m-ae
前后翻页 mc-v
文首尾 m-<>

重复number次命令 c-u number 命令
取消操作c-g
切换窗口数量 c-x 1
重载 c-l

删前后一个字符 c-d
剪后一个词 m- m-d
剪至行尾 c-k
剪至句尾 m-k
选择剪切 c- c-w
粘贴最近 c-y
粘贴以前的 m-y
撤销 c-/ 或者 c-_ 或者 c-x u

打开文件 c-x c-f
保存文件 c-x c-s
保存所有未存文件 c-x s
打开缓存列表 c-x c-b
打开某一缓存 c-x b 缓存名

退出 c-x c-c
切换到命令行 c-z ,切回来 fg 或者 %emacs

搜索 c-s

初上手不太熟悉, 在vue-router的官方文档中也没有找到结合单文件组件怎么使用. 通过vux的模板摸索如下规律:

  1. 根目录下面的index.html可以不做任何修改;
  2. 路由的引入主要是在src目录下的main.js文件中, 示例:
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
import Home from './components/HelloFromVux' // 引入各个 .vue文件, 这儿有HelloFromVux.vue和Hello.vue. 这儿省略了.vue后缀, 需要在webpack的配置文件中配置, 后面说.
import Hello from './components/Hello'
Vue.use(VueRouter)  // 单文件组件开发中必须要引入

const routes = [
    {path: '/', component: Home},
    {path: '/hello', component: Hello}
]

const router = new VueRouter({
  routes
})

/* eslint-disable no-new */
new Vue({
  el: '#app-box',
  router,
  render: h => h(App)
}) // .$mount('#app-box')
// .$mount或者 el: 两种方式的mount都可以. 因为是加在在#app-box中的, index.html中的div id需要是app-box

3.项目根目录webpack中配置(webpack.config.js)如下内容可以在import时省略.vue后缀:

  resolve: {
    extensions: ['.js', '.vue', '.json']
  },
  1. 那么在哪儿放呢? 不用放在index.html里面, 在任何一个.vue文件的template里面都可以, 并且不需要在.vue的script里面import vue-router
    例如在app.vue中:
<template>
  <div id="app">
  i am app
  <router-link to='/Hello'>Hello</router-link>
  <router-link to='/'>home</router-link>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style lang="less">
</style>

sublime中jshint是使用用户目录下的.jshintrc做配置的. 在windows系统中位置在:

C:\Users\YourUserName\.jshintrc

默认这个配置文件不存在, 需要自己新建一个.
.jshintrc内容如下, 我做了些修改以适应vue的风格
(asi:true, 不检查分号, esversion:6, 使用es6语法; browser: true, 加入浏览器的全局变量)

{
  "asi": true,
  "boss": false,
  "camelcase": true,
  "curly": true,
  "eqeqeq": true,
  "eqnull": false,
  "esversion": 6,
  "evil": false,
  "expr": false,
  "forin": true,
  "funcscope": false,
  "immed": true,
  "indent": 2,
  "latedef": true,
  "loopfunc": false,
  "maxerr": 7,
  "newcap": true,
  "node": true,
  "nonew": true,
  "plusplus": true,
  "quotmark": "single",
  "regexdash": false,
  "shadow": false,
  "strict": false,
  "sub": false,
  "supernew": false,
  "trailing": true,
  "undef": true,
  "unused": true,
  "white": true,
  "browser": true
}

更多详细配置请参考JS Hint Options

跨域是JS的xhr跨域请求。静态资源无跨域限制。
不同端口/二级域名/一级域名都存在跨域问题。
一个经典跨域问题是页面通过iframe内嵌其他域的页面。
最古老解决跨域的方法是iframe代理页面。受限最多。
次古老解决跨域问题是jsonp。据说请求限于get/head/post。
最新解决跨域问题是cors。适用于restful。

似乎很难搜索到Node.js与C++对比的资料. 当然不对比也知道C/C++一定更快, 但究竟快多少?
这儿有一篇解决最长共有子串问题的对比, 但看起来更像是CUDA的软文... (CUDA vs. C++ vs. Node.js: Genomic Algorithm Performance)[http://www.glassenberg.com/blog/3d-graphics/cuda-vs-c-vs-node-js-genomic-algorithm-performance/]
从文中来看, 这种算法下C++是Node.js的10倍. 当然CUDA更快.
从Java和C++的对比来曲线比较Node.js呢? 这篇2010年文章(C++ vs Java performance; It’s a tie!)[http://blog.cfelde.com/2010/06/c-vs-java-performance/]. 从文中的12项测试来说, Java与C++各有胜负打了个平手. 然而作者在2003年做的比较中, java居然获胜了... 我猜测这是否由于测试中任务太高级的原因?
在google的一篇对比论文中(Google pits C++ against Java, Scala, and Go)[http://www.theregister.co.uk/2011/06/03/google_paper_on_cplusplus_java_scala_go/],google对比了C++, java, scala,go, 当然C++获胜, 可有个前提: 除非你是个天才. Google在论文中提到, 让C++获胜需要很多深度的优化调整, 而这种程度的调整对于平均水平的程序猿来说是不可能的.
因此, 如果C++没有赢,那是因为你的程序写的不够好(逃..),当然了, C/C++是距离汇编最近的语言了, 这个层次上没人赢得了.

话说回来, 既然C/C++这么难搞, JavaScript能不能用于嵌入式?
已经有这样的项目了, 国内有(ruff)[https://www.ruff.io/], 国外有(Espruino)[http://www.espruino.com/], 以及Espruino衍生的(Puck.js)[https://www.puck-js.com/]项目, 但这些项目粗看起来都是要你买他们的板子...似乎还不存在一个较为通用的编译器可以编译为51, AVR或者STM32的.不过这已经不错了是不, 特别看到Espruino Pico这么小巧还有一个STM32!

也许正如ruff的CEO所言, JavaScript可以让前端工程师开发硬件, 可能会带来硬件创业爆发式的春天.

Node.js比Python更快, 我在之前已经试验过了, 甚至比Python的性能优化项目pypy更快. 快得不是一个数量级.
Node.js甚至也比PHP更快, 以至于快过了Facebook对PHP的优化项目HHVMComparing Node.js vs PHP Performance, 但是比不过go语言.
Node.js比Java更快, 在这篇文章里快20% (Performance Comparison Between Node.js and Java EE)[https://dzone.com/articles/performance-comparison-between]
那下一步令人好奇的是,

  • Node.js和C/C++谁更快? 已经有一个项目将C/C++编译为JavaScript的子集(asm.js)[https://github.com/dherman/asm.js/], 为的是让C/C++项目可以在浏览器环境运行(更多是游戏运行于webGL), 还有一个LLJS项目,LowLevelJavaScript,似乎与之有关, LLJS不提供动态GC(垃圾收集), 而是交给程序猿手动收集(LLJS on GitHub)[https://github.com/mbebenita/LLJS]
  • Node.js能不能用于嵌入式开发? 与C/C++相比, 性能如何?

是的, 继前一篇JS可以使用字符串做函数名之后, 又可以使用object做函数名了. 事实上, 它还能使用Number, Boolean, Symbol(ES6)做函数名.

秘诀其实是对象的key可以这么做. 你可以使用字符串, number,boolean, symbol, object做key.

而你又知道所有的全局变量其实都是window(node下是global)的子元素, 所以你可以这么定义:

obj = {x:1}
window[obj] = function(){console.log('obj')}
window[obj]() // 输出 'obj'

window[true] = function(){console.log('true')}
window[1] = function(){console.log('1')}
s = Symbol()
window[s] = function(){console.log('s')}

window[true]() // 输出true
window[1]() //输出 1
window[s]() //输出 s

但这又有什么用? 不知道...谁能告诉我?

是的, 并且是es5就已经只支持的.
因为函数和变量一样, 默认是全局变量的子元素, 并且子元素除了用点'.'调用外,还可以用数组方括号[]调用. 区别是方括号内是写字符串的.

p = console.log //省字数
function x(){p('x')}
function y(){p('y')}
f = 'x'

这时候, window.x === window['x'] 都是x函数.(在node中window甩global替换) 于是可以这样调用

window[f]() // 输出x
f = 'y'
window[f]() // 输出y

这样执行相同的指令window[f]可以实际执行不同的函数x,y
参考how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string
后面有一个回答很有价值的, 就是将函数的点链式调用写在字符串里面,复制过来,感觉如果和科里化/pointfree结合会很有用, 似乎能创造一种自然语言一般的编程方式.

来自Jason Bunting的回答:

Don't use eval unless you absolutely, positively have no other choice.

As has been mentioned, using something like this would be the best way to do it:

window["functionName"](arguments);

That, however, will not work with a namespace'd function:

window["My.Namespace.functionName"](arguments); // fail

This is how you would do that:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

In order to make that easier and provide some flexibility, here is a convenience function:

function executeFunctionByName(functionName, context /*, args */) {
  var args = [].slice.call(arguments).splice(2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

You would call it like so:

executeFunctionByName("My.Namespace.functionName", window, arguments);

Note, you can pass in whatever context you want, so this would do the same as above:

executeFunctionByName("Namespace.functionName", My, arguments);

如果把上面的My.Namespace.functionName改成My Namespace FunctionName是不是就像是自然语言了?

官方原文为系统内置事件之触摸事件冒泡
感觉原文讲得并不清晰, 并且似乎和实际有出入.
原文中讲到两种冒泡:
* 一种是沿着节点树, 也就是层级管理器中的节点关系, 从子节点向父节点冒泡;
* 另一种是沿着视图中的上下层覆盖关系, 从上层往下层冒泡.
经过测试发现, 沿着节点树冒泡, 每一层节点都可以捕获到事件, 除非在某一层上明确使用e.stopPropagation()
而沿着视图冒泡, 有两点不同:
1. 事件会在最先捕获touch事件的节点上终止,不继续向下层冒泡;
2. 捕获任一touch事件(如touchend), 其他touch事件(touchstart, touchmove, touchcancel)都在此节点上终止, 下层视图都不能收到事件;