• Home

MBP101 Yosemite升级 SSD

本人机子为MacBook Pro (13-inch, Mid 2012),系统已经升级为OS X 10.10.1 Yosemite;光驱位和硬盘位置的SATA均为 SATA3,但硬盘仅支持 SATA2,所以协商以 SATA2速度运行。
mac check sata 3
一番 V2EX 和 Google 发现 Yosemite 引入一个叫 kext signing 的东西,默认开启,开启后会禁止使用未经苹果认证授权的第三方硬件,也会影响 TRIM 的使用。
TRIM 可以对 SSD 进行增强,比如稍微提高读写速度、使用寿命等。在这篇文章FAQ and support for using Trim Enabler in OS X Yosemite里提到了。

在旧版本系统里通常是使用 Trim Enabler 来开启Trim 的,免去敲命令行的烦恼。现在多了 kext signing,就必须先关闭 kext signing。在 Trim Enabler 3.3 以上版本已经集成了 kext signing 开关闭的功能。我用的是4.0.4。trim enabler turn off kext signing

按流程走,重启后重新打开 Trim Enabler,再开启 Trim 就可以了。

最好拿个足够大的移动硬盘做一个 Time Machine 备份,以免玩大了搞坏原硬盘丢了数据。

准备材料:
1、SSD,我采用的是 SamSung SSD 840 EVO,目前价格约850RMB;
2、光驱硬盘托架,我采用的是Nimitz OptiBay-3,购买时要注意托架的厚度,是否支持 SATA3 ;
3、可选的 USB 外置吸入式光驱盒,用来把拆下来的光驱做成外接 USB 光驱;
4、拆机工具,买2、3时有赠送。
硬盘托架和光驱盒加起来大概100+。

详细拆解更换可以参考 Zealer 王自如的视频Macbook Pro 改装 RAID

搞定后启动 Mac,对新硬盘进行初始化、格式化。

本来想用 USB 移动硬盘进行 Time Machine 备份,然后进入 Recovery HD 把备份回复到 SSD 盘上,奈何移动硬盘有很多资料,也没分区。Recovery HD 在从10.9升级到10.10时已经损坏,双系统 Win 7也进不去。只能用别的方法了。

解决方法是使用Carbon Copy Cloner,把整个机械盘的数据复制到 SSD 上。如果你的 SSD 介绍,可以选择删掉旧硬盘部分数据,所以选择性的复制。比如指复制系统和 Applications。我在清除很多无用、冗余、旧数据,把大小降到200一下,进行的整盘复制。复制花费时间较长,主要是因为机械盘读较慢,小文件过多。用了大概3个小时。复制完会提示给 SSD 创建 Recovery HD,我的旧 Recovery HD 已经损坏,且 SSD 空间所剩不足就放弃了。

ccc hd to ssd

重启后按住 option 键,选择 SSD 启动。进入系统配置,把 SSD 改为启动盘,这样每次启动就会载入 SSD 上的系统了。

change mac startup drive

关于HD和 SSD 如何组合发挥SSD 读写快容量小、HD 容量大速度慢的功效,大概有 Fusion Driver,Raid 0, Raid 1,SSD 做系统启动盘、机械盘做数据、挂在其文件系统下,比如/home。这个日后再研究。

iPhone 6和6Plus屏幕、UI设计和适配那些事

且看iPhone几个系列的屏幕数据:

 iPhone 4*iPhone 5*iPhone 6iPhone 6P
物理大小 - 对角(inch)3.544.75.5
物理大小 - 宽高(inch)1.94*2.911.96*3.482.3*4.12.7*4.79
PPI329.65325.97325.61400.53
物理分辨率(px)640*960640*1136750*13341080*1920
逻辑分辨率(pt)320*480320*568375*667414*736
渲染分辨率(px)640*960640*1136750*13341242*2208
像素/点比率2222.6

首先要看到的事实是6P的ppi变大了,也就是像素更小了。如果还是按1:2的点像比,那么这块1080*1920像素分辨率的屏幕应该有540*960的点分辨率。但实际计算用到点分辨率却是414*736,点像比是1:2.6,不到1:3。
那么问题来了,为什么苹果不沿用326ppi左右屏幕,而要用401ppi的屏幕?为什么6P的点分辨率是414*736?

关于这些问题可以参考知乎iPhone 6 Plus的逻辑分辨率为什么是414×736?
大概就是保证:
1.6P屏幕必须6大,5.5英寸为前提;
2.显示更多内容,所以点分辨率必须大于375*667;
3.ppi不能比之前低;
4.同样逻辑单位(点)的内容,如字体、按钮物理尺寸不能比之前小,否者会造成视觉、操作不便。
5.在现有工艺可达到。
所以最终401ppi、414*736、1080*1920、1:2.6的配置更像是一种折中的非完美方案。

问题又来了,为什么不是326ppi、880*1560(880≈2.7”*326ppi,1560≈4.79”*326ppi)、440*780、1:2这种尺寸呢?

这样还可以继续用2x图。这里就略过不研究了。

如有2.6对于开发、设计来说都不是一个特好的数字,所以苹果把它约等了一下变成3,又搞了个渲染分辨率的概念。
414*736的3倍正是1242*2208,在这个分辨率计算界面的样式,然后把最终的画面下采样(downsampling)缩小1.15显示到1080*1920上。渲染分辨率还用在未专门适配4.7英寸的iPhone 6的时,把4英寸的640*1136画面上采样(upsampling)放大1.171875倍显示在750*1334屏幕上,当然会看起来比较模糊。采用3的话以后如果采用461ppi屏幕也更容易兼容。

iPhone 6 plus downsampingiphone 6 upsampling

更全更详细的图示请参见:The Ultimate Guide To iPhone Resolutions

PPI计算和常见手机PPI信息:https://www.sven.de/dpi/

以主屏幕分辨率的app图标为例,大小为60pt*60pt,为什么@3x下icon的尺寸180*180就是正确的呢?在@2x下120*120的icon,物理尺寸是0.36”≈120px*1.96”/640px,而@3x下180*180的icon物理尺寸是0.39≈(180px/11.5)*2.7”/1080px。可见他们的物理尺寸基本一致。

对于6P,@2x素材的大小乘以1.5便是@3x图的大小。

对于iPhone 5系,屏幕只是变长了,垂直方向上的适配很简单。然后对于6和6p来说,不仅边长变宽,点像比率也变大了。那么在设计iPhone UI时就不再像以前一样了。应该结合使用point、autolayout的“相对”布局,什么时候该用固定point大小,什么时候该用相对尺寸,具体并没有可套用的准则。

比如主屏icon图标保证尺寸是60point,横向平分间隔;相册里每行4张缩略图,4等分,没有具体point大小;nav bar是同一Point大小;tab bar图标统一point大小,间隔均分。

在出设计图给程序员时的标注也不再全部是绝对的像素或pt,像间隔应该表明是横向均分。

用markman标注

在设计时应该以哪个iPhone为参考呢?画布尺寸为多大呢?
画布应该以iPhone4的点分辨率320px*480px,放大3倍,即960px*1440px为标准。这样既保证了UI对最小屏幕的绝对适配,也方便了@3x素材的导出。
在横向上,6和6P使空白区域拉伸即可。纵向可以结合留白、放大、使用滚动。

 

在编程实现应该使用Autolayout,摒弃过去的绝对pt布局。

使用代码进行布局时可以使用一些对原生NSLayoutConstraints的封装简化库,减少臃肿,提高代码可读性,加快速度。

MasonryPureLayoutKeepLayout

本人使用 PureLayout,虽然语法没 Masonry 那么简单,但是 bug 少。

 

修复cocoapods

在拉下松爷更新的Podfile后,尝试用pod update更新,结果出现下面错误

$pod update
Update all pods
Analyzing dependencies
[!] Unable to satisfy the following requirements:

- `JSQMessagesViewController (~> 6.1.0)` required by `Podfile`

没什么头绪,尝试查一下版本

$pod list | grep JSQM
  JSQMessagesViewController 6.0.0

JSQMessagesViewController主页明明标了已经是6.1.1,是不是版本库有本地缓存,在pod --help加google下,发现命令pod repo update,果断运行一下,卡住,加上–verbose

$pod repo update --verbose
  $ /usr/bin/git rev-parse  >/dev/null 2>&1

Updating spec repo `master`
  $ /usr/bin/git pull --ff-only
  error: Your local changes to the following files would be overwritten by merge:
  	CocoaPods-version.yml
  	Specs/AdMobMediationAdapterMMedia/1.5.0/AdMobMediationAdapterMMedia.podspec.json
  Please, commit your changes or stash them before you can merge.
  error: The following untracked working tree files would be overwritten by merge:
  	Specs/AAShareBubbles/1.1.0/AAShareBubbles.podspec.json
  	...[略去n行]
  	Specs/AQSEvent/0.2.0/AQSE
  Aborting
  Updating da90008..86016e3

[!] CocoaPods was not able to update the `master` repo. If this is an unexpected issue and persists you can inspect it running `pod repo update --verbose`

果然本地有缓存,还是git管理的,更新时冲突,google了一下,找到相关资料:
1.http://stackoverflow.com/questions/19477178/cocoapods-error-during-pod-update
2.http://blog.cocoapods.org/Repairing-Our-Broken-Specs-Repository/

解决方法:删除本地缓存,重新setup

$rm -fr ~/.cocoapods/repos/master
$pod setup

centos 6.5安装git

#yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
#wget https://www.kernel.org/pub/software/scm/git/git-2.2.0.tar.gz
#tar -zxf git-2.2.0.tar.gz 
#cd git-2.2.0
#make prefix=/usr/local all
#make prefix=/usr/local install

如果出错下面错误

/usr/bin/perl Makefile.PL PREFIX='/usr/local' INSTALL_BASE='' --localedir='/usr/local/share/locale'
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 3.
BEGIN failed--compilation aborted at Makefile.PL line 3.
make[1]: *** [perl.mak] Error 2
make: *** [perl/perl.mak] Error 2

就是没装perl-devel导致

python MySQLdb例子

以下代码使用了torndb(torndb是对mysqldb的简单封装,调用和使用cursor一致)
mysqldb如果查询时传入的参数是值序列,则sql的paramstyle必须是format,即%s作为占位符;
如果传入的参数是键值序列,则sql的paramstyle必须是pyformat,即%(xxx)s作为占位符;

1.count

    def get_all_topics_count_by_node_slug(self, node_slug):
        sql = 'SELECT COUNT(0) FROM topic LEFT JOIN node ON topic.node_id = node.id WHERE node.slug = %s'
        return self.db.get(sql, node_slug)['COUNT(0)']

2.select(分页)

    def get_all_topics_by_node_slug(self, node_slug, current_page=1, page_size=36, ):
        sql = '''SELECT topic.*,
                author_user.username as author_username,
                author_user.nickname as author_nickname,
                author_user.avatar as author_avatar,
                author_user.uid as author_uid,
                author_user.reputation as author_reputation,
                node.name as node_name,
                node.slug as node_slug,
                last_replied_user.username as last_replied_username,
                last_replied_user.nickname as last_replied_nickname
                FROM topic
                LEFT JOIN user AS author_user ON topic.author_id = author_user.uid
                LEFT JOIN node ON topic.node_id = node.id
                LEFT JOIN user AS last_replied_user ON topic.last_replied_by = last_replied_user.uid
                WHERE node.slug = %s
                ORDER BY last_touched DESC, created DESC, last_replied_time DESC, id DESC
                LIMIT %s, %s'''

        total_count = self.get_all_topics_count_by_node_slug(node_slug)
        total_page = int(math.ceil(total_count / float(page_size)))
        current_page = current_page if current_page <= total_page else total_page
        current_page = current_page if current_page >= 1 else 1
        previous_page = current_page - 1 if current_page > 1 else 1
        next_page = current_page + 1 if current_page < total_page else total_page

        result = {
            "list": self.db.query(sql, node_slug, (current_page-1)*page_size, page_size),
            "page": {
                "prev": previous_page,
                "next": next_page,
                "current": current_page,
                "pages": total_page,
                "total": total_count,
                "size": page_size
            }
        }
        return result

3.insert(任意字段)

    def add_new_topic(self, topic_info):
        sql = 'INSERT INTO topic ('
        sql += ', '.join(topic_info.keys())
        sql += ') VALUES ('
        sql += ', '.join(['%s'] * len(topic_info.keys()))
        sql += ')'
        return self.db.insert(sql, *topic_info.itervalues())

4.update(任意字段,pyformat)

    def update_topic_by_topic_id(self, topic_id, topic_info):
        sql = 'UPDATE topic SET '
        sql += ', '.join(['%s = %%(%s)s' % (k, k) for k in topic_info.keys()])
        sql += ' WHERE id = %(id)s'
        print sql
        return self.db.update(sql, id=topic_id, **topic_info)

python db api正确使用方式

很多人在用Python DB API时会用以下方式拼接sql

cmd = "update people set name='%s' where id='%s'" % (name, id) curs.execute(cmd)

然后调用cursor.execute执行,这样容易产生sql注入

正确的方法是使用占位符语法

cmd = "update people set name=%s where id=%s" 
curs.execute(cmd, (name, id))

execute语句在执行时会先对元组(name, id)的值转为字符串,进行转义,

不同的数据库支持不同占位符语法,常见占位符包括以下:
1.’qmark’ Question mark style, e.g. ‘…WHERE name=?’
2.’numeric’ Numeric, positional style, e.g. ‘…WHERE name=:1’ ‘named’
3.’named’ Named style, e.g. ‘…WHERE name=:name’
4.’format’ ANSI C printf format codes, e.g. ‘…WHERE name=%s’
5.’pyformat’ Python extended format codes, e.g. ‘…WHERE name=%(name)s’
注意pyformat后的s

常见数据库python链接库实现的默认paramstyle

>>>import MySQLdb; 
print MySQLdb.paramstyle 
format 
>>> import psycopg2; 
>>>print psycopg2.paramstyle 
pyformat
>>> import sqlite3; 
print sqlite3.paramstyle 
qmark

如果你在使用MySQL 或 PostgreSQL, 可以用%s(即使是数字或者非字符)

更全的关于python防止sql注入的资料下载sqlinjection-120205200846-phpapp01

检查安装的Python是否支持UCS-4

>>> import sys
>>> print sys.maxunicode

当用--enable-unicode=ucs4编译安装时,输出的是1114111;
当用--enable-unicode=ucs2编译安装时,输出的是65535.

吐槽j2ee&maven

maven作为一个j2ee事实上的标准,被大部分的开源项目采用,但是找一个库的坐标是真新费劲。
j2ee开源项目为什么不学习python开源项目,在官方主页把坐标明显的标出来啊!!!!
在http://search.maven.org和http://www.mvnrepository.com/搜出来的各种重复!不能做个官方认证吗?
以jstl为例,这么写行

        
            jstl
            jstl
            1.2
        

这么写也行

        
            javax.servlet
            jstl
            1.2
        

1.1还要加个taglibs:standard:1.1.2;
以jackson为例,2.x和1.x连groupId都换了,也是醉了。

J2EE真心混乱啊。

osx升级到10.9以上homebrew不能用

想用homebrew装个maven结果

$ brew install maven
usr/local/bin/brew: /usr/local/Library/brew.rb: /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby: bad interpreter: No such file or directory
/usr/local/bin/brew: line 23: /usr/local/Library/brew.rb: Undefined error: 0

原因是系统升级后ruby的版本升级到到了2.0,而/usr/local/Library/brew.rb里写死了用1.8版本运行brew

#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -W0
# encoding: UTF-8

在osx 10.10 Yosemite里尝试直接修改1.8为2.0结果don’t work!
在github里找到解决方法:

cd /usr/local
git fetch origin
git reset --hard origin/master

brew又可以用啦

chrome删除重复书签

google书签在自动重复后会莫名其妙的出现以下重复,同步机制和算法真是不敢恭维,比svn、git之类的diff弱多了。

去掉重复书签可以用Chrome扩展应用如SuperSorter、Bookmark Sentry。
SuperSorter谨慎使用,虽然可以去重,但是不能合并同名文件夹,会打乱文件夹排序。
Bookmark Sentry已经在Chrome Web Store找不到了。

或者可以使用delicious来收藏或者管理,同样有chrome插件。

最后提醒:使用这些插件扫描你的书签可能会泄露隐私。