优大网

7 / 15

我从其他Shell脚本中学到了什么?

摘要:作者Fizer Khan是一位Shell脚本迷,他对有关Shell脚本新奇有趣的东西是如此的痴迷。本文他分享了八大Shell脚本技巧,希望你会喜欢,这些脚本可以直接拿来使用!

作者Fizer Khan是一位Shell脚本迷,他对有关Shell脚本新奇有趣的东西是如此的痴迷。最近他遇到了authy-ssh脚本,为了缓解ssh服务器双重认证问题,他学到了许多有用且很酷的东西。对此,他想分享给大家。

一、Colors your echo 

大多数情况下,你希望输出echo Color,比如绿色代表成功,红色代表失败,黄色代表警告。

 

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
NORMAL=$(tput sgr0)
GREEN=$(tput setaf 2; tput bold)
YELLOW=$(tput setaf 3)
RED=$(tput setaf 1)
function red() {
    echo -e "$RED$*$NORMAL"
}
function green() {
    echo -e "$GREEN$*$NORMAL"
}
function yellow() {
    echo -e "$YELLOW$*$NORMAL"
}
# To print success
green "Task has been completed"
# To print error
red "The configuration file does not exist"
# To print warning
yellow "You have to use higher version."

这里使用tput来设置颜色、文本设置并重置到正常颜色。想更多了解tput,请参阅prompt-color-using-tput
 

 

二、To print debug information (打印调试信息)

打印调试信息只需调试设置flag。

 

1
2
3
4
5
6
7
8
9
function debug() {
    if [[ $DEBUG ]]
    then
        echo ">>> $*"
    fi
}
# For any debug message
debug "Trying to find config file"

 

某些极客还会提供在线调试功能:
 

 

1
2
3
# From cool geeks at hacker news
function debug() { ((DEBUG)) && echo ">>> $*"; }
function debug() { [ "$DEBUG" ] && echo ">>> $*"; }

三、To check specific executable exists or not (检查特定可执行的文件是否存在) 

1
2
3
4
5
6
7
8
9
10
11
12
OK=0
FAIL=1
function require_curl() {
    which curl &>/dev/null
    if [ $? -eq 0 ]
    then
      return $OK
    fi
    return $FAIL
}

这里使用which来命令查找可执行的curl 路径。如果成功,那么可执行的文件存在,反之则不存在。将&>/dev/null设置在输出流中,错误流会显示to /dev/null (这就意味着在控制板上没有任何东西可打印)。
 

 

 

有些极客会建议直接通过返回which来返回代码。

 

1
2
3
# From cool geeks at hacker news
function require_curl() { which "curl" &>/dev/null; }
function require_curl() { which -s "curl"; }

四、To print usage of scripts  (打印使用的脚本) 

当我开始编写shell 脚本,我会用echo来命令打印已使用的脚本。当有大量的文本在使用时, echo命令会变得凌乱,那么可以利用cat来设置命令。

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat << EOF
Usage: myscript <command> <arguments>
VERSION: 1.0
Available Commands
    install - Install package
    uninstall - Uninstall package
    update - Update package
    list - List packages
EOF

这里的<<被称为<<here document,字符串在两个EOF中。 

五、User configured value vs Default value (用户配置值VS 默认值)

有时,如果用户没有设置值,那么会使用默认值。

 

1
URL=${URL:-http://localhost:8080}

检查URL环境变量。如果不存在,可指定为localhost。
 

六、To check the length of the string 检查字符串长度

 

1
2
3
4
5
if [ ${#authy_api_key} != 32 ]
then
  red "you have entered a wrong API key"
  return $FAIL
fi

利用 ${#VARIABLE_NAME} 定义变量值的长度。

七、To read inputs with timeout (读取输入超时)
 

 

1
2
3
4
5
6
7
8
READ_TIMEOUT=60
read -t "$READ_TIMEOUT" input
# if you do not want quotes, then escape it
input=$(sed "s/[;\`\"\$\' ]//g" <<< $input)
# For reading number, then you can escape other characters
input=$(sed 's/[^0-9]*//g' <<< $input)

八、To get directory name and file name  (获取目录名和文件名) 

 

1
2
3
4
5
6
7
8
# To find base directory
APP_ROOT=`dirname "$0"`
# To find the file name
filename=`basename "$filepath"`
# To find the file name without extension
filename=`basename "$filepath" .html`

英文出自:FizerKhan

趣文:为什么软件开发周期通常是预期的两三倍?

【感谢@袁欣_Jason 的热心翻译。如果其他朋友也有不错的原创或译文,可以尝试推荐给伯乐在线。】

导读:有国外开发者在 Quora 提了这个问题:“为什么软件开发周期通常是预期的两三倍?” 并补充问:“这是开发人员的错误? 是管理失误? 是因为做事方法不对, 或者说缺乏好的方法?还是说这就是软件开发流程的特点?” Michael Wolfe 在2012年1月28日给的回复,非常经典,截至我们发布时已有8016个赞。以下是译文。

让我们先沿着海岸线,从旧金山(SF)走路去洛杉矶(LA),去拜访我们住在Newport Beach的朋友,我拿出地图在上面画出了行进路线。

全程大约有400英里,如果我们每天走10小时每小时4公里的话,只用10天就可以到达目的地。立刻打电话给我们的朋友预定下周六的晚餐,告诉他们下周六晚上六点我们一定会准时出现,朋友们已经等不及了!

第二天清晨,我们带着准备冒险的兴奋起床,背起行囊,拿出地图,准备计划我们冒险的第一天,看一眼地图,噢,不!

哇,海岸线上有这么多迂回曲折的线路。每天行进40英里的话,10天后只能勉强到达Half Moon Bay(半月湾?)。这趟旅行至少有500英里,而不是400。赶紧打电话给我们的朋友,将晚餐顺延至下下周周二。人还是应该现实一点。朋友们有点失望,不过仍然盼望见到我们,况且花 12 天从 SF 到 LA 也不赖。

把不开心的事丢到一边,准备出发。两小时过后,我们才刚刚走出动物园。出了什么事?我们低头看了一下脚下的路:

天哪,这样走路也太慢了!有沙子、海水、阶梯、溪流,还有海边愤怒的海狮!这样我们只能按每小时2公里的速度前进,只有我们预估一般的速度。要么我们现在每天走20小时,要么再把晚餐推迟一个星期。好吧,让我们各退一步:每天走12个小时,把晚餐安排到下下周的周末。只好再打电话给朋友告诉他们这个情况。朋友们有些不高兴,但还是表示可以,到时候见。

在辛苦走了12小时后,我们准备在 Moss Beach 扎营休息。靠,要把帐篷在风中立起来根本不可能。直到半夜才开始休息。不过没什么大不了:明天在加快点速度就可以了。

第二天早上睡过头了,早上10点才醒,起来浑身酸痛精疲力尽。艹,今天没法走12个小时了,先走10个小时,明天可以走14个小时。收拾东西出发。

再缓慢行进了几个小时之后,我发现伙伴脚有点跛。妈的,是水泡。必须现在解决它,在这些问题开始减慢我们的速度前,必须将它们扼杀在萌芽状态。我慢跑了45分钟到达内陆3英里远的Pescadero,买了一些创可贴再快速跑回去给朋友包扎了一下。我快累坏了,太阳也快下山了,又浪费了一天的时间。到我们准备休息前今天只走了6英里。但是我们确实需要补充一下供给。一切都很好,明天我们就能赶上。

第二天醒来,扎紧脚上的绷带准备出发。转角之后突然发现,靠!这是个啥?

你妹的地图上怎么没标出它!现在我们只能往内陆走3英里,绕过这些被联邦政府用栅栏保护起来的区域,中途迷路了两次,在中午前才好不容易又回到了海岸线。今天的时间过了一大半,而我们才前进了差不多1英里。好吧,不过我们不会再打电话给朋友推迟了,今天我们会一直走到午夜试着赶上进度。

晚上在大雾里断断续续地睡了一夜。一大早被我的伙伴叫醒,他一阵阵的头疼,还有点发烧,我问他能不能坚持一下。“你在想什么呢,混蛋,我已经连续三天在这么冷的雾中赶路,没有休息过了。“好吧,今天看来只能黄了,只能在原地好好恢复了。现在我们已经有经验了,今天好好休息明天再走14个小时,还有几天的时间,我们一定能够做到!

第二天我们昏昏沉沉地起来了。我看了一眼随身的地图:

天啊!我们已经走了10天旅程里的第5天还没有离开海湾区域!太荒唐了!我们要重新估计一下准确的时间再打给朋友,搞不好会被骂,但至少得找一个现实一点的目标。

同伴说,我们在四天里走了40英里,这趟旅程至少又600英里,那就至少要60天,安全一点的说法说不定要70天,“没门…是,以前我是没走路从SF去过LA,但肯定不会要70天的时间,如果告诉他们我们要到复活节才能到,那要被他们笑死的“,我说。

我接着说,“如果你能保证每天走16个小时,我们就能把落下的时间补回来!我知道很困难,但现在是最关键的时刻,别抱怨了!”伙伴对我吼道 “一开始又不是我告诉别人下周日我们就能到的!因为你犯的这个错差点要我的命!”

两个人就这样不说话了。我还是没打出电话,等我的伙伴明天冷静一点我再决定,我也愿意做一些更合理的承诺。

第二天上午,我们一直待在各自的帐篷中直到一场暴风雨袭来。我们赶紧收拾好东西直到10点才摆脱危险。浑身酸痛,又长了好多新水泡。之前发生的事谁也没提,直到发现我那愚蠢的伙伴把水壶落下了,又被我指责了一顿,我们不得不再花30分钟回去取它。

我心里记得我们的厕纸已经快用完了,下次到一个小镇的时候应该囤一点。在我们又转个弯后,才发现一条湍急的河流挡住了去路,这时我突然感到肚子一阵难受……

http://blog.jobbole.com/45756/

分布式系统事务原子性的非阻塞实现

摘要:分布式系统中,常见的多对象更新操作实现却比较困难,如果将这些操作看作一个事务,实现事务的原子性就成了关键所在。通常情况下原子性都是通过锁实现的,作者提供了一种非锁的方式实现——NBTA。

本文作者Peter Bailis是美国Berkeley的研究生,主要研究方向是分布式系统与数据库。作者目前主要的研究内容是分布式数据的一致性,尤其是如何调和ACID特性和分布式一致性模型,以及如何在理论和实际中更好的理解最终一致性。

作者将分布式系统中的事务定义为针对多个服务器的同时操作,本文主要讨论了分布式系统事务的原子性的一种实现算法。通常情况下原子性都是通过锁实现的,这个算法并没有使用锁,原理很简单,采用了简单的多版本控制和存储一些额外的元数据,虽然作者只是在实验环境中实现了这个算法,并没有投入到实际生产中,但是作者思考问题的方式值得参考。

分布式系统事务原子性

在现实的分布式系统中,多对象更新的操作很常见,但是实现起来却并不简单。同时更新两个或多个对象时,对于这些对象的其他读取者,原子性很重要:你的更新要么全部可见,要么全部不可见。

这里所说的原子性和线性一致并不是一个概念,数据一致性在Gilbert和Lynch证明CAP原理时被提到过,后来通常被称为原子一致性。而线性一致化关注实时的顺序操作,是一个单对象的问题。这里的“原子性”源于数据库环境(ACID中的“A”),涉及对多个对象的执行和查询操作。为了避免混淆,我们称这个原子性为“事务原子性”。

许多场景中都会遇到这种问题,从社交网络图(例如Facebook的TAO系统,双向的朋友关系被保存在两个单向的指针中)到类似计数器(例如Twitter的Rainbird分层聚合器)和二级索引的分布式数据结构。本文中,我将假设我们的工作都是高可用的事务,原子性的多对象更新,或事务的原子性,是其首要特性。

现有的技术

多对象更新的事务操作通常采用以下三种策略之一:

 

 

使用锁来同时更新多个项目。执行更新操作时加写锁,执行读操作时加读锁,就可以保证事务的原子性。但是在分布式环境中,局部故障和网络延迟都意味着锁操作可能会导致Bad Time。

具体来讲,锁操作有可能会导致一些怪异的结果。如果客户端在持有锁时宕机,服务器本应该最终撤销这个锁。这需要某种形式的故障检测或超时(在异步网络中会导致一些尴尬的情况)以及在撤销锁前同时撤销以前的操作。但是在执行更新操作时阻塞读操作显然是不合理的,反之亦然。如果我们追求高可用性,锁不是一个值得考虑的方案。

 

实体组

 

将想要同时更新的对象放在一起。这种策略通常称为“实体组”,可以让事务性原子更简单:在一台机器上加锁很快,而且不会遇到分布式锁的局部故障和网络延迟的问题。不幸的是,这种解决方案会影响数据布局和分布,而且不适用于难于分割的数据。

 

Fuck-it模式

使用“fuck-it”模式,不进行任何并发控制的情况下更新所有的对象,并保持事务的原子性。这个策略是很常见的:扩展性良好,适用于任何系统,但是直到系统达到稳定状态后,才会提供原子性保证(例如聚合,或者说最终一致性)。

NBTA

 

在这篇文章中,作者会介绍一种简单的替代方案,作者称其为事务原子性的非阻塞实现,简称为NBTA(Non-blocking transactional atomicity),使用多版本和一些额外的元数据在不使用锁的情况下,保证事务的原子性。具体来说,这种方案不会由于过程错误而阻塞读取和写入操作。关键的想法是避免执行局部更新,并且利用额外的元数据代替副本间的同步。

NBTA示例

可以用这个简单的场景来说明NBTA:有两个服务器,server for x上存储x,server for y上存储y,初值都是0。假设有两个客户端,Client1要执行写入操作,使x=1,y=1,Client2要同时读取x和y,关于副本的问题稍后会讨论。作者将Client1要执行的写入操作称为一个事务,而这个事务的操作对象server for x和server for y被称为事务兄弟。

good和pending

将每台服务器的存储分为两中状态:good和pending。要保证同属于一个事务的写入操作,如果其中一个操作被存储为good状态,这个事务的其它写入操作要么被存储为good,要么被存储为pending。比如在上面所说的场景中,如果x=1在server for x上被存储为good,那么必须保证y=1在server for y被存储为good或pending。

首先,各服务器会收到到写操作请求保存为pending状态,然后一旦服务器知晓(可能是异步的)某个写入操作相关的事务兄弟都已经将操作请求保存为pending状态,这个服务器就会更新这个操作为good状态。客户端进行两轮通信,就可以使服务器得到写操作已经稳定的信息:第一轮通信中,server for x和server for y会将从Client1收到请求保存为pending状态,并将确认回复给Client1,Client1收到确认后会进行第二轮通信,通知server for x和server for y写操作已达到稳定状态。

竞争危害和指针

理想的状态是,只读取good状态的数据,就可以保证事务的原子性。但是存在一种竞争条件的情况:比如server for x已经更新x=1,并保存为good状态,但在其事务兄弟server for y中相关操作y=1依旧是pending状态,Client2如果只读取good状态的数据,得到的结果将是x=1,y=0,破坏了事务的原子性。我们希望这种情况下,第二个服务器能够自动调用pending状态的数据以供读取。

为了解决这个问题,可以在每个写入操作中加入一些额外的信息:事务兄弟的列表以及一个时间戳。这个时间戳是客户端进行多值更新前,为每个写操作唯一生成的,比如,可以是客户端ID+本地时间或一个随机数。这样的话,当一个客户端读取good状态的数据时,还会读到时间戳和具有相同时间戳的事务兄弟的列表。客户端也会在发送读取请求附带一个时间戳,服务器会根据时间戳从pending或good中取出数据交付给客户端。如果客户端的请求中没有附带时间戳,服务器会将good中时间戳最高的值交付给客户端。

优化

以下是NBTA算法的一些优化:

pending和good的规模

如果用在good中只保存最近的写入操作,那么一个写入操作的兄弟事务可能会被覆盖,为了避免这种情况的发生,服务器会在good中将历史数据保留一定的时间。

更快的写操作

有一种方案可以替代客户端的第二轮通信操作。服务器一旦将写操作存入pending中,就直接互相通信,可使用类似于PAXOS的算法实现。此外,客户端也可以异步发起第二轮通信。然而,为了确保客户端在这些情况下读取写操作,它们要保留元数据直到每个写操作都被存为good状态。

副本

目前为止的讨论都基于每个数据项只存储在一个服务器上。算法实现的前提条件是每个服务器的强一致性。服务器间的副本有两种情况:如果所有的客户端都只能访问一部分服务器,那么客户端只需要对这些对应的服务器集合进行更新,这组服务器都存有数据的副本。如果客户端可以访问任何服务器,那么需要花费较长的时间去同步数据。

读/写事务

以上讨论的算法同样适用于读/写操作。对于ANSI标准的可重复读模型,主要的问题是保证从一个事务的原子组中读取。可以在事务执行前,事先声明所有的读取操作或者通过类似向量时间的元数据实现。

元数据的规模

最谨慎的做法是将元数据一直保存,但是也可以在写操作在所有服务器中都达到good状态时,将元数据删除。

算法的实现

作者采用LevelDB数据库实现了NBTA算法及其改进。在Yahoo!的云平台上,8个操作的NBTA事务可以达到最终一致性的33%(所有都是写操作)至95.2%(所有都是读操作)峰值吞吐量。并且这种实现是线性扩展的,运行50个EC2实例,对于长度为8的事务(50%的读操作,50%的写操作),可以达到每秒执行250000次操作。

实验结果表明NBTA的性能大大优于基于锁的操作,因为不会发生阻塞。主要的花销来自于元数据以及将写入操作从pending更新为good。基于这些结果,作者已经开始将NBTA应用于其它数据存储和二级索引上。

结论

这篇文章展现了如何在不使用锁的情况下,实现在任意数据分片的原子性多对象更新。数据库中有很多类似于NBTA的算法。例如客户端第二轮通信的优化是通过PAXOS的算法实现的,使用额外的元数据保持并发更新类似于B树或其它非锁的数据结构。当然,多版本并发控制和基于时间戳的并发控制在数据库系统中也都有悠久的历史。但是NBTA的关键是实现事务的原子性,同时避免中央集权的时间戳或并发控制机制。具体来说要在数据读取操作前达到一个稳定状态,主要的挑战是解决竞争条件。在实际中,相比其它基于锁的技术,这个算法表现得很好。(编译/周小璐 审校/仲浩)

原文链接:Non-blocking transactional atomicity

http://www.csdn.net/article/2013-08-08/2816504-non-blocking-transactional-atomicity

 

java实现矩形,数字从四周到中心逐渐增大

打印效果:Matrix

public class TestMatrix {
public static void main(String[] args) {
testMatrix();
}

static void testMatrix() {
int row = 5, col = 3, x = 0, y = 0, start = 1000;
int[][] matrix = new int[row][col];
setMatrix(matrix, x, start);
printMatrix(matrix);
}

/**
* 递归实现.<br>
* 从四周到中心,数字逐渐递增
*
*/
static void setMatrix(int[][] matrix, int p, int start) {
int xLen = matrix.length, yLen = matrix[0].length;
int i, doublep = 2 * p;
if (yLen <= doublep || xLen <= doublep)
return;

// 上边
int topMax = yLen – p;
for (i = p; i < topMax; i++) {
matrix[p][i] = start++;
}

// 右边
int rightMax = xLen – p;
int rightY = yLen – p – 1;
for (i = p + 1; i < rightMax; i++) {
matrix[i][rightY] = start++;
}

// 没有右边情况
if (xLen == doublep + 1) {
return;
}

// 下边
int bottomX = rightMax – 1;
for (i = yLen – p – 2; i >= p; i–) {
matrix[bottomX][i] = start++;
}

// 没有下边
if (yLen == doublep + 1) {
return;
}

// 左边
for (i = xLen – p – 2; i > p; i–) {
matrix[i][p] = start++;
}
setMatrix(matrix, p + 1, start);
}

/**
* 打印数组
*/
static void printMatrix(int[][] matrix) {
for (int[] xl : matrix) {
for (int yl : xl) {
System.out.print(yl + ” “);
}
System.out.println();
}
}

相处越久越懂你,考拉FM借短节目组装你的个性广播电台

沈超 发表于 2013/08/02-19:43 车语传媒 /俞清木 /考拉FM

移动电台应用已经不是什么新鲜事物,除了司空见惯的各类音乐电台外,此前被我们报道过的就有蜻蜓FM窄播以及国外的TuneIn。但是旧行当也能玩出新花活,今年 6 月份上线的考拉FM从体验和模式上算是一个另类。

先从操作体验上看。打开考拉界面,进入视野的只有播放控制、节目页、用户账号三个元素,而操作方式也被极度精简:左右滑动节目页实现节目切换,上滑表示“喜欢”,下滑表示“踩”。

加上播放\暂停,可被执行的基本操作只有五种,连社交分享都隐藏在用户“喜欢”之后出现的二级选项中。如果可以的话,我真的很想在考拉所标榜的“极简主义”之前再加一个“丧心病狂的”作为修饰词。

再从内容上看。其他电台应用推给用户的多是内容连续的“频道”,而考拉 FM 提供的则是内容碎片化的“节目”。大多数“节目”都简短到几分钟左右,是为了与移动场景下用户分散的注意力相适应。

当然考拉要做的不止这些:把内容打散,以节目流的形式“喂”给听众,听众通过“喜欢”“踩”的动作表达个人偏好,后台通过算法不断优化节目流再反馈给听众,最终听众会拥有一部个性化定制的专属电台。以上都需要依靠一个包括普林斯顿博士、麻省理工硕士和斯隆商学院 MBA 的技术班底来实现,带着这一系列名校光环,相信考拉在数据挖掘和机器学习上的实力应该会比较扎实。

此外,值得一提的是考拉的出品公司。考拉 FM 由车语传媒推出,车语长期从事电台频道运营和广告代理业务,创始人俞清木曾任搜狐汽车频道主编。车语拥有十分丰富的内容储备和客户资源,包括:1200 个签约主播贡献的 14000 多个独立音频;优酷土豆、PPTV、爱奇艺等贡献的 300 档节目;有声读物公司鸿达以泰、酷听网、时代光华等贡献的 12000 多集的有声读物……再加上相对强大的自制内容能力,客观地说,考拉 FM 的版权风险可能是同类产品中最小的。

目前车语传媒已获 DCM、贝塔斯曼、君联资本三家投资,并且正在与其他机构接洽中。

如果你的数据可以让互联网公司盈利,为什么就不能替你赚钱?

boxi 发表于 12小时前 个人数据 /Reputation.com /Personal /Michael Fertik /consumer data vault

现在,典型的互联网商业模式都是这样的:提供免费服务,然后通过收集到的用户个人数据来赚钱。Facebook、Google、LinkedIn 皆如此。这些公司是如何根据你的兴趣爱好来推送定向广告的?是不是向其他公司出售数据来赚钱了?

你的数据应该能为你赚钱才对。虽然大家对这件事的讨论已经持续了几年,但是却一直没有人付诸实践。不过网上隐私和信誉管理初创企业Reputation.com打算要首开先河,其联合创始人兼 CEO Michael Fertik 透露,他的公司不久将会推出一项名为“消费者电子资料库”的新功能,如果用户将其特定的个人信息分享给其他公司的话,就能获得定的折扣和特别待遇。比方说,让航空公司了解你的收入情况可以换得积分并在下次飞行时获得升舱待遇。

Fertik 称他现在已经在跟若干感兴趣的大公司谈过。但是并未透露哪些数据可以交易,用于什么目的,但是他说主流的航空公司都比较喜欢这个主意。

Reputation.com 成立于 2006 年,迄今为止共筹得了 6700 万美元的融资。目前该公司提供的产品可帮助个人和公司在互联网和各种专有数据库上寻找有关自己的信息。付费后客户还可以让 Reputation.com 删除相关信息或记录。

Reputation.com 的这些产品已经拥有了数百万用户,这意味着许多人在 Reputation.com 上面已经有了数据可供交易。这些数据包括家庭住址、购买习惯、工作经历以及收入信息等。

虽然 Reputation.com 的用户数不可与 Facebook 的同日而语,但是 Fertik 说 Reputation.com 客户的数据对于营销人员来说更有价值。Reputation.com 还申请了数据挖掘方面的专利,可识别客户数据资料库中的内在价值。

但是宾州大学沃顿商学院的教授 Peter Fader 对此提出质疑,认为这些信息的价值未必像 Fertik 说的那么有用,相对而言,捕捉客户行为的数据会更加重要,而且许多公司通过与客户各种渠道的交互早已掌握那些信息。

至于消费者,Fader 预计他们对管理和交易自己数据的积极性也不会提高。因为管理个人数据要花费的精力要超过其得到的好处。

但是 Shane Green 不同意教授的观点。Shane Green 是提供个人信息存储的初创企业Personal的联合创始人兼 CEO,他说越来越突出的隐私问题表明许多人并不关心自己数据发生了什么事情。Personal 此前曾有过与 Reputation.com 类似的计划,但现在计划变了。不过,Green 仍认为 Fertik 的愿景是有意义的,他认为未来的营销市场将会越来越往基于用户许可的方向发展。

Green 举了一个租车到期的例子来说明个人控制个人数据带来的价值。只有一家汽车公司知道这一点,但是如果你的确想买车的话,其他汽车公司甚至会愿意付数百美元让你透露这一信息。

Personal 成立于 2009 年,目前已融资 1570 万美元。该公司目前的关注点是帮助用户核对和重用数据,比方说利用存储的数据完成大学和贷款的申请。

Personal 的目的也是要建立一个基础设施,让用户选择性地与其他公司分享数据从而获得折扣等好处。类似于用 Facebook 或 Google 账号登录其他网站,用户也可以用 Personal 账号与其他公司连接,然后控制该公司可访问的数据内容和访问时间。现在 Car and Driver 网站已经可以用 Personal 账号登录,用户可以通过授权页面选择允许网站访问的数据,包括制造商、汽车型号、驾龄等。Green 说:“数据市场的价值将超乎想象,但是我们现在关注的是盈利。”

第一个ps例子:泡泡笔刷

效果图泡泡笔刷
制作步骤
1.新建一个文件,高400,宽400,分辨率72,rgb颜色8位,背景内容白色
2.改变背景色:图像->调整->反相(ctrl+i)
3.双击右下方的黑色图片,弹出确定就行(进行解锁,把它变色图层)。
4.滤镜-》渲染-》镜头光晕,选择第三个,出现一个关照效果
5.滤镜-》扭曲-》极坐标,选择第二个
6.图像-》图像旋转-180度
7.滤镜-》扭曲-》极坐标,选择第一个,出现一个圆的效果
8.长按选框工具,选择椭圆选框工具,按住shift拉出一个圆,大小不要大于外围圆的大小
9.ctrl+shift+i,进行反相,按delete删除
10.ctrl+shift+i,进行反相,按ctrl+i,图像从黑变白
11.右键-》取消选择
12.编辑-》定义画笔预设

可以直接拿来用的15个jQuery代码片段

摘要:开发人员利用jQuery代码不仅能给网站带来各种动画、特效,还会提高网站的用户体验。本文总结了开发者经常使用的15个jQuery代码片段,大家可以直接拿来用。

jQuery里提供了许多创建交互式网站的方法,在开发Web项目时,开发人员应该好好利用jQuery代码,它们不仅能给网站带来各种动画、特效,还会提高网站的用户体验。

本文收集了15段非常实用的jQuery代码片段,你可以直接复制黏贴到代码里,但请开发者注意了,要理解代码再使用哦。下面就让我们一起来享受jQuery代码的魅力之处吧。

1.预加载图片

 

1
2
3
4
5
6
7
8
9
10
11
12
(function($) {
  var cache = [];
  // Arguments are image paths relative to the current page.
  $.preLoadImages = function() {
    var args_len = arguments.length;
    for (var i = args_len; i--;) {
      var cacheImage = document.createElement('img');
      cacheImage.src = arguments[i];
      cache.push(cacheImage);
    }
  }
jQuery.preLoadImages("image1.gif""/path/to/image2.png");

源码 

 

2. 让页面中的每个元素都适合在移动设备上展示

 

 

 

1
2
3
4
5
6
7
8
9
10
11
var scr = document.createElement('script');
document.body.appendChild(scr);
scr.onload = function(){
    $('div').attr('class''').attr('id''').css({
        'margin' : 0,
        'padding' : 0,
        'width''100%',
        'clear':'both'
    });
};

源码 

3.图像等比例缩放

 

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
$(window).bind("load"function() {
    // IMAGE RESIZE
    $('#product_cat_list img').each(function() {
        var maxWidth = 120;
        var maxHeight = 120;
        var ratio = 0;
        var width = $(this).width();
        var height = $(this).height();
        if(width > maxWidth){
            ratio = maxWidth / width;
            $(this).css("width", maxWidth);
            $(this).css("height", height * ratio);
            height = height * ratio;
        }
        var width = $(this).width();
        var height = $(this).height();
        if(height > maxHeight){
            ratio = maxHeight / height;
            $(this).css("height", maxHeight);
            $(this).css("width", width * ratio);
            width = width * ratio;
        }
    });
    //$("#contentpage img").show();
    // IMAGE RESIZE
});

源码 

4.返回页面顶部

 

1
2
3
4
5
6
7
8
// Back To Top
$(document).ready(function(){
  $('.top').click(function() { 
     $(document).scrollTo(0,500); 
  });
});
//Create a link defined with the class .top
<a href="#" class="top">Back To Top</a>

源码 

 

5.使用jQuery打造手风琴式的折叠效果

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var accordion = {
     init: function(){
           var $container = $('#accordion');
           $container.find('li:not(:first) .details').hide();
           $container.find('li:first').addClass('active');
           $container.on('click','li a',function(e){
                  e.preventDefault();
                  var $this = $(this).parents('li');
                  if($this.hasClass('active')){
                         if($('.details').is(':visible')) {
                                $this.find('.details').slideUp();
                         else {
                                $this.find('.details').slideDown();
                         }
                  else {
                         $container.find('li.active .details').slideUp();
                         $container.find('li').removeClass('active');
                         $this.addClass('active');
                         $this.find('.details').slideDown();
                  }
           });
     }
};

6.通过预加载图片廊中的上一幅下一幅图片来模仿Facebook的图片展示方式

 

 

1
2
3
4
5
6
7
8
var nextimage = "/images/some-image.jpg";
$(document).ready(function(){
window.setTimeout(function(){
var img = $("").attr("src", nextimage).load(function(){
//all done
});
}, 100);
});

源码

7.使用jQuery和Ajax自动填充选择框 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
$(function(){
$("select#ctlJob").change(function(){
$.getJSON("/select.php",{id: $(this).val(), ajax: 'true'}, function(j){
var options = '';
for (var i = 0; i < j.length; i++) {
options += '
' + j[i].optionDisplay + '
';
}
$("select#ctlPerson").html(options);
})
})
})

源码 

8.自动替换丢失的图片

 

 

1
2
3
4
5
6
7
8
// Safe Snippet
$("img").error(function () {
    $(this).unbind("error").attr("src""missing_image.gif");
});
// Persistent Snipper
$("img").error(function () {
    $(this).attr("src""missing_image.gif");
});

源码

9.在鼠标悬停时显示淡入/淡出特效

 

 

1
2
3
4
5
6
7
8
$(document).ready(function(){
    $(".thumbs img").fadeTo("slow", 0.6);// This sets the opacity of the thumbs to fade down to 60% when the page loads
    $(".thumbs img").hover(function(){
        $(this).fadeTo("slow", 1.0);// This should set the opacity to 100% on hover
    },function(){
        $(this).fadeTo("slow", 0.6);// This should set the opacity back to 60% on mouseout
    });
});

源码 

10.清空表单数据

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function clearForm(form) {
  // iterate over all of the inputs for the form
  // element that was passed in
  $(':input', form).each(function() {
    var type = this.type;
    var tag = this.tagName.toLowerCase();// normalize case
    // it's ok to reset the value attr of text inputs,
    // password inputs, and textareas
    if (type == 'text' || type == 'password' || tag == 'textarea')
      this.value = "";
    // checkboxes and radios need to have their checked state cleared
    // but should *not* have their 'value' changed
    else if (type == 'checkbox' || type == 'radio')
      this.checked = false;
    // select elements need to have their 'selectedIndex' property set to -1
    // (this works for both single and multiple select elements)
    else if (tag == 'select')
      this.selectedIndex = -1;
  });
};

源码 

11.预防对表单进行多次提交

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(document).ready(function() {
  $('form').submit(function() {
    if(typeof jQuery.data(this"disabledOnSubmit") == 'undefined') {
      jQuery.data(this"disabledOnSubmit", { submited: true });
      $('input[type=submit], input[type=button]'this).each(function() {
        $(this).attr("disabled""disabled");
      });
      return true;
    }
    else
    {
      return false;
    }
  });
});

源码 

12.动态添加表单元素

 

1
2
3
4
5
//change event on password1 field to prompt new input
$('#password1').change(function() {
        //dynamically create new input and insert after password1
        $("#password1").append("");
});

源码 

13.让整个Div可点击

 

1
2
blah blah blah. link
The following lines of jQuery will make the entire div clickable: $(".myBox").click(function(){ window.location=$(this).find("a").attr("href"); return false; });

源码 

14.平衡高度或Div元素

 

1
2
3
4
5
var maxHeight = 0;
$("div").each(function(){
   if ($(this).height() > maxHeight) { maxHeight = $(this).height(); }
});
$("div").height(maxHeight);

源码 

 

15. 在窗口滚动时自动加载内容

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var loading = false;
$(window).scroll(function(){
    if((($(window).scrollTop()+$(window).height())+250)>=$(document).height()){
        if(loading == false){
            loading = true;
            $('#loadingbar').css("display","block");
            $.get("load.php?start="+$('#loaded_max').val(), function(loaded){
                $('body').append(loaded);
                $('#loaded_max').val(parseInt($('#loaded_max').val())+50);
                $('#loadingbar').css("display","none");
                loading = false;
            });
        }
    }
});
$(document).ready(function() {
    $('#loaded_max').val(50);
});

来自: codegeekz

创业者如何在Demo演讲上打动投资人?

摘要:Demo演讲中怎样才能打动投资人?一句话说清你的idea。在Google两位创始人Larry和Sergey向红杉资本寻求融资的时候,他们就一句话介绍了Google的独特与功能:Google一键通世界。你们感受一下。

作为记者,有时会参加一些创业创新类会议倾听创业者们的演讲。一般来说,主办方会给创业者10分钟的时间去展示自己的idea。在讲的过程中,有的创业者可能是因为长时间和机器交流,本身并不擅长言谈,演讲的时候显得特别腼腆和不自信。演讲结束后谁大家都云里雾里,在最后投资人提问的环节也答非所问。

也许有的投资人会在会后深入的了解你的产品,挖掘出它的潜力,但大部分投资人都不会有这个精力和时间。怎么才能在演讲中吸引到他们?如果你看过《乔布斯的魔力演讲》,应该会有所感触,虽然是乔布斯在新品发布上会的演讲技巧,但是很多其实是通用的。下面分享一些自己的观点(并不完全是书中所说):

 

时间控制。我们都知道,人的大脑会产生厌倦感,注意力时间是有限的,一般是在10分钟以内大家会认真听你的演讲(更甚的说法是六分钟),一旦超过那个时间点,大家的注意力可能都不在你那里了,打哈欠、看手表、玩手机、窃窃私语等,一片躁动。但是有些创业者就是无法在10分钟内讲完自己的内容,让人很是着急。

演讲思路。一般以讲故事的方式提出问题,然后介绍你的idea能解决这个问题。当然,不同的idea有不同的演讲思路,总的来说,你要能一直吸引大家的注意力,让他们关心你所讲的内容。

幻灯片尽量简洁。“复杂的最终境界是简单”,虽然微软给你提供了一级标题、二级标题、三级标题,但你最好不要用,否则幻灯片感觉像学术论文一样的复杂。堆砌文字只会让大家为了去理解幻灯片上大量的文字信息而分心,导致对你所讲的内容关心不多。最好一张幻灯片一个点。

把投资人都当“懒人”。投资人也是观众,而观众分为视觉、听觉、知觉性观众,反映到你的幻灯片就是,对听觉和视觉型观众,尽量用图片,因为图片更直观易理解,且能给人留下更长久的印象。对于必须要用文字的表达,也尽量简洁,比如只显示一个关键词,它可能是某个数据、年份或者游戏中某个角色,你要做的事情就是具体去解释这些关键词背后的意义给“懒惰”的观众。对于知觉性的观众,如果你做的是硬件产品,一定要与他们互动,让他们去触摸、把玩。

把投资人当小白。演讲中尽量避免专业术语,措辞尽量简单。关于这点,对比最强烈的的两个演讲是在2007年的Macworld大会上乔布斯和盖茨的。盖茨给人的感觉就是用一堆的专业术语自说自话,乔布斯给人的感觉是用通俗易懂的语言和观众互动。

让数字鲜活起来。对于一些枯燥的专业数据,你要去类比或者作比喻。比如形容IBM的超级计算机Roadrunner。如果给你说:这台计算机能力超强悍,运算速度达到了1petaflop/s,也就是每秒1000万亿次。是不是觉得有些懵?好像特厉害,但不知道到底有多厉害。如果这么给你形容:它的计算能力与10万台笔记本电脑计算能力的总和,是不是一下就觉得数字鲜活起来了?

idea的精简有力表达。你需要用一句话说清楚你idea能解决的问题和独特之处。在Google两位创始人Larry和Sergey向红杉资本寻求融资的时候,他们就一句话介绍了Google的独特与功能“Google provides access to the world’s information in one click”(Google一键通世界),正是这简单的表达,让投资人理解了Google技术的意义。

当然,上面这些只是一些通用的东西,演讲起来还得具体问题具体分析,但无论你介绍的是硬件、App、游戏或是开发工具,在去见投资人或者参加演讲之前,一定要彻彻底底弄清自己在做什么,不仅是为了融资,更是为了弄清你的这个idea到底有没有价值。

 

http://www.csdn.net/article/2013-07-17/2816253-startup-pitch

几道容易出错的JavaScript题目

下面这几道JavaScript题目大多来自于周五的一个小分享。都是很小的题目,但是很容易犯错。有一些是语言特性使然,有一些则是语言本身没有设计好而留下的陷阱。结果就是,遇到的人很容易陷进去骂娘,这些东西是略有些反直觉,感兴趣的不妨看看,平时我们还是尽量少些这样似是而非的代码。

1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Container( properties ) {
    var objthis = this;
    for ( var i in properties ) {
        (function(){
                var t = properties[i];
                objthis[ "get" + i ] = function() {return t;};
                objthis[ "set" + i ] = function(val) {t = val;};
        })();
    }
}
var prop = {Name : "Jim", Age : 13};
var con = new Container(prop);
console.log(con.getName());
con.setName("Lucy");
console.log(con.getName());
console.log(prop.Name);

这段代码会输出什么?前面两行分别是“Jim”和“Lucy”,这不会有问题;但是第三行应该输出的是“Jim”,但是有的人会误认为prop对象已被修改,故输出“Lucy”。其实在匿名函数中,properties[i]的值已经赋给了临时变量t,之后闭包对于外部变量的引用完全由t这个媒介来完成,因此prop传入以后并未发生任何属性的更改。

2.

1
2
3
4
5
function a (x) {
    return x * 2;
}
var a;
console.log(a);

这段代码中,其实var a并没有任何影响,输出的是a(x)这样的方法签名。

3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
c = 999;
var c = 888;
console.log(this.c); //①
function b (x, y, c) {
    c = 6;
    arguments[2] = 10;
    console.log(c); //②
    console.log(this.c); //③
    
    var c = 6;
    console.log(c); //④
    console.log(this.c); //⑤
}
b(1, 2, 3, 4);

这道题是比较变态的。

  • 第①处,this指的是window,在window下,c、this.c、var c在这里指的是同一个东西,看透这一点就好办了。打印的是888。
  • 第②处,方法体中,参数c和arguments[2]指的是同一个地址,所以把后者赋为10的时候,打印的是10,不是6。
  • 第③处,this指的是window,打印的是888。
  • 第④处,打印的是6。
  • 第⑤处,打印的是888。

4.

1
2
3
4
5
6
7
8
9
var start = new Date();
setTimeout(
    function(){
        var end = new Date();
        console.log(end - start);
    },
    1000
);
while(new Date() - start < 2000);

JavaScript因为是单线程工作的,因此虽然回调函数设置了1000毫秒后执行,事实上在1000毫秒的时候根本得不到执行,等待到while循环执行完毕后(因此已经是2000毫秒以后了),才去执行,因此输出应该是一个大于2000的数字。

5.

1
2
3
(function(){
    console.log(typeof arguments);
})();

很多人会说打印的是array,其实,typeof根本不会打印array的啊,打印的是object。

6.

1
2
function a(){return a;}
console.log(new a() instanceof a);

应该打印的是false,其实原因很简单,new a()的时候,因为return语句,得到的不是a的实例,而是a本身,a instanceof a当然是false啦。

最后,还有一个小题目是关于Function Invocation Pattern的,我在这篇文章里有写到,就不单独贴出来了。

文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》

http://www.raychase.net/1485

« 较早的 文章 较新的 文章 »

Copyright © 2024 优大网 浙ICP备13002865号

回到顶部 ↑