Hack a New Year

Hack a New Year

新年的 Hackathon 刚刚结束,和上次部门的 Hackathon 完全是两种不同的感觉,有些东西有必要拿出来说说~

 

我们做了什么?

我们的项目叫“闪验”,提供一种快速验证团购券的方案。

原理很简单,和 Bump 类似,用户勾选需要验证的团购券,然后用户和商户碰一下,就可以进行验券了。

从产品的角度来讲,它有很多问题,但是我们为什么做这个?

引用我们这次活动的一句话: just for fun!

实现原理也很简单:

两台设备碰一下,把自己的地理位置和时间传给服务器,服务器会接收到许许多多 Bump 请求,然后根据距离和时间算出可能在碰撞的两个人。相互确认后就匹配成功了。

2012年总结

2012年过去了,最近的一个月内,导师和部门老大一共找我谈话了三次,和我一起对上个季度和上一年作出了总结。

但谈话式的总结总会思路短路,不够全面。或许在总结的时候,文字还是最好的方式,因为能有足够的时间思考。

明年提前把这个总结写好,这样谈话的时候就会有很多可以说得了吧?

 

阅读

2012年,线上阅读还是和以前差不多,Google Reader 订阅,订阅的数量也没有明显的变化,最大的变化就是加入了 iteye,因为最近一直在学习 Java 嘛。

而纸质书籍的阅读数量真的要反思一下了。去年得益于 kindle 的新鲜感,今年没了新鲜感,阅读量明显下降了。

总体书目如下:

  • 《Programming Entity Framework Code First》
  • 《Java编程思想》
  • 《The Art of Readable Code》
  • 《轻量级Java EE企业应用实战》
  • 《黑客与画家》(在读)
  • 《数据结构(Java语言实现)》(在读)

看书的第一步是选书,前几年我一直在看深入 .Net 的书,看多了就发现很多知识点是重复的,它们并不能给我带来更多的东西了,性价比越来越低了。

如何 Mock 非虚方法和密封类?

问题

很常见的问题,没有接口,那如何 Mock 非虚方法和密封类

我在上一篇文章(单元测试有感)中介绍了单元测试的原则,也提到了一些技巧,但是代码是以前写的,总会有很多不能克服的地方,还有也不可能把所有的方法改成 vitrual,或者所有的类都有接口。

 

寻找

一开始搜索:mock non-virtual ,找到了一篇文章:传送门

文中提到了一个神器:Typemock,貌似它可以实现,但是它是收费的…

大致看了看它的原理,和 PostSharp (PostSharp是用来做 AOP 的)差不多,都是会去修改编译完成的 dll 文件,简单粗暴!

虽然粗暴,但貌似的确是一个不错的方法,别的项目正常编译,Test 项目中为了测试,把所有的方法加上 Virtual 关键字,这样不就行了吗?

思路是清晰了,可惜工具都是收费了,直到看到了老赵的博客

上面的链接是老赵的原文,可惜他好像误操作,被另一篇文章替换了。

下面的链接是别人转载的,可以看,虽然代码缩进都不对。

另外,老赵的文章提供了一个很好的思路,但是没有后续具体的操作细节,我也摸索了很久。所以,下面我会给大家介绍一下完整的、具体的实现步骤。

单元测试有感

你为什么不写单元测试?

前一段时间,部门有两位同事给大家进行了 Unit Test 的分享。

其中一位的主题是:Mock 技术

主要介绍了如何用 Mock 技术辅助单元测试。

另一位的主题是:单元测试之分割复杂业务逻辑

主要是以一个案例,介绍了复杂的业务逻辑应该怎么进行单元测试。

利用 WCF 调试模式寻找内部错误

诡异的BUG

今天同事遇到了一个诡异的 WCF 问题,我自己也遇到过,觉得很有参考意义,拿来分享一下!

现象是 WCF 调用后报错,但是没有详细的错误信息,错误内容是:连接中断(偶尔也会出现别的内容)。

最诡异的是,本地起服务,断点调试 catch 不到任何异常!

 

自己上次也遇到了同样的问题,于是帮忙解决,WCF 的很多内部错误是不会抛出来的,所以只能通过开启 WCF 调试模式来解决。

java 访问 Salesforce API

.net to java

最近部门准备转 java 了,大家都积极性很高,看上去 .net 还是不受待见啊~

言归正传,之前和 salesforce 的 API 交互都是用 .net 做的, WebService,没什么难度,网上千篇一律,都是标准的方法。

但是 java 就不一样了,各种方法,各种问题…

最后终于捣鼓出了一个可用的版本。

 

 

网页动态查询条件的实现

场景

最近有一个需求,会在 mongodb 中插入各种类型的数据,算是记录业务日志的数据库吧。

因为业务对象类型都不同,所以插入的数据格式也完全不同。

除此之外,还需要提供一个查询界面,可以搜索数据。

插入数据没任何问题,但是查询就…

Linq To Salesforce Toolkit

简介

上篇文章中(Linq To Salesforce),我只要介绍了 Linq To Salesforce 的基本原理。

但很多人更关心的是如何使用,后来我又写了一个 Tooltik 项目,不仅包括了查询,还包括了一些基本的增删改的封装,可以帮助开发者快速开发和 Salesforce API 交互的应用程序,算是开袋即食吧!

 

使用指引

下载项目

首先到 Github 上下载 Linq To Salesforce 项目。

Linq To Salesforce

锤子与钉子

手中有锤子,眼前的一切就都变成钉子了…

手上有 LINQ,就想把一切都转换成 LINQ。Salesforce API 也不例外。

Salesforce 的 API 调用方法还算简单,可以自动生成实体,但是有如下缺点:

  1. 查询语句还是原始的 SOQL ,类似于 SQL
  2. 每次查询最多 200 个对象,如果超过了,还需要用 QueryMore 方法继续查询

总之,我想把 Salesforce API 查询语句转换为 LINQ 的查询形式,是否可行?

Entity Framework Code First 配置介绍:数据库

目录

简介

配置实体的属性

配置实体间的引用关系

配置数据库映射

 

映射表名和组织架构名

//Data Annotations
[Table("PersonPhotos")]
public class PersonPhoto

[Table("Locations", Schema="dbo")]
public class Destination

//Fluent API
modelBuilder.Entity<Destination>().ToTable("Locations", "dbo");

Entity Framework Code First 配置介绍:引用关系

目录

简介

配置实体的属性

配置实体间的引用关系

配置数据库映射

 

引用关系

Entity Framework 中配置了对象之间的引用关系后,在查询数据的时候会非常方便。

但是很多老系统中都是没有显示指定外键的,大多是靠在子对象中加一个主对象的 ID 来解决问题。

这时候如果不配置一下的话,是根本无法实现两个对象之间的引用关系的。因为 Entity Framework 并不知道那一列是用来确定引用关系的。

所以,这章将会介绍它默认的规则,也会介绍如何自由地配置引用关系。

Entity Framework Code First 配置介绍:属性

目录

[简介][1]

[配置实体的属性][2]

[配置实体间的引用关系][3]

[配置数据库映射][4]

 

配置方法介绍

在 Code First 之前,其实大家都知道一种配置方法:

class AnimalType
{
  public int Id { get; set; }
  [Required]
  public string TypeName { get; set; }
}

没错,这就是 Code First 的配置方法之一:Data Annotations

直译叫做数据批注,原理就是在对应的字段上加上 System.ComponentModel.DataAnnotations 命名空间下的一些 Attribute,就可以实现各种配置了。

这种作法在 Model First 和 Database First 的时代就有了,也可以同时被用来做 MVC 的数据验证。

Entity Framework Code First 配置介绍

目录

简介

配置实体的属性

配置实体间的引用关系

配置数据库映射

 

简介

自从 Code First 推出后,大家慢慢地把开发模式转换了过来,也从中发现了很多优点。

但是,公司最近的一个需求一直无法被满足。(因为之前不知道 Code First 那么强大)

 

目前的代码中,有实体,有数据库,实体间有关联,但是数据库中无显示外键。

大家第一眼看到有数据库的时候,肯定会想到用 Database First。但是,生成的对象之间并没有引用关系,因为没有显示外键,如果没有引用关系,那又何必用 ORM 呢?

工具思维

Facebook 的工具思维

如果说软件工程师是为用户服务,那是不是会有一类人为同行服务?

架构师算一类,为开发工程师服务,还有呢?

 

上个月来了一位前 Facebook 的雇员给我们讲座,聊到了他的部门,说他们部门经过很好的发展后,人数减少了。

我听了以后总感觉这句话前后矛盾,“很好的发展” & “人数减少了”,在国内,我是在无法把这两个现象联系在一起。

后来在提问环节,也有人提出了同样的问题。

于是,他便引出了 Facebook 的工具思维。

迭代器的妙用之 Salesforce API

上期回顾

在前两篇文章中(延迟加载与延迟求值查询迭代器的妙用),介绍了很多延迟加载、延迟求值查询和迭代器的知识。

本文也是利用了相关技术,巧妙了实现了一个功能。

 

Salesforce API 的调用

最近会进行 Salesforce 开发,过程中需要在 C# 中调用 Salesforce 提供的 API。

Salesforce API 请求数据库的时候和执行 SQL 语句差不多,但是你没办法一下子读取到所有数据!

如果想要得到一张表中的所有数据,你只能这么读:

var qResult = connection.query("SELECT FirstName, LastName FROM Contact");
var qResult2 = connection.queryMore(qResult.getQueryLocator());
var qResult3 = connection.queryMore(qResult2.getQueryLocator());

这是最粗暴的读取方式,每次读取只能得到200条数据,如果想要更多的数据,必须利用上次返回结果里的一串字符串,然后就可以得到后面一批数据了。

迭代器的妙用

延迟查询与延迟求值查询

在我的上一篇文章中,给大家介绍了延迟查询与延迟求值查询的实现原理和注意事项。

前几天在项目开发的时候,发现了一个非常好的应用场景,可以利用延迟查询与延迟求值查询达到非常棒的结果!

 

业务场景与常规解决办法

大家平时是否经常有这样的一个场景?

场景:数据库一个表中有十万、百万条数据,有这么一个作业偏偏要把它们都独取出来,然后一条条地进行处理。(单条数据之间没有依赖关系)

处理:一下子读出来?不可能吧… 那只能利用类似分页的方法,一部分一部分地取了。

Web Worker 为何不能直接调用函数?

Web Worker 的奇怪用法

当我第一次看到 HTML5 中 Web Worker 的用法时,非常地疑惑:

var worker = new Worker('worker.js');

既然是新起一个线程,为什么要调用外部的 js 文件,而不是直接传入一个函数呢?

var worker = new Worker(function(){
    //do something
});

因为调用外部 js 会非常的麻烦。

延迟加载与延迟求值查询

对延迟加载的片面认识

很多人对延迟加载的初步认识就是,在使用 LINQ for Entity 的时候,查询语句不会立即执行查询,只有在使用 foreach 或者 ToList() 等方法的时候,才会去查询数据库。

那如果我用的不是 LINQ for IQueryable,而是 LINQ for IEnumerable(前者往往是查询远程数据的,后者查询的都是内存数据),例如自己的一些数据库访问层,返回的数据就是 List,内存已经在数据中了,是不是就没有延迟加载了呢?

非也!

 

延迟加载的实现原理

LINQ for IQueryable 查询的往往是远程数据的,当你调用 Where(),Single() 等方法的时候,并没有去查询数据库,而是保存为表达式树了。

只有当你使用 foreach 或者 ToList() 等方法的时候,才会把之间的所有表达式转换成 SQL 或其他查询方法,然后和远程数据交互。

具体原理可以查看下来文章:http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx

请注意绑定了事件的局部对象

GeoCoordinateWatcher 的诡异问题

前两天在做 WP7 开发,需要用到 GPS 定位,这里会用到一个 GeoCoordinateWatcher 类。

写了一段代码后发现自己写错了,但是它竟然可以运行!再仔细一推敲,发现了很多坑。

 

我在 stackoverflow 上也报告了这个问题:传送门

问题代码如下:

private void button1_Click(object sender, RoutedEventArgs e)
{
    GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
    watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
    watcher.Start();
}

void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
    Debug.WriteLine(e.Position.Timestamp.ToString());
}

上述代码中,理论上 watcher 实例在按钮点击事件后应该会被销毁,所以下面的 PositionChanged 事件应该也不会被触发。

一开始这么写,是我的错误,但是看到这个问题后,我才发现我的程序是可以正常运作的…

调试后才发现,这个对象永远不会被销毁,每按一次就会多一个实例,并且你找不到它!

GPS 位置每改变一次,所有的实例就会输出调试信息。

在 WP7 中同步多个 Google 日历

WP7 上同步 Google 服务

Android 上的 Google 服务没的话说,好用的不得了。到了 WP7 平台上,只能用 Mail For Exchange 来同步 Google 服务了。

基本上体验也很好,除了不能支持多日历!注意,这里的多日历指的是同一个 Google Account 下的多个日历,而不是不支持多个 Google Account。

Google Calendar 上新建和引用的其他日历没办法在 WP7 上同步。