关于随机数

在随机数这个问题上,一般程序员总是要经历下面的过程:

  1. 压根没有随机数的概念,想使用随机数的念头往往出于想每次执行自己辛辛苦苦写的小程序时可以有不一样的结果。
  2. 发现有个函数/方法是专门用来生成随机数的,试了一下,确实挺随机的。
  3. 兴高采烈的在自己的小程序里使用了这个函数/方法。结果发现每次结果其实还是一样的(C的话)
  4. 经历了千万次google才发现原来自己没加种子,只有不同的种子才会产生不同的随机数。往往种子都是使用一个恒定在变的东西——–时间。
  5. 当程序被高频访问的时候,问题又来了————-时间在计算里有最小单位,所以高频访问中临近访问的随机数是一样的。
  6. 又学会了一种叫随机数仓库的东西,来应对突然的高频访问。不断的往随机数队列里填充随机数,然后每个访问都是去随机数队列里去取。
  7. 然后,突然有一天,有人告诉你,这些不是随机数,最多只能称为伪随机数。

那么问题来了,什么是伪随机数,维基百科上的解释

伪随机性英语:Pseudorandomness)是指一个过程似乎是随机的,但实际上并不是。例如伪随机数(或称伪乱数),是使用一个确定性的算法计算出来的似乎是随机的数序,因此伪随机数实际上并不随机。在计算伪随机数时假如使用的开始值不变的话,那么伪随机数的数序也不变。伪随机数的随机性可以用它的统计特性来衡量,其主要特征是每个数出现的可能性和它出现时与数序中其它数的关系。伪随机数的优点是它的计算比较简单,而且只使用少数数值很难推算出计算它的算法。一般人们使用一个假的随机数,比如电脑上的时间作为计算伪随机数的开始值。

所以严格来讲,计算机生成的随机数并不是严格意义上的随机。那么我们如果想要真正的随机数怎么办呢。

有一个简便的方法,调用http://random.org的接口。

调用示例等参考此链接

 

Javascript的KeyCode

在前端开发中,经常使用onkeypress,onkeydown等event来做快捷键。
我之前就是打算使用“;”来做快捷键功能。
使用了如下代码

document.onkeydown = function(e) {
    e = e || window.event;
    var kcode = e.which || e.keyCode;
	if(String.fromCharCode(kcode) == ";") {
              // TODO Place your code here.
	}
};

结果。。。只有在Firefox好用,Chrome和IE都阵亡了。
我并没有做任何的浏览器判断,怎么会自动按浏览器区分功能呢?

原来,对于event的keycode,大部分的按键的keycode值在所有浏览器中都是一致的。
但是,有一小撮按键。。。。很不幸就有我选中的的“;”,在firefox和Chrome中是不一致的。
具体列表参照http://www.javascripter.net/faq/keycodes.htm

Salesforce如何取得Guest User的Debug Log

// Update4 2018/04/10

Salesforce这次不仅吃书。。。连设定都吃回去了。。。
这篇文章不用看了,以后再也不用设Cookie了。一切又回到了最初的样子。
官方文档

从Winter’17开始,Guest User的Debug Log不再能通过正常渠道直接获取了。这给我们做Wechat集成的小伙伴们造成了很大的困扰。
虽然说官方文档中,介绍了在Chrome下使用插件添加Cookie的方法来激活Guest User的Debug log,但微信里是没法修改Cookie的。
不过官方提到了可以通过各种代码添加Cookie的Sample Code,尤其是Javascript,可以放到被访问的页面上。
代码只有简简单单的一句

document.cookie ="debug_logs=debug_logs;domain=.force.com";

在修改了Page之后,兴冲冲的打开了微信进行测试,发现并没有卵用。
然后切回浏览器,通过浏览器访问发现,这段Js代码加入的Cookie值与我之前用插件添加进去的值并完全不一致。
不一致的属性是“Path”,由于我的Salesforce Site是设定了Path的,所以Js代码生成的Cookie的Path也跟着变成了我设定的Path。而我用插件加入的Cookie的Path属性默认为“/”。
好,那么我们修改一下这句Js

document.cookie ="debug_logs=debug_logs;domain=.force.com;path=/";

修改完之后再试,问题解决,Debug Log乖乖出来了。
打完收工。

// Update 1

微信内置浏览器是可以使用Cookie的,不过要慎重,因为微信的内置浏览器对于Cookie的处理策略与桌面浏览器不是很一致,并且每个版本都有变动。所以不应该过度依赖于微信内置浏览器的Cookie。

// Update 2

微信的内置浏览器为X5内核,所以行为和渲染等都与Webkit内核有出入。慎重!!
另,Spring’17 开始进入倒计时的时候,发现前文提到的官方文档不见了!!但是此方法仍然有效!!到底发生了什么!!

// Update 3
对于Salesforce官方不断吃书的行为表示不满与谴责(Knowledge文章被取消了)。
然并卵,已经不是第一次吃书了,所以想参考官方文档的同学看这里

关于Lorem Ipsum

对于前端开发人员来讲,涉及到内容填充或者排版的时候,最常用的就是Lorem Ipsum文本。

标准文本内容

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

// Update 1

在Word里如果输入=Rand()会随机的生成一段文本给你当填充物,或者输入=lorem(),则是填充Lorem Ipsum。当然这两个函数都贴心的设置了可选参数,可以选择长度与段落数量等。

Salesforce删除数据时出现Insufficient privileges的可能原因

遇到一个诡异的情况,用户通过界面删除一条自定义Object的数据的时候出现了Insufficient privileges。
按理说,如果用户的Profile没有此Object的删除权限的话,应该连删除按钮都看不到才对。

事情有蹊跷。首先检查了Profile,增删改查都有,但是没有Motify All和View All。
那么排除了Profile的嫌疑。
接下来查看Role。发现此用户的Role在role hierarchy中已经是比较高的位置了。
然后检查Sharing Rule。发现此Object的基本Sharing设定已经改成了Private,并且启用了role hierarchy。
那么问题就应该出在这里了。
去查看用户无法删除的那条数据,果然Owner不是用户本人,且Owner的Role与此用户同级。

在Salesforce中,如果Object的全局Sharing Rule为Private,那么除非用户的Profile是System Admin或者拥有Motify All权限,否则当用户想删除的数据的Owner为别人且Role为同级或者更高级的话,就会出现权限不足的问题。

告知用户,想删除此数据的话,请先把Owner改成自己,然后再删除。问题解决。

参考来自官网的信息

Task中的字段TaskSubType在ApexClass中不可见问题

在Task上有一个标准字段叫做TaskSubType,是一个Picklist。在属性页面无法看到与选择任何属性。也无法更改Picklist里的值,虽然里面有内置三个值。

某一天,我试图在Task的trigger里判断字段TaskSubType的值,在保存代码时报错,错误内容为“Error: Compile Error: Invalid field TaskSubtype for SObject Task”。

我用查询工具查询该字段,正常。
我用匿名块访问该字段,正常。

奇了个怪了。

使用查询工具查看该字段,有create-able,filter-able,nillable,restricted picklist,sort-able,没有update-able。不过应该不影响这里。也查看了FLS,也没有问题。

好,耐心查看Task的文档,发现此字段原名ActivitySubType,是在Winter’16加入Salesforce的。再回头一看ApexClass,原来用的是API 30。

果断改成API 36。保存正常。

这个就类似于Java的JDK,在JDK1.8加入的新特性,在JDK1.4是肯定无法使用的。
较早前创建的Apex Class或者Visualforce Page一定要注意API版本问题。

Salesforce的Trust终于改版了

trust site是由Salesforce提供,用来监控所有服务与实例状态的网站。

经典应用场景是,发现实例变得很慢,然后打开trust,哦。。。发生了性能降低。

新版trust也提供了新版API,可以获得相关实例的JSON串,自己定时获取,自己解析,可以实现自动提醒,自动警报。

API地址 https://api.status.salesforce.com/v1/instances/{你的实例名}/status

所有接口的说明 https://api.status.salesforce.com/v1/docs/

phpfreechat中一个啼笑皆非的Bug

因为觉得所有在线聊天工具要经过人家的服务器不够把握,所以在自己的服务器上架设了phpfreechat。
这款在线聊天室,有着不在服务器储存任何聊天记录的优点。

然后有一天,我试图在上面发送一个数字 0
没有任何反应。
习惯性的按了下F12,发现phpfreechat提供了控制台输出。

readyState: 4, responseText: "{ "error": "Wrong message format (must be a JSON string)" }", status: 400, statusText: "error"}

哦?必须是个Json?
又去下了一份源代码,查找报错内容 “Wrong message format (must be a JSON string)”。
顺利定位到唯一一本代码,channels.php中的如下代码片段。

  // check that request content contains a message
  $data = json_decode($req->getBody());
  if (!$data or !is_string($data)) {
    $res->status(400); // Wrong message format
    $res['Content-Type'] = 'application/json; charset=utf-8';
    $res->body('{ "error": "Wrong message format (must be a JSON string)" }');
    return;
  }

如果我在第二行传入了一个0,$data仍然等于0。
在第三行,死在了!$data上。!$data是个很诡异的判断。
在PHP中,非0即true,0即false,”0″是false,’0’也是false。
就因为我写了一个0,便中了招,进入了报错代码块。

我们再来看一下第三行代码的意图: 如果非(false/0/null/未初始化/””/…) 或者 不是字符串的话,报错。
可是我单独打一个0,并不应该被算作非法输入。
那么改成什么好呢?

Salesfroce更新了Summer 16′ 版本的ForceIDE v37.0

官网地址:https://developer.salesforce.com/page/Force.com_IDE_Installation
更新日志:https://developer.salesforce.com/page/Force.com_IDE_Release_Notes

我在Eclipse Neon上已经成功更新。
本次更新的最大变更是。。。。更改了插件安装地址。没错。
还有提供了Lightning单独的开发组件。

另外,值得一提的是,启用了Java早就有的Open Type功能。

重点来了,打断点! Debug调式!没错!像个堂堂正正的Java程序员那样!
不过我还没试验这个新功能,之后会更新。