Frossky 发布的文章

RPC(remote process call)远程过程调用,指的是要调用一个本机上没有的方法,并获取结果。
这听上去和API差不多,通常API都是基于http的,准确的说是http/1.1。并且以JSON作为返回值。
更理想和漂亮的API调用就是Restful的API,同样基于HTTP/1.1,使用了协议提供的get,post,delete,put等方法。
然而追求效率的程序猿们发现HTTP/1.1协议本身的问题造成延迟,导致响应速度有些慢,于是google提出了一种基于HTTP/2(更快的HTTP)的gRPC协议。
当然作用是比Restful API更快了。
这儿还有一个gRPC和Restful相互转换的项目grpc-gateway
nodejs使用grpc,看这儿
简单来说,nodejs中,需要
1. 定义服务接口, 在xxx.proto文件中定义。定义采用的是protocol buffer数据结构,哦,又是另一种XML、JSON的替代品。但protocol buffer(现在是第三版proto3)不止如此,它更是一种语言
2. 定义服务端,在server的.js文件中定义。
3. 客户端调用。

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。

tortoiseSVN commit的时候忽然不能显示新的文件了, 只好用命令行.

svn add * --force

可是这个命令行居然也不起作用了. 难道是有忽略文件?

svn add *  --force --no-ignore

这次可以了, 可是是在哪儿忽略的呢?似乎是忽略了所有任意的文件啊

似乎很难搜索到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是不是就像是自然语言了?