Thrift Python版本中文传输问题和解决

前段时间项目内用到了Thrift封装C/S交换数据,这东西好处自然是每个平台都有相应的框架实现,客户端不用关心具体逻辑,有了.thrift定义后直接调接口(作为软饭,个人觉得用起来没有WCF舒服,这么好的东西微软不下力气推广啊)。

Java和C++写的Server都顺利调试通过,卡在Python的一个实现出现的问题上了。好吧,先不要问为什么一定要用Python做Server,这涉及到项目内的一些糟事,略过。具体问题表现是:自己定义的object,两个string field只有一个可以成功赋值。如果给其中一个赋值后,另外一个一定是空字符串。

尝试过各种情况,发现中文出现的时候复现。在Python中提到中文问题,那么自然先想到str、unicode这两个类型在搞鬼。算幸运的是,在盲目调试了一天之后,找到了好用的解决方案。文中的解决方法好用,但需要修改thrift本身代码。对于部署在实际服务器上的服务来说,可能不太适用,所以可以这样做:

class MyTBinaryProtocol(TBinaryProtocol.TBinaryProtocol):
    def __init__(self, trans, strictRead=False, strictWrite=True):
        TBinaryProtocol.TBinaryProtocol.__init__(self, trans, strictRead, strictWrite)

    def writeString(self, str):
        if type(str) is unicode:
            str = str.encode('utf-8')
        self.writeI32(len(str))
        self.trans.write(str)

class MyTBinaryProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory):
    def __init__(self, strictRead=False, strictWrite=True):
        TBinaryProtocol.TBinaryProtocolFactory.__init__(self, strictRead, strictWrite)

    def getProtocol(self, trans):
        prot = MyTBinaryProtocol(trans, self.strictRead, self.strictWrite)
        return prot

然后启动Server的部分修改为:

pfactory = MyTBinaryProtocolFactory()

旅游和出差时候的锻炼

最近爱燃烧连发两篇和出差锻炼相关的文章《谈出差与跑步》和《出差如何选择跑步地点?》。虽然我基本没有出差经验,但想结合自己之前旅游之中锻炼的经历谈谈相关话题。

先说跑步吧。

去日本和越南旅游的时候,我都带上了跑鞋——一次是为了备战北马保持状态,一次纯粹是形成了习惯。对于行李之中安排跑步装备的问题,可不仅仅是再塞一双跑鞋那么简单:你得考虑跑步时候不能穿着纯棉衣服吧?衣服又分上衣和裤子。护具是否需要?跑鞋配套的袜子呢?跑表要带吗?零零碎碎加在一起也会占不少地方。所以我倾向于选择vibram或者其他五趾鞋,衣服尽量选择轻便、折叠后不太占地方的。简而言之就是锻炼毕竟还是旅游附属品,别搞得本末倒置。

跑步的路线选择则要根据目的地而定。如果是大城市,那么早起出来可能已经会有很多人在外面活动,跑步时候和行人、车辆的互相影响不能忽视。在河内跑步算个艰难的决定:平时走路时候摩托车已经很凶残,你要和他们抢道么?所以当时我只是把在老城区的路线当成热身,慢慢挪到还剑湖附近,然后开始绕着湖放心地飞奔。而类似渡假类型的目的地就没那么大问题,有沙滩的话再好不过,连鞋都可以不用了。

六点半的京都,人车都很少。但这个时候在东京池袋已经热闹起来。

至于时间,推荐还是早上。出去旅游了都,对自己好点儿吧,大晚上的先不说安全问题,无论是暴走一天还是吃喝玩乐,总要给身体足够休息才行。一般来说,有跑步习惯的人多半适应早起,至少我当时都是五点半到六点起来,跑个四十分钟,加上洗澡也不过一小时——等我收拾完毕,旅伴还没起呢。

另外一个选择早上的因素是空气。日本这种常年pm2.5不超过50的还好,碰上空气甚至还不如北京的地方,还是老老实实在宾馆里HIIT吧,做两套Insanity都比加号。

然后是其他锻炼。

HIIT好说,各种动作基本都是徒手,注意别声音太大让楼下找上来就行。

一般来说,商务型旅店就别想着有健身房了。甚至一些高档的酒店和度假村的“健身房”,也只是几台跑步机+配不成套的哑铃而已。所以这个时候需要一些无器械训练。相关的训练视频、书籍和文章太多,比如P90X、Tapout、Insanity,扔到移动设备里面,以备不时之需;《无器械健身》《城市就是健身房》《囚徒健身》等等,甚至连我这种二把刀都写过几篇相关的blog,大家可以看过后随手记下自己喜欢的动作。

不过有健身房的话,还是首推选择它。肌肉这玩意儿,不维持的话掉得太快。虽然有之前锻炼底子恢复起来也不慢,但毕竟要经过反复期。

总之,祝大家锻炼愉快,就算是在出差和旅行中。

C++的类型转换重载(type casting overriding)

最近项目里面用了mysqlpp,注意到query对象在获取查询结果时候的store()方法返回了StoreQueryResult,虽然它不是指针但是可以这样用:

if (StoreQueryResult queryResult = query.store()) {...

一开始以为写错了——而且就算是运算符重载,不也只能用“!”么。查了一下相关的文档,原来这玩意是类型转换重载。

operator关键字后面的类型任意,甚至可以是void*,显而易见在这种情况下需要这么做:

private:
    bool _isValid;
public:
    operator void*() const { return _isValid ? this : nullptr; }

这样一来也可以达到上面type casting的效果。

但这几种方式或多或少都存在问题,所以The Safe Bool Idiom介绍了另外一种方式:嵌套类/安全类型转换。可以看到mysqlpp用的也是这种方式。文章最后还利用模板创建了支持多类型的版本。

这个故事告诉我们,C++的细节太多了。

p.s:想到了C#的nullable type。

在C# 2.0之前,类似int这种值类型是不能和null比较的,所以总需要提供一个getter或者其他什么method进行bool判断。有了nullable type后,就可以用int? x = 0; 这样的语法创建可和null比较的值类型对象。

那个问号其实只是语法糖,真正实现功能的是System.Nullable。嗯,到了这里就和之前看到的reusable version of type casting很像了吧。用ILSpy或者其他什么工具打开mscorlib.dll,可以看到Nullable在实现上是这样(省略一些细节):

namespace System
{
	[TypeDependency("System.Collections.Generic.NullableComparer`1"), TypeDependency("System.Collections.Generic.NullableEqualityComparer`1")]
	[Serializable]
	public struct Nullable where T : struct
	{
		private bool hasValue;
		internal T value;
		public T Value
		{
			[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
			get
			{
				if (!this.HasValue)
				{
					ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
				}
				return this.value;
			}
		}
		[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
		public Nullable(T value)
		{
			this.value = value;
			this.hasValue = true;
		}
		[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
		public static implicit operator T?(T value)
		{
			return new T?(value);
		}
		public static explicit operator T(T? value)
		{
			return value.Value;
		}
	}
}

说白了还是privaate flag + getter + conversion method。最后两个方法,就是C#版本的type casting overriding。

一些新的(接近)HIIT训练

不喜欢老用同一套训练,所以经常换姿势。HIIT的特点就是维持短时间高心率 + 间歇。一般我都会用20分钟左右做完的训练方法,每组动作持续2~3分钟,组间休息30s~1分钟。同时希望可以兼顾一些力量练习。超过20分钟的HIIT……还真没敢尝试。

1. Burpee + 深蹲

很简单,从1个Burpee + 9个深蹲、2个 + 8个开始,一直做到9个 + 1个,算作一组。一般是三组。

Burpee可以选择普通的后蹬腿方式,也可以采用侧式的。我一般是后蹬腿、俯卧撑然后起来纵跳(牛逼的可以尝试Power Jump)。深蹲采用Indian Squat。

每组约5分钟,中间休息30s~60s。

2. Burpee + 高抬腿

Burpee × 15 + 原地高抬腿冲刺 × 50,算作一组,8组。组间休息15s~30s。现在我一般是1组、2组连续 × 3、1组这样做。

高抬腿和Power Jump真是虐人/自虐的好选择。

3. 侧腹强化

V字俯卧撑 × 15、原地熊步 × 15、直臂Plank膝盖屈伸 × 15、侧腹俯卧撑 × 15、屈臂膝盖屈伸 × 15、Ski Abs × 10、俯身支撑直腿侧摆 × 10。然后(高抬腿 × 10 、原地冲刺 × 20、俯身支撑冲刺 × 8) × 3。

这样是一组,3组起。

这套动作是各种其他健身产品里面扒下来和侧腹有关的动作组合而成。每个动作最多15个,每组时间撑死了5到6分钟。但是做完后侧腹和肩几乎要断裂,因为做一遍你就会发现基本所有动作都是胳膊支撑完成,而且侧腹接受持续刺激。有心练出马甲线的妹子和人鱼线的汉子可以试试然后反馈给我:D。

4. 间歇跑

冲刺200米 + 中速200米算作一组,10组。大概是最简单的练习,跑步机和路跑两相宜,效果却不一般。不过一定要注意冲刺阶段的姿势——没错,心肺其实只会痛苦而已,如果在高强度运动下不注意跑步姿势,膝盖和腿部肌肉会承受过多压力。我之前因为练这个(跑High了做了20组)导致腓肠肌疼了半个月。

5. 胸外侧强化。

Burpee又来了!既然要强化,那就要用Tapout XT里面的版本:摸脚尖,然后腾空变成俯卧撑姿势,Knee Strike两次后直接跳起来。这个 × 15。

侧移俯卧撑 × 15。Power Jump × 20,只是为了休息一下胸肌。最后再来腾空俯卧撑 × 15。

这个的话,做个一两组就行了,对自己别太过分。

春节越南行小结 六 河内-回程-总结

从芽庄赶回来,基本上能吃的馆子都休假了。于是选择路边摊。

6_hanoi_dinner

 

开拔,回河内。第二天中午的飞机,所以实际上在越南没什么芽庄机场很小,设施也比较简陋。

6_nhatrang_airport

 

汤头有些臭——类似于螺丝粉那种感觉。但面条和汤本身吃起来却挺香。卫生就不要在意了,至少我们吃完没有出现什么异常:)。

6_hanoi_dinner2

 

之前还担心河内机场没有购物的地方,没想到出关后挑花了眼。店大概有十五六家,零食、巧克力、咖啡、烟和纪念品都有。推荐买6号登机口左边第二家的漆碗,非常漂亮,小的6刀,大的10刀,送人自用两相宜。

6_hanoi_airport

 

回程飞机的位置还不错。

6_hanoi_airplane

 

吃的东西也很满意,比去程好多了。尤其是多给了水果。牛肉面条基本吃完。

6_hanoi_airplane2

 

鸡肉饭也还成。

6_hanoi_airplane3

 

所有战利品,唯一感觉就是买少了!尤其是Craft Link和河内其他小店。河内机场的松鼠咖啡盒装版和袋装咖啡豆都推荐,两者在很多店铺都卖,价格从5.5~7刀不等。

6_beijing_bought

 

花了最后90K买的方便Pho。面条还不错啦,但汤料完全就是味精嘛。

6_beijing_pho

6_beijing_pho2

总结

其实可总结的没有多少了,基本所有心得信息都在第一篇里面提到。那么就说说目的地选择、礼物和土特产相关吧。

买特产

  • 如之前多次所说,河内一些很不错的小店值得逛。买的时候下狠手,看上就不要犹豫!手工店的东西基本都是物超所值,买了一堆可能才几百RMB。相信我,不这样的话,回来后肯定后悔。除了丝巾之外,漆器和牛角工艺品也值得一看。
  • 除了手工艺品外,越南吃的也值得一带,国内能轻松买到而且价格和越南买持平甚至更便宜的——比如G7咖啡、排糖和果干——就不要考虑买了。个人推荐其他牌子的咖啡(比如松鼠Con Soc)、烟、腰果(大概¥25-30/斤)和其他干果、春卷皮等等。
  • T恤,路边摊图案好玩、合心意的就拿下,一件大概2刀也就是12人民币左右,做工就不要在意了。越南还有一些独立品牌做T恤很漂亮,比如还剑湖北面PHO Hang Bac南面有家连锁的(抱歉忘了名字),在芽庄也有分店,价格自然也会贵,质量绝对OK,大约¥100一件。其他的衣服,比如越南传统服装,除非被人特别委托或自己很喜欢,还是不要考虑,买回来根本穿不出去。

目的地选择

  • 如第一篇提到,如果希望节约成本,那么就胡志明市进出,然后美奈芽庄可以坐大巴;节约时间可以选择飞机来往胡志明和芽庄(不到1个小时)。
  • 喜欢暴走和人文景观的,选胡志明市和河内比较好;想看自然景观和渡假的话,推荐美奈。芽庄属于两者都有的类型,偏重于大海沙滩。
  • 其他的城市暂时无法给出意见,等去过再说:)