做这样一个简单的 app:

一个天气应用,干净清爽的界面,天气信息一目了然。它不仅可以精确预测未来 10 天的天气,还可以显示某地的历史天气信息。它具有自定义提醒功能,支持 web 版本, iOS 版, Android 版。

为什么想要做这样一个 App ?因为你喜欢旅行,但没找到一个天气 App 可以提供你下个月或者某个特定月份的天气信息;因为你懒你没有每天看天气预报的习惯,你想要在第二天温度达到 30 度以上或者温差有 +/-7 度的时候,获得温馨提示;因为你要成为一个 Full Stack Engineer ,你必须不断训练每个 stack 的能力。

随着redis的发展,越来越多的架构用它取代了memcached作为缓存服务器的角色,它有几个很突出的特点:

  1. 除了Hash,还提供了Sorted Set, List等数据结构
  2. 可以持久化到磁盘
  3. 支持cluster (3.0)

它的性能和memcached不相上下,再加上流行的其他组件(比如队列)也会用到redis,从架构简单出发,已经没有必要混用redis和memcached了。

写篇短文介绍一下用redis作为缓存服务器配置时候需要注意几个点。

Genymotion简介

Genymotion是一套完整的工具,它提供了Android虚拟环境。如果你没有物理机器,又不想忍受官方模拟器的折磨,Genymotion会是你非常不错的选择, 它简直就是开发者、测试人员、推销者甚至是游戏玩家的福音。

本文仅谈业余时间的技术学习,不谈工作中的要求。

技术固然要时时学习,因为更新快嘛,但对待技术上学什么,怎么花时间学,需要一个指导思想,否则浪费时间而且效果不好。

  1. 抓住主干,而非细节 最近很火的一句话是“你不要用战术上的勤奋掩盖战略上的懒惰”。放到技术学习上就先主理解主干后关注枝叶,比如C++的好书很多,《Effective C++》和《Inside C++ Object Model》是好书,但它们都不是用来入门的,为什么? 因为它们不是主干,语言实现细节和各种坑你都了解了,碰到实际问题依然用不好C++。

  2. 尽量不折腾 不去折腾那些不成熟的技术,尽量用较为成熟的技术。在一年多之前,我用AngularJS,MongoDB的时候把我可给坑惨了,所以我下决心如果不因为工作坚决不碰Go语言,Node.js,要学不如学Erlang。新技术应用场景不清晰,前景不清晰,生态环境弱,类库少,坑多不容易跳出来。简而言之就是风险大于收益。同理我也不喜欢用Linux而喜欢Mac,Vim的包也是别人弄好了直接install的。

在开发网站时,同一张图片时常需要生成多张不同尺寸的缩略图片。

一般有两种策略生成缩略图,一种在上传图片时,生成所有尺寸的缩略图,另一种是请求指定尺寸时再生成缩略图。

前一种方式会有一些限制,当我们需要一种新的图片尺寸时,需要使用脚本重新生成。而后一种方式就比较灵活。(淘宝也是采用这个方案,只是淘宝使用ImageMagick。)

网上有一种是借助 lua_nginx module 调用 GraphicsMagick 命令生成缩略图片,不过 nginx 默认发布版本是不包含 lua_nginx 模块,需要重新编译安装,这样太麻烦,实现方式并不灵活。我们需要一种更灵活的方式来实现。

解决方案一


写了一个自定义类继承SSLSocketFactory:

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
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.conn.ssl.SSLSocketFactory;

public class SSLSocketFactoryEx extends SSLSocketFactory {
        
   SSLContext sslContext = SSLContext.getInstance("TLS");
        
   public SSLSocketFactoryEx(KeyStore truststore) 
                        throws NoSuchAlgorithmException, KeyManagementException,
                        KeyStoreException, UnrecoverableKeyException {
                super(truststore);
                
   TrustManager tm = new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}  
    
@Override  
public void checkClientTrusted(
   java.security.cert.X509Certificate[] chain, String authType)
                                            throws java.security.cert.CertificateException {}  
    
@Override  
public void checkServerTrusted(
   java.security.cert.X509Certificate[] chain, String authType)
                                            throws java.security.cert.CertificateException {}
        };  
        sslContext.init(null, new TrustManager[] { tm }, null);  
}  
    
@Override  
public Socket createSocket(Socket socket, String host, int port,boolean autoClose) throws IOException, UnknownHostException {  
  return sslContext.getSocketFactory().createSocket(socket, host, port,autoClose);  
}  
    
@Override  
public Socket createSocket() throws IOException {  
    return sslContext.getSocketFactory().createSocket();  
}  
}

objection 是一个轻量级的依赖注入框架,受Guice的启发,Google Wallet 也是使用的该项目。「依赖注入」是面向对象编程的一种设计模式,用来减少代码之间的耦合度。通常基于接口来实现,也就是说不需要new一个对象,而是通过相关的控制器来获取对象。2013年最火的PHP框架 laravel 就是其中的典型。

假设有以下场景:ViewControllerA.view里有一个button,点击之后push一个ViewControllerB,最简单的写法类似这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
- (void)viewDidLoad
{
    [super viewDidLoad];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.frame = CGRectMake(100, 100, 100, 30);
    [self.view addSubview:button];
}
 
- (void)buttonTapped
{
    ViewControllerB *vc = [[ViewControllerB alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
}

这样写的一个问题是,ViewControllerA需要import ViewControllerB,也就是对ViewControllerB产生了依赖。依赖的东西越多,维护起来就越麻烦,也容易出现循环依赖的问题,而objection正好可以处理这些问题。

众所周知,Android机型尺寸各种各样,于是屏幕适配就成了Android开发中很重要的一环。Android屏幕适配可能一些开发者都会遇到这样的问题,今天就来分享下屏幕适配,你会发现其实Android屏幕适配也可以很简单。

基本概念

Android屏幕适配必须要理解的一些概念,这部分可能比较枯燥,但是俗话说的好“工欲善其事,必先利器”,翻译过来就是“有什么样的枪,决定你打什么样的鸟”,一旦这些概念你理解掌握了,屏幕适配你自然而然就觉得简单多了。

  • px

    是英文单词pixel的缩写,意为像素,屏幕上的点。我们通常所说的分辨率如480X800就是指的像素。

    在设计领域中,像素是用来计算数码影像的最小单位。计算机中显示的图像并非连续的线条组成,而是由许多肉眼看不见的小点组成。如果把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小点所组成,这些小点就是构成影像的最小单位“像素”。由于是最小的独立显示单位,px均为整数,不会出现0.5px的情况。如:

对于新入门的开发者,如何安装 Ruby, Ruby Gems 和 Rails 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境。 次安装方法同样适用于产品环境!

系统需求


首先确定操作系统环境,不建议在 Windows 上面搞,所以你需要用:

Mac OS X 任意 Linux 发行版本(Ubuntu,CentOS, Redhat, ArchLinux …) 强烈新手使用 Ubuntu 省掉不必要的麻烦! 以下代码区域,带有 $ 打头的表示需要在控制台(终端)下面执行(不包括 $ 符号)

原文:http://bundler.io/rationale.html

首先,你要在你应用根目录下一个叫Gemfile文件里声明这些依赖,它看起来是这个样子的:

1
2
3
4
5
source 'https://rubygems.org'

gem 'rails', '4.1.0.rc2'
gem 'rack-cache'
gem 'nokogiri', '~> 1.6.1'

这个Gemfile说明了这些事情:

首先,他告诉 bundler 默认是在Gemfile里指定的https://rubygems.org上来找 gem。如果你的一些 gem 需要从一个私有的 gem 服务器上获取,那么你可以为这些 gem 覆盖掉这个默认的源设置。

接着,你声明了一些依赖:

  • 版本是4.1.0.rc2的rails
  • 任意版本的rack-cache
  • 版本是>= 1.6.1但是< 1.7.0的nokogiri