爱好收藏

老白老白

上个月开始看美剧,绝命毒师,五季看完,真的很棒
沿用网友们的习惯,我们把男主沃尔特,叫“老白”

几个角度:
1. 第一、二季的时候,感受最深的是(口可口可,估计是人到中年有共鸣),一个男人,为了家庭,真的不容易。
一个将死之人,为了自己老婆孩子,去做这种“不要命”的搞毒品的事,游走在各色风险之间,去和各种“不要命”的人打交道。
2. 业务模式的发展,从房车/地下室“小作坊”,一路走到和大毒枭联合,再到自成一派
做什么,都要有个学习、提高、循序渐进的过程:
第一季,他们找屠库出货;
第二季屠库死了,他们只能自建渠道去卖;
再到后来给大毒枭打工,只做直接最擅长的制毒工作,将销售交给其他大佬
最后一季,对整个行业上下游有了足够了解后,开始单干
3. 钱,money,多少才到头
从开始,算的清清楚楚,只想挣76.x万美元,却一次一次被中断制毒、堵死销路,用了两季也没打到目标
到后来坐上大毒枭的顺风车,已经远远超过了目标,却还不满意,还受不住手
第三季的时候,面对各种风险,加之身体暂时没问题了,其实男主已经放弃了制毒,可惜又被毒枭拉下了水
到第五季,有一个大好的机会,没有什么风险一下赚到500万,可自信心爆棚的男主,却已经收不住手了,一口气赚到了九千万!
这时再收手,却已经晚了。。。

4. 故事&剧情
很佩服美剧的编剧们,第二季,汉克和乌龟那段,和主剧情基本无关,但是作为一个独立的故事,也是非常精彩
另外,第三季吧,那只苍蝇。。。哈哈,一只苍蝇居然真的拍了一集,而且并不让你觉得无聊,反而能感受到人物内心的煎熬
5. 汉克
说实话,整整五季,最痛心疾首的就是汉克的死。虽然很讨厌他对男主一直穷追不舍。可是这么敬业、这么有正义感的一个警察,突然就死了,真的不应该啊
6. 谎言
为了可以有时间去安心制毒,从第一季开始,男主对老婆编造了一个又一个。。。“善意的谎言”。可看似“天衣无缝”的谎言,到后来却一一被识破,直到最后,老婆完全不在信任男主。这种情况,太矛盾了:你能接受“为你好、对你有利”的谎言吗?
———
不像很多美剧为了拍续集、不停故能玄虚绕圈子的套路,绝命毒师是一个完整的故事,到第五季结尾,尘归尘土归土,男主给家人留下了足够的钱,然后清理掉仇人,自己也挂了
话虽如此,倒数第二集,男主独自一人,守着一千万,躲在穷乡僻壤的小屋里。。。这时,真的希望故事就这么结束
可惜男主杀了个回马枪
故事结局,还算圆满吧,无论最初的目的是什么,男主也算罪大恶极,死的也算罪有应得
而他拼了老命挣下来的钱,总算有了一个合法的渠道,可以给到他的家人了~~,堪称死得其所

Hello World

指定eclipse启动jdk

对于一个懒人,最讨厌的就是各种升级了,所以手头的工具,基本都是能不升就不升
昨天因为调试程序需要,升级了mac的jdk,从1.6升到了10,结果今天eclipse就启不来了,报错:
java.lang.NoClassDefFoundError: org/w3c/dom/stylesheets/StyleSheet
。。。。
没细看,因为用脚指头也能想到,四年了,这个eclipse一直都正常,肯定是昨天升级的锅
搜了一下解决方案:
修改“eclipse.ini”,加上这么两行,指定jdk就行了:
-vm
/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin

mac版eclipse,需要右击启动eclipse.app,“显示包内容”,Eclipse.app/Contents/MacOS

Hello World

js里,image onload事件无效问题的处理

使用image的src,做页面事件上报,上报成功,标记
但是奇怪的是,使用new Image()方式,注册的onload一直无效
使用前端开发工具,看img请求,返回,都正常
查了一下,有些人说,是onload,在src后面的问题,img如果加载很快,以至于在onload就加载完了,所以需要将onload放在src前面
。。。可以肯定的是,保证不是这个原因,因为js是事件驱动的,除非src和onload不在同一个代码段里
后来,突发奇想,测试onerror,居然会执行
于是翻出红宝书查,onload是在图片加载完成,并且图片解析无误时,才会触发。。。图片解析无误
。。。
这个请求,返回的是一段base64,很久以前的一段老代码,是一个1*1的图,但是,不知什么时候,估计是为了返回内容少一点,删了一段。。。出错了,图片解析不成功
于是重新搞了一个图片,echo出去~~ok了!!
。。。
重复一下上面一大段文字的中心意思:
onload是在图片加载完成,并且图片解析无误时,才会触发
———-
转载请注明出处:http://www.jiangkl.com/2018/04/image_onload_无效/

Hello World

[转]python参考–字符串方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
capitalize()  #把字符串的第一个字符改为大写
casefold()    #把整个字符串的所有字符改为小写
center(width) #将字符串居中,并使用空格填充至长度 width 的新字符串
count(sub[, start[, end]]) #返回 sub 在字符串里边出现的次数,start 和 end 参数表示范围,可选。
encode(encoding='utf-8', errors='strict') #以 encoding 指定的编码格式对字符串进行编码。
endswith(sub[, start[, end]])  #检查字符串是否以 sub 子字符串结束,如果是返回 True,否则返回 False。start 和 end 参数表示范围,可选。
expandtabs([tabsize=8])  #把字符串中的 tab 符号(\t)转换为空格,如不指定参数,默认的空格数是 tabsize=8。
find(sub[, start[, end]])  #检测 sub 是否包含在字符串中,如果有则返回索引值,否则返回 -1,start 和 end 参数表示范围,可选。
index(sub[, start[, end]])  #跟 find 方法一样,不过如果 sub 不在 string 中会产生一个异常。
isalnum()  #如果字符串至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False。
isalpha()  #如果字符串至少有一个字符并且所有字符都是字母则返回 True,否则返回 False。
isdecimal()  #如果字符串只包含十进制数字则返回 True,否则返回 False。
isdigit()  #如果字符串只包含数字则返回 True,否则返回 False。
islower()  #如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回 True,否则返回 False。
isnumeric()  #如果字符串中只包含数字字符,则返回 True,否则返回 False。
isspace()  #如果字符串中只包含空格,则返回 True,否则返回 False。
istitle()  #如果字符串是标题化(所有的单词都是以大写开始,其余字母均小写),则返回 True,否则返回 False。
isupper()  #如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回 True,否则返回 False。
join(sub)  #以字符串作为分隔符,插入到 sub 中所有的字符之间。
ljust(width)  #返回一个左对齐的字符串,并使用空格填充至长度为 width 的新字符串。
lower()  #转换字符串中所有大写字符为小写。
lstrip()  #去掉字符串左边的所有空格
partition(sub)  #找到子字符串 sub,把字符串分成一个 3 元组 (pre_sub, sub, fol_sub),如果字符串中不包含 sub 则返回 ('原字符串', '', '')
replace(old, new[, count])  #把字符串中的 old 子字符串替换成 new 子字符串,如果 count 指定,则替换不超过 count 次。
rfind(sub[, start[, end]])  #类似于 find() 方法,不过是从右边开始查找。
rindex(sub[, start[, end]])  #类似于 index() 方法,不过是从右边开始。
rjust(width)  #返回一个右对齐的字符串,并使用空格填充至长度为 width 的新字符串。
rpartition(sub)  #类似于 partition() 方法,不过是从右边开始查找。
rstrip()  #删除字符串末尾的空格。
split(sep=None, maxsplit=-1)  #不带参数默认是以空格为分隔符切片字符串,如果 maxsplit 参数有设置,则仅分隔 maxsplit 个子字符串,返回切片后的子字符串拼接的列表。
splitlines(([keepends]))  #按照 '\n' 分隔,返回一个包含各行作为元素的列表,如果 keepends 参数指定,则返回前 keepends 行。
startswith(prefix[, start[, end]])  #检查字符串是否以 prefix 开头,是则返回 True,否则返回 False。start 和 end 参数可以指定范围检查,可选。
strip([chars])  #删除字符串前边和后边所有的空格,chars 参数可以定制删除的字符,可选。
swapcase()  #翻转字符串中的大小写。
title()  #返回标题化(所有的单词都是以大写开始,其余字母均小写)的字符串。
translate(table)  #根据 table 的规则(可以由 str.maketrans('a', 'b') 定制)转换字符串中的字符。
upper()  #转换字符串中的所有小写字符为大写。
zfill(width)  #返回长度为 width 的字符串,原字符串右对齐,前边用 0 填充。
format('s1', 's2', ...) #以此,以s1/s2代替目标字符串中的“{0},{1}”; “{a} have a {b}.”.format(a="I", b="pen")

转自:http://bbs.fishc.com/thread-38992-1-1.html

Hello World

python如何连接mysql

python3.x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pymysql
 
#简单封装的query方法
def query(sql):
    conn = pymysql.connect(host = 'xx.xx', port=3306, user = 'xx', passwd = "xx", db='xx')
    cur  = conn.cursor()
    cur.execute(sql)
    r    = []
    for row in cur:
        r.append(row)
    cur.close()
    conn.close()
    return r
 
sql  = "select count(id) from tabName"
rd   = query(sql)
print(rd[0])

ok,就是这样
—————–
btw,好久没写新东西,主要是最近一年做的,新东西不多,大部分需要代码实现的东西,都是统计类类的需求。利用手头的这点货,php、nodejs,实现简单的统计分析,有时真的很吃力,效率也低。所以,新的一年,以统计为出口,开一个新技能树:python。这里从最简单的mysql连接开始~~~

其他

39.8

项目里算价钱,发现一个诡异的bug:商品库有个东西,价格是39.80元,到这边库里转化成“分”,成了3979
弱类型语言,有时就是这么无奈,实测发现,对于php,计算:
$p = 39.8
echo (int)$p*100
哈哈,得到的果然是3979
修改$p值、修改乘数为10或1000,都正常,就是39.8和100的组合会出问题
拿同样是弱类型语言的js做了下测试大家来欣赏一下:
39.8*100 = 3979.9999999999995
39.81*100 = 3981
39.800000*100 = 3979.9999999999995
39.8*10 = 398
39.8*100000 = 979999.9999999995
39.8*1000 = 39800
39.9*100 = 3990
计算机里浮点数计算,有时还是很不靠谱的,以后牵扯到这类逻辑的时候,一定要注意了

Hello World

搞定异步编程(二)——使用Promise管理并行程序

也算是延续三年前的一个系列,这里实测一下ES6新出的Promise对nodejs的异步编程有多大改观
还是沿用三年前那篇文章的场景,连续访问三个http接口,然后对三个结果做综合处理
话不多说,上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var _http = require('./lib/http.js');
//对使用Promise做异步操作的封装,需要返回Promise对象,且成功回调resolve,出错回调reject
function testg(url){
    return new Promise((resolve, reject)=>{
        _http.get(url, {}, (retu)=>{
            console.log('Promise, retu, resolve', url);
            resolve(retu);
        }, (er)=>{
            console.log('Promise, er, reject');
            reject(er);
        });
    });
}
Promise.all([
    testg('https://www.baidu.com'), //一次调用三个异步请求
    testg('https://www.qq.com'), 
    testg('https://www.sina.com')
]).then((retu)=>{
    //三个异步请求的成功回调结果,封装在retu数组里
    console.log('Promise.all, retu', retu[0].length, retu[1].length, retu[2].length);
}).catch((er)=>{
    console.log('catch, er');
});

——–
转载请注明出处:http://www.jiangkl.com/2017/05/nodejs_promise

Hello World

来看一下不按常理出牌的js

某公众号上看了一篇“一道面试题引发的对JavaScript类型转换的思考”,里面提到的面试题是这样的:

实现一个函数,满足如下功能:

1
2
3
add(1)(2) // 3  
add(1, 2, 3)(10) // 16  
add(1)(2)(3)(4)(5) // 15

这么一个小功能,实现方法当然见仁见智,这里想说的js的function类型。
我面试前端的时候,经常问这么样一个问题:“jquery里的‘$’是个什么东西?”
对方不明白的话,就直接问“typeof $,会返回什么?”
能回答“function”的,就说明对方对js的数据类型是有了解的
对,$本身是个function,只是上面挂了各种属性和方法
这是第一点

第二点
是js的高阶函数
在学习闭包的时候,会用到高阶函数。所谓高阶函数,说白了就是一个函数,return的还是函数
上面的add(x)(x)(x),所以add肯定是高阶函数的形式

第三点
如果return的是函数,怎么得到相加后的数字
所以函数本身要带上toString(),或者valueOf()

好了,结合上面几点,下面是这个函数的实现,比预想的简单:

1
2
3
4
5
6
7
8
9
10
11
12
function add(){   //第一层add,第一次调用时执行
  var s0 = 0;     //闭包参数,记录累加值
  var f1 = function(){ //内层add,级联调用,实际上是调用的它
    for(var i = 0; i < arguments.length; i++) s0 += arguments[i];
    return f1;
  };
  f1.toString = function(){
    return s0;   //返回累加值
  }
  f1.apply(null, arguments);  //第一次执行时,先add一次
  return f1;
}

————-
转载请注明出处:昆仑的山头

Hello World 软硬兼施

Arduino如何多任务

小搜了一下,Arduino没有简单的多线程/多任务的解决方案
换个方向想想,也对,Arduino本身那点存储空间,就是个微控制器,专心能控制好一个东西就行了,还搞神马多任务
不过,考虑到代码的整齐度,简单的模块划分还是需要的,比如,需要同时分别控制指示灯和舵机时,你不能把所有的代码都放在Loop函数里吧
借鉴以前用js做动画里的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <Servo.h>
Servo duoji1servo;
 
const int pinLed1   = 12;   //连接红色led
const int pinLed2   = 13;   //连接蓝色led
const int pinDuoji  = 9;    //连接舵机控制端口
 
void setup() {
  pinMode(pinLed1, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  duoji1servo.attach(pinDuoji);
}
 
long _ti = 0;  //控制参数累加
void loop() {
  _ti++;
  ledTest(_ti);
  duojiTest(_ti);
  delay(1);    //1毫秒
}
 
//led闪动测试
int ledi = 0;
void ledTest(long ti){
  ledi++;
  if(ledi == 512){
      ledi = 0;
  }
  int n = ledi;
  if(ledi > 255){
    n = 512 - ledi;
  }
  analogWrite(pinLed1, n);   //分别控制LED亮度
  analogWrite(pinLed2, (255 - n));
}
 
//舵机测试
int duojii = 0;
void duojiTest(long ti){
  if(ti % 10 == 0){//调用间隔,10毫秒计算一次
    duojii++;
    if(duojii > 360){
      duojii = 1;
    }
    if(duojii <= 180){  //正传
      duoji1servo.write(duojii);
    }else{              //反转
      duoji1servo.write(360 - duojii);
    }
  }
}
Hello World 软硬兼施

Arduino的指令时间研究

习惯了服务器端编程的思路,玩硬件也想把时间搞得清楚一些
简单研究Arduino一个指令所需的时钟周期,板子是某宝上最常见的Arduino UNO R3,先上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const int LED1  = 13;               //红色LED
const int LED2  = 12;               //蓝色LED
int loopin      = 0;
 
void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}
 
void loop() {
  loopin++;
  if(loopin % 2 == 1){              //点亮红色LED
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, LOW);
    delay(1000);                    //持续1秒
  }else{                            //点亮红色LED
    digitalWrite(LED2, HIGH);
    digitalWrite(LED1, LOW);
    delay(1000);                    //持续1秒
    //******************************关键看这里,这个for循环的时间,约等于delay(1000),此时双色同时亮起
    for(long i = 0; i < 160000; i++){
      digitalWrite(LED1, i % 2 == 0 ? LOW : HIGH);
      digitalWrite(LED2, i % 2 == 1 ? LOW : HIGH);
    }
  }
}

就这么多~~
整体上,用一个超长的for循环模拟出一个1秒的delay,然后观察同时亮起的时间,是否等于单独亮起的时间
实际测算,到16万时,同时亮起的时间,基本等于另外两个亮起的时间
(这里只是估算,有时间的话,也可以算的更精确一点:对着计数器数秒,看闪动的次数是否和秒数一直,不一致的话,就调整这个i得最大值)
也就是说,这里的一个for循环,Arduino的大约需要 1/160 毫秒,或者说0.16M,简答分析这个for循环做了哪些事情
1. i+1,= i, i与最大值比较,大约3次
2. i%2,== 0 ?, 高电平或低电平输出,大约3次
3. 与上一步基本一致
加起来大约10个指令?
Arduino UNO R3的晶振频率是16M,也就是说,大约,晶振的10个周期,可以执行一个程序指令
另一个方面,UNO的处理器核心是ATmega328,8位处理器,i是long型32位,上面的每次运算,cpu至少要算四次(具体8位处理器怎么捣腾相加两个32位的数,记不清了),按这种方式算的话,其实也差不多
—-over
转载请注明出处: 昆仑的山头