抠腚爱揉曼

Coding Iron Man

成本一块钱修复电容屏抽风

前几天在等公交的时候突然我的Hero屏幕抽风了……具体表现就是有时候乱飘,单点变多点,然后手指离开几公分也有反映。总之是各种不能用了……本来打算去换个屏或者卖了换成MS的……

不过今天无意中看到可以用电击法治疗之……于是就试了下,所用工具就是一次性火机上的点火器。拆了一个火机后,对着屏幕电了十多二十下,亮屏的时候,不亮的时候,拿在手上放在地上各种电……总之电完之后直到现在都好好的,貌似确实有效果~所以说电电更健康啊~

想查查原理,查了半天还是不知道具体为什么,哪位路过的同学学电工啥的可以解答一下~

做了件有趣的事情

有个好友在国内某网站当编辑,他的悲催主管要求他们每一个人在站内要有3个拥有500好友的马甲用来干各种事情……好友便求助于我帮忙点掉一些加好友申请,但本着技术是第一生产力的原则,于是我尝试着分析了下某网站申请加好友的流程并调戏了一把。以前也没有尝试过做类似的事情,所以在这里随便记录一下,具体内容就不说了……不然应该会被看出来是哪个网站……

申请加好友的操作其实很简单,输入一段话和验证码按确定就好了。要模拟这个操作所需要解决的几个问题就是:

  1. 获取到请求地址和参数
  2. 附带用户登录信息发送请求
  3. 绕过验证码

第一点,通过chrome开发者工具或者firebug都可以,抓取浏览器和服务器之间的请求和响应就可以获取到请求地址和参数。稍微分析下参数之后就找出了需要的信息……
第二点,其实只需要在请求的时候把cookie信息一并丢过去就好了,sessionId也是放在cookie里的。通过在chrome的js console里输入document.cookie获取到cookie内容……
第三点,好吧这个其实应该是最麻烦的部分……我从来没关注过这方面的信息,验证码原理什么的OCR什么的完全不懂啊。但是在分析了某网站的验证码机制后发现相当悲催……它在请求验证码的时候把验证码图片以及一个和图片关联的惟一ID传送给浏览器form,然后通过用户输入的验证码和那个惟一ID是否匹配来验证(以上都是我猜的~)。杯具的地方在于这个验证码惟一ID在被验证一次后并没有即时失效,在相当相当相当长的一段时间内,通过那个惟一ID和验证码发起请求都有效(以上也是我猜的~都不知道是不是有失效策略……),于是于是于是~万事俱备,只欠编码~

首先我手动操作发了一个加好友申请,抓取到请求和响应后把请求地址,用户id,验证码以及验证码惟一ID分离出来,把好友给我的活跃用户表格正则表达式提取为一堆数字ID初始化为一个集合。接着要做的事就是拼请求,开连接,丢cookie信息,发起请求获取响应,然后要是乐意的话分析下response的信息,对成功失败以及重复发送申请进行统计……在简单实验了几次成功之后,我就很欢乐的给他的三个用户总过发了3000多个好友申请……就不知道通过率有多少了……

BTW: 程序是用Scala写的,其实也没用什么Scala的特性,主要是拼请求地址之类有一大堆乱七八糟符号的字符串的时候用原始字符串各种好用不用转义……

无聊转个笑话……[The Daily WTF]Got Time?

Peter 是一家公司的新程序员,Noah 的继任。有一天他接到这样一封信:

Subject: 请再增加些天数
Content: Peter 童鞋你好,能不能给我们的交易报表再加点天数?我不知道是不是该这么讲,以前 Noah 在的时候,每次要增加天数就要改程序的。

于是我们的 Peter 童鞋跑去翻历史遗留代码,然后他明白了为啥每次都得通过改程序才能增加天数:
Read the full article »

关于MySQL事务隔离级别

好吧,今天查一个问题查了一整天……最后发现其实很简单……不过因为过程很艰辛所以不得不记录一下……

问题场景很简单。有两个互相嵌套的事务1和2,2嵌套在1中。事务2插入了一条数据并提交到数据库,事务1尝试获取事务2插入的数据,然后很杯具的失败了~

相信绝大多数人看到这个场景再结合此文标题就会各种知道然后BS我居然要花掉一整天来查这个问题……是的,现在我也是各种知道但是杯具的是当时我各种不知道……

事情的起因是同事写了一个简单注解驱动的多数据源事务管理,于是就拿过来用,然后在写某单元测试的时候发现了这个问题。当然,我第一反应是……这事务管理器靠谱么……于是开始埋头看他的代码(从这里开始我方向已经跑偏了)。看完他的没看爽,又跑去看了一圈ibatis的代码。看完还是嘛原因没找出来……于是去翻mysql日志……翻完更是祭出了端口监听工具抓包分析……

经过上述种种折腾之后……好吧……它不就是因为MySQL的InnoDB默认的数据隔离级别是Repeatable Read而Oracle之流的大多数数据库都是Read Committed么……我只不过是因为被既然都已经提交到数据库了你凭什么不让我读类似这样的惯性思维所影响了嘛(特别是在询问一个MySQL DBA和一个Oracle DBA都没有给我什么建设性建议的情况下……)~

于是在我很用力的敲下了下面的命令后,世界变得更美好了……

mysql> set global transaction isolation level read committed

Scala笔记2

最近几天杂事很多,导致那本薄薄的Scala至今未看完……今天先来接一下Scala笔记2

  • Scala的访问控制机制和Java有别。有些许的概念不同而且能够做到更加细粒度的控制。Scala默认访问修饰为public,Java则是微妙的default。Scala中的protected则比Java更小气,它只对自己和派生类可见,同包下的其它类无法访问,而且类也只能访问自己的基类中的protected成员,无法访问继承同样基类的其余派生类中的基类protected成员。Scala对细粒度访问控制体现在private和protected修饰可以通过方括号指定额外的报名或类名来赋权。
  • Read the full article »

SFINAE

什么是SFINAE

在C++中有很多的编程技巧(Trick),SFINAE就是其中一种,他的全义可以翻译为“匹配失败并不是一个错误(Substitution failure is not an error)”。简单来说他就是专门利用编译器匹配失败的一种技巧。

案例

比如我们想实现一个通用的函数叫AnyToString,他可以实现任意类型的数据转成字符串:

template<typename ValueType>
char* AnyToString(const ValueType& value);

我们更希望这个函数能检查ValueType类型自己有没有ToString方法,如果有就直接调用,没有的话就采取通用的处理方案。但是C++没有反射机制,不能像C#那样通过TypeInfo来检查,更没有像Java那样纯粹的OOP,从最基类就定义了ToString方法,下面的子类只用负责重载。
所以我们希望能有一种方法能让C++也能检查某个类型是否定义了某个成员函数,这就可以用到SFINAE。
Read the full article »

Eclipse仿Netbeans配色方案

今天把Intellij IDEA、Netbeans的最新版都搞了下来玩了下(主要是想试下它们分别的Scala插件),不过最后还是因为习惯问题屈服与Eclipse的淫威之下……好吧其实大学里的时候我明明还是Netbeans控的,而且感觉Netbeans6.5之后的UI和配色都很符合我的口味,而且Eclipse那像干了的血一样的keyword颜色我也实在审美疲劳了,于是我决定把Netbeans的配色偷过来。

Netbeans的配色其实很简单,黑灰蓝绿棕就这几种颜色,对照着改下还是相当快的,先上截图。

打开Eclipse->Window->Preferences->Java->Editor->Syntax Coloring(当然也可以在Perferences的filter里直接输入Syntax定位)

Read the full article »

Scala笔记1

最近在看Scala,把笔记贴过来存档。

  • Scala基于JVM,通过scalac编译成JVM字节码。不同于Groovy(同样是跑在JVM上),Scala是静态类型的,因此可以支持泛型和多态等特性。Scala完全使用自己的规则创建,因此相对于Groovy来说学习成本更高(Groovy其实就是Java的强化?简化?版)。而且因为基于JVM,因此可以很好的和现有Java项目整合,在Scala中可以直接使用Java现成的无数类库。
  • Scala通过var和val定义变量。var定义可变量,val定义不可变量,类似Java中的final,一旦初始化赋值后就无法改变。Scala鼓励尽可能的使用val让类和方法获取原生的线程安全性,同时通过val和闭包(方法对象)的使用来支持函数式编程。当然Scala也可以使用Java抠腚们熟悉的命令式来书写。
  • 既然Scala支持FP,因此它确实支持尾递归优化。只不过受制于JVM,只能做到简单的尾递归优化,在比较复杂的情况下无法确实优化。下面的代码清单是一个尾递归的例子,递归了一亿次,一切正常。
    object Main {
      def main(args: Array[String]): Unit = {
        println(doSum(100000000L, 0))
      }
    
      def doSum(n: Long, sum: Long): Long = {
        if (n == 0L) {
          sum
        } else {
          doSum(n - 1, sum + n)
        }
      }
    }
    

    Read the full article »

发发牢骚吐吐槽

BLOG开了有段时间了,基本上发的文分类都是抠腚。不过既然扯淡这个分类存在,偶尔还是要扯扯的。虽然就吐槽能力来说,我只能算是见习未转职,不像吐槽神F这般张口就来。

总之就是不乐意于结果导向对评价的权重过高。所谓结果结果,往往都是业务的成果更容易体现,也更容易如某篇文所说的那样写出各种report来(毕竟某公司还是严重的业务导向)。虽说做好业务才能产生更好的业绩,虽说技术就是为业务服务的,但对于结果和业务的偏向就让希望好好做技术的人境况不尴不尬。之前离开的一个朋友多半也是感受不到技术的氛围,每天都在做些无爱的事情才跑路的……

偶尔被教导,要站在业务的角度看待技术。只不过对于我等踏出校门不过一年多的小兵,并不指望也不该被别人指望站到多高的角度去统筹业务和技术。我只想给自己多积攒些资本好安身立命,既然不乐意以后当个PD什么的,也不想随波逐流,就只得选择去做技术。然后越做越迷茫,除了每每学到些东西能够让自己释怀之外,更多的时候只感觉到自己的边缘地位和选择带来的差距。

绩效考核什么的也都是虚的,如何好看,最后也是别人一念之间。付出到回报的转化率无法自己把握就算了,然而连个让我懂的起的衡量标准都不知道的感觉却每每只能让我低头,然后看看自己的脚……

我浮躁了

N!

template<int N>
struct Factorial
{
    static const int Result = N * Factorial<N - 1>::Result;
};

template<>
struct Factorial<0>
{
    static const int Result = 1;
};