英媒晒国外名人收入 比尔·盖茨每天入账6000多万元

国际在线专稿:在各类媒体上看到哪个福布斯富豪又赚了多少钱时,可能并不会给人造成太大的冲击。不就是数字嘛,多加几个零就是了,数数谁不会啊?

但是,如果把这个数字换算成日薪甚至是时薪和自己对比的话,可以说就很扎心了…

英国《每日邮报》近日统计了多位富豪的日均收入以及花钱方式,一起来看看吧。

(并没有换算成小时单位,所以还请放心阅读)

比尔·盖茨

日均收入:710万英镑(约6215万人民币)

据彭博社报道,盖茨去年进账共26亿英镑(约227.7亿人民币),平均到每天就是710万英镑。

除此以外,作为盖茨基金会主席,盖茨本人能够调动的金钱量更大于他自身的收入……

花销:盖茨喜欢去冰岛度假,还常和家人一起驾游艇出游。

盖茨曾说过:“到了一定程度以后,金钱对于我个人就没什么用处了。现在我用钱的主要目的就是贡献给基金会,并将资源送到世界最穷苦的人们手中。”

J·K·罗琳

日均收入:19.8万英镑(约173.4万人民币)

作为《哈利波特》系列的作者,罗琳从其版税、电影、主题公园、各种纪念品以及舞台剧表演中获得巨大的收入,而她现在还在继续写作。

花销:罗琳和丈夫以及三个孩子一起住在爱丁堡,据说曾以百万英镑买下邻居的房子……

阿黛尔·阿德金斯

日均收入:14.4万英镑(约126万人民币)

阿黛尔的第三个专辑《25》全球共售出2000万份,仅在英国就帮她捞了1650万英镑(约1.44亿人民币)。

花销:在美国和英国多地拥有房产。

大卫·贝克汉姆

日均收入:13.6万英镑(约119.1万人民币)

小贝的肖像权公司去年给他开出了1270万英镑(约1.1亿人民币)的薪水,使用其形象打广告的商家遍布各种行业。

花销:小贝在科茨沃尔德的房子花了近六百万英镑(约5255万人民币),他的宝贝女儿哈珀(Harper)上芭蕾课也是一笔不小的花销。

英国女王

日均收入:11.7万英镑(约102.5万人民币)

英国政府会将皇室不动产利润中的15%给予女王,去年她因此获得的收入共有4280万英镑(约3.7亿人民币),近期预计还将增长。

花销:女王的各种度假在她总花销中其实所占比例不大,维护各个皇家宫殿的费用才是大头。

詹妮弗·劳伦斯

日均收入:4.9万英镑(约42.9万人民币)

尽管这位奥斯卡影后时常抱怨自己的收入不如一些男演员高,但她去年也有1820万英镑的收入(约1.59亿人民币)。

花销:在比弗利山庄的住宅价值540万英镑(约4728万人民币)。

 

解读Linux启动过程

转自:https://my.oschina.net/macwe/blog/1531024

解读Linux启动过程

 

1. 概述

本文解读一下从CPU加电自检到启动init进程的过程, 先通过下面这张图大致看一下Linux启动的整个过程。

本文的分析环境是GRUB 0.97 + Linux 2.6.18。

2. BIOS

CPU加电后首先工作在实模式并初始化CS:IP=FFFF:FFF0,BIOS的入口代码必须从该地址开始。BIOS完成相应的硬件检查并提供一系列中断服务例程,这些中断服务提供给系统软件访问硬件资源(比如磁盘、显示器等),最后选择一个启动盘加载第一个扇区(即:MBR,共512字节)数据到内存0x7C00处,并从这里开始执行指令(CS:IP=0000:7C00),对于笔者的电脑来说这就是GRUB的Stage1部分。

3. GRUB

GRUB的作用是bootloader,用来引导各种OS的。

3.1. Stage1

Stage1就是MBR,由BIOS把它从磁盘的0扇区加载到0x7c00处,大小固定位512字节,此时的CPU上下文如下:

eax=0011aa55 ebx=00000080 ecx=00000000 edx=00000080 esi=0000f4a0 edi=0000fff0
eip=00007c00 esp=00007800 ebp=00000000 iopl=0 nv up ei pl zr na po nc
cs=0000 ds=0000 es=0000 fs=0000 gs=0000 ss=0000 eflags=00000246
// 注: dl=启动磁盘号, 00H~7FH是软盘, 80H~FFH是硬盘。

因为只能是512字节,大小受限,它就干一件事,把Stage2的第一个512字节读取到0x8000,然后jmp到0x8000继续执行。

3.1.1. 读磁盘

磁盘扇区寻址有两种方式:

  • CHS方式:传统的方式,使用三元组(10位Cylinder, 8位Head, 6位Sector)来寻找扇区,最大只能找到(2^10) * (2^8) * (2^6) * 512 = 8GB的硬盘容量,现在的硬盘明显不够用了。
  • LBA方式:现在的方式,使用48位线性地址来寻找扇区,最大支持(2^48) * 512 = 128PB的硬盘空间。虽然机械上还是CHS的结构,不过磁盘的固件会自动完成LBA到CHS的转换。

因为CHS明显不适合现在的硬盘,所以LBA模式寻址是现在的PC的标配了吧!万一磁盘不支持LBA或者是软盘,需要我们手工转换成CHS模式。转换公式如下(就是三维空间定位一个点的问题):

磁道号C = LBA / 每磁道的扇区数SPT / 盘面总HPC
磁头号H = (LBA / 每磁道的扇区数SPT) mod HPC
扇区号S = (LBA mod SPT) + 1

判断是否支持LBA模式

/* check if LBA is supported */
movb	$0x41, %ah
movw	$0x55aa, %bx
int	$0x13

如果返回成功(CF=1)并且BX值是0xAA55表示支持LBA寻址(用Extensions方法)。

注意:3.5英寸软盘需要使用CHS方式寻址,它的CHS参数是80个柱面、2个磁头、每个磁道18个扇区,每扇区512字节,共1.44MB容量。

LBA模式读的功能号是AH=42h,DL参数是磁盘号,DS:SI参数是Disk Address Packet(DAP)结构体的内存地址,定义如下:

struct DAP {
    uint8_t sz; // 结构体大小
    uint8_t unused;
    uint16_t sector_cnt; // 需要都的扇区总数
    struct dst_addr { // 内存地址,读到这里
        uint16_t offset;
        uint16_t segment;
    };
    uint64_t lba_addr;  // 磁盘的LBA地址
};

参考:

  • https://en.wikipedia.org/wiki/Logical_block_addressing#CHS_conversion
  • https://en.wikipedia.org/wiki/INT_13H

3.2. Stage2

Stage2就是GRUB剩下的全部的代码了,包括BIOS中断服务的封装给C代码使用、键盘驱动、文件系统驱动、串口、网络驱动等等,它提供了一个小型的命令行环境,可以解析用户输入命令并执行对OS的启动。

3.2.1. start.S

首先Stage2的头512字节(start.S)被加载到0x8000,并在这里开始执行,此时的CPU上下文如下:

eax=00000000 ebx=00007000 ecx=00646165 edx=00000080 esi=00007c05 edi=0000fff0
eip=00008000 esp=00001ffe ebp=00000000 iopl=0 nv up ei pl zr na po nc
cs=0000 ds=0000 es=0800 fs=0000 gs=0000 ss=0000 eflags=00000246

start.S的工作是把Stage2的后续部分全部加载到内存中(从0x8200开始),有103KB大小。

3.2.2. asm.S

asm.S是0x8200处的代码,先看一下CPU上下文环境:

eax=00000e00 ebx=00000001 ecx=00646165 edx=00000080 esi=00008116 edi=000081e8
eip=00008200 esp=00001ffe ebp=000062d8 iopl=0 nv up ei pl zr na po nc
cs=0000 ds=0000 es=1ae0 fs=0000 gs=0000 ss=0000 eflags=00000246
3.2.2.1. 最开始的代码应该设置好段寄存器和栈
cli
/* set up %ds, %ss, and %es */
/* cs=0000 ds=0000 es=0000 fs=0000 gs=0000 ss=0000 */
xorw	%ax, %ax
movw	%ax, %ds
movw	%ax, %ss
movw	%ax, %es

/* set up the real mode/BIOS stack */
movl	$STACKOFF, %ebp
movl	%ebp, %esp
sti

此时:

cs=0000 ds=0000 es=0000 ss=0000 esp=00001ff0 ebp=00001ff0。
3.2.2.2. 保护模式和实模式

因为GRUB没有实现自己的中断服务,所以访问硬件资源还是使用BIOS的中断服务例程(实模式)。GRUB的命令行环境是工作在保护模式下的,所以当GRUB需要访问BIOS中断的时候需要切换回实模式,于是在GRUB执行过程中会有频繁的实模式和保护模式的互相切换操作,当切换回实模式后别忘了保存保护模式下的栈指针

(1) 实模式进入保护模式

/* transition to protected mode */
DATA32	call EXT_C(real_to_prot)

/* The ".code32" directive takes GAS out of 16-bit mode. */
.code32

下图是实模式到保护模式的切换步骤:

GRUB没有设置分页机制和新的中断,所以GRUB的保护模式访问的是物理内存且是不能使用INT指令,不过对于bootloader来说够用了。因为需要切换到保护模式栈,原来的返回地址要放到新的栈上,以保证能够正常ret:

ENTRY(real_to_prot)
	...
	/* put the return address in a known safe location */
	movl	(%esp), %eax
	movl	%eax, STACKOFF  ; 把返回地址保存起来备用

	/* get protected mode stack */
	movl	protstack, %eax
	movl	%eax, %esp
	movl	%eax, %ebp      ; 设置保护模式的栈

	/* get return address onto the right stack */
	movl	STACKOFF, %eax
	movl	%eax, (%esp)    ; 把返回地址重新放到栈上
	
	/* zero %eax */
	xorl	%eax, %eax

	/* return on the old (or initialized) stack! */
	ret                     ; 正常返回

(2) 保护模式切换回实模式

	/* enter real mode */
	call	EXT_C(prot_to_real)
	
	.code16

下图说明了保护模式切换回实模式的步骤:

保护模式的栈需要保存起来以便恢复现场,让C代码正确运行,实模式的栈每次都重置为STACKOFF即可,和(1)一样,也要设置好返回地址:

ENTRY(prot_to_real)
	...
	/* save the protected mode stack */
	movl	%esp, %eax
	movl	%eax, protstack  ; 把栈保存起来

	/* get the return address */
	movl	(%esp), %eax
	movl	%eax, STACKOFF   ; 返回地址放到实模式栈里

	/* set up new stack */
	movl	$STACKOFF, %eax  ; 设置实模式的栈
	movl	%eax, %esp
	movl	%eax, %ebp
	... 
3.2.2.3. 创建C运行时环境

C的运行环境主要包括栈、bss数据区、代码区。随着切换到保护模式,栈已经设置好了;随着Stage2从磁盘加载到内存,代码区和bss区都已经在内存了,最后还需要把bss区给初始化一下(清0),接下来即可愉快的执行C代码了。

3.2.2.4. 执行cmain()

先执行一个init_bios_info()获取BIOS的信息,比如被BIOS使用的内存空间(影响我们Linux映像加载的位置)、磁盘信息、ROM信息、APM信息,最后调用cmain()。 cmain()函数在stage2.c文件中,其中最主要的函数run_menu()是启动一个死循环来提供命令行解析执行环境。

3.2.2.5. load_image()

如果grub.cfg或者用户执行kenrel命令,会调用load_image()函数来将内核加载到内存中。至于如何加载linux镜像在Documentation的boot.txt和zero-page.txt有详细说明。

load_image()是一个非常长的函数,它要处理支持的各种内核镜像格式。Linux镜像vmlinuz文件头是struct linux_kernel_header结构体,该结构体里头说明了这个镜像使用的boot协议版本、实模式大小、加载标记位和需要GRUB填写的一些参数(比如:内核启动参数地址)。

  • 实模式部分:始终被加载到0x90000位置,并从0x90200开始执行(linux 0.11就这样做了)。
  • 保护模式部分:我们现在使用的内核比较大(大于512KB),叫做bzImage,加载到0x100000(高位地址,1MB)开始的位置,可以任意大小了。否则小内核zImage放在0x10000到mbi.mem_lower * 1024(一般是0x90000)区域。
3.2.2.6. linux_boot()

我们正常的启动过程调用的是big_linux_boot()函数,把实模式部分copy到0x90000后,设置其他段寄存器值位0x9000, 设置CS:IP=9020:0000开始执行(使用far jmp)。

至此GRUB的工作完成,接下来执行权交给Linux了。

4. setup.S

该文件在arch/i386/boot/setup.S,主要作用是收集硬件信息并进入保护模式head.S。初始的CPU上下文如下:

eax=00000000 ebx=00009000 ecx=00000000 edx=00000003 esi=002d8b54 edi=0009a000
eip=00000000 esp=00009000 ebp=00001ff0 iopl=0 nv up di pl zr na po nc
cs=9020 ds=9000 es=9000 fs=9000 gs=9000 ss=9000  eflags=00000046

4.1. 自身检查

先检查自己setup.S是否合法,主要是检查末尾的两个magic是否一致

# Setup signature -- must be last
setup_sig1:	.word	SIG1
setup_sig2:	.word	SIG2

4.2. 收集硬件信息

主要是通过BIOS中断来收集硬件信息。收集的信息包括内存大小、键盘、鼠标、显卡、硬盘、APM等等。收集的硬件信息保存在0x9000处:

# 设置ds = 0x9000,用来保存硬件信息
movw	%cs, %ax			# aka SETUPSEG
subw	$DELTA_INITSEG, %ax 		# aka INITSEG
movw	%ax, %ds

这里看一下如何获取内存大小,这样OS才能进行内存管理。这里用三种方法获取内存信息:

  1. e820h:请求中断INT 15H,AX=E820H时返回可用的物理内存信息,e820由此得名,参考http://www.uruk.org/orig-grub/mem64mb.html。由于内存的使用是不连续的,通过连续调用INT 15H得到所有可用的内存区域,每次查询得到的结果ES:DI是个struct address_range_descriptor结构体,返回的结果都是64位的,完全能够满足目前PC的需求了。
     struct address_range_descriptor {
     	uint32_t base_addr_low;   // 起始物理地址
     	uint32_t base_addr_high;
     	uint32_t length_low;      // 长度
     	uint32_t length_high;
     	uint8_t type;             // 1=OS可用的, 2=保留的,OS不可用
     };
    
  2. e801h:通过请求中断INT15h,AX=e801H返回结果,最高只能得到4GB内存结果。
  3. 88h:古老的办法,通过请求中断INT15h,AH=88H返回结果。最高只能得到16MB或者64MB的内存,现在的电脑不适用了。

扩展阅读:http://wiki.osdev.org/Detecting_Memory_(x86)#E820h

4.3. 启用A20

让CPU访问1MB以上的扩展内存,否则访问的是X mod 1MB的地址。下面列举三种开启A20的方法:

  1. 使用I/0端口92H,AL的将1-bit置1
     inb	$0x92, %al			# Configuration Port A
     orb	$0x02, %al			# "fast A20" version
     andb	$0xFE, %al			# don't accidentally reset
     outb	%al, $0x92
    
  2. 使用BIOS中断INT 0x15, AX=0x2401
     movw	$0x2401, %ax
     pushfl					# Be paranoid about flags
     int	$0x15
     popfl
    
  3. 使用键盘控制器
     movb	 $0xD1, %al			# command write
     outb	 %al, $0x64
     call	 empty_8042
    
     movb	 $0xDF, %al			# A20 on
     outb	 %al, $0x60
     call	 empty_8042
    

4.4. 进入保护模式

4.4.1. 临时的GDT和IDT

这里的IDT全部是0;Linux目前使用的GDT如下:

gdt:
	.fill GDT_ENTRY_BOOT_CS,8,0

	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
	.word	0				# base address = 0
	.word	0x9A00				# code read/exec
	.word	0x00CF				# granularity = 4096, 386
						#  (+5th nibble of limit)

	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
	.word	0				# base address = 0
	.word	0x9200				# data read/write
	.word	0x00CF				# granularity = 4096, 386
						#  (+5th nibble of limit)
gdt_end:

这里只定义了两个DPL为0的代码段和数据段,只给内核使用的。

4.4.1. 设置CR0.PE

这里使用lmsw指令,它和mov cr0, X是等价的

movw	$1, %ax				# protected mode (PE) bit
lmsw	%ax				# This is it!
jmp	flush_instr

4.5. 调转到head.S(CS:EIP=0x10:100000)

至此硬件信息就收集完成,这些收集到的硬件信息都保存在0x90000处,后续OS可以使用这些硬件信息来管理了。

5. head.S

该文件位于arch/i386/kernel/head.S,这个是内核保护模式的代码的起点,笔者电脑的位置在0x100000,此时CPU上下文是:

eax=00000001 ebx=00000000 ecx=0000ff03 edx=47530081 esi=00090000 edi=00090000
eip=00100000 esp=00008ffe ebp=00001ff0 iopl=0 nv up di pl nz na pe nc
cs=0010 ds=0018 es=0018 fs=0018 gs=0018 ss=0018               eflags=00000002

注:已经进入保护模式,CS的值是GDT表项的索引。

它的作用就是设置真正的分段机制和分页机制、启动多处理器、设置C运行环境,最后执行start_kernel()函数。

5.1. startup_32

5.1.1. 加载临时的分段机制

boot_gdt_table就是临时的GDT,其实和start.S的一样:

	lgdt boot_gdt_descr - __PAGE_OFFSET
	movl $(__BOOT_DS),%eax
	movl %eax,%ds
	movl %eax,%es
	movl %eax,%fs
	movl %eax,%gs

ENTRY(boot_gdt_table)
	.fill GDT_ENTRY_BOOT_CS,8,0
	.quad 0x00cf9a000000ffff	/* kernel 4GB code at 0x00000000 */
	.quad 0x00cf92000000ffff	/* kernel 4GB data at 0x00000000 */

5.1.2. 初始化内核bss区和内核启动参数

为了让C代码正常运行,bss区全部清0,启动参数需要移动到boot_params位置。

5.1.3. 启动临时分页机制

临时的页表,只要能够满足内核使用就行。页目录表是swapper_pg_dir,它是一个4096大小的内存区域,默认全是0。一般__PAGE_OFFSET=0xC0000000(3GB),这是要把物理地址0x00000000映射到0xc0000000的地址空间(内核地址空间)。下面是页目录表和页表的初始化代码:

page_pde_offset = (__PAGE_OFFSET >> 20); // 3072,页目录的偏移

	// 页目录表存放在pg0位置,arch/i386/kernel/vmlinux.lds中定义
	movl $(pg0 - __PAGE_OFFSET), %edi
	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx  // edx是页目录表的地址
	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
10:
	// 创建一个页目录项
	leal 0x007(%edi),%ecx			/* Create PDE entry */
	movl %ecx,(%edx)			/* Store identity PDE entry */
	movl %ecx,page_pde_offset(%edx)		/* Store kernel PDE entry */
	addl $4,%edx   // 指向swapper_pg_dir的下一个项
	movl $1024, %ecx   // 每个页表1024个项目
11:
	stosl  // eax -> [edi]; edi = edi + 4
	addl $0x1000,%eax // 每次循环,下一个页目录项
	loop 11b
	/* End condition: we must map up to and including INIT_MAP_BEYOND_END */
	/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
	leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp  // 页表覆盖到这里就终止
	cmpl %ebp,%eax
	jb 10b
	movl %edi,(init_pg_tables_end - __PAGE_OFFSET)

下面是对上面代码的翻译(这样更有利于理解):

extern uint32_t *pg0;  // 初始值全0
extern uint32_t *swapper_pg_dir;  // 初始值全0

void init_page_tables()
{
	uint32_t PAGE_FLAGS = 0x007; // PRESENT+RW+USER
	uint32_t page_pde_offset = (_PAGE_OFFSET >> 20); // 3072
	uint32_t addr = 0 | PAGE_FLAGS;  // 内存地址+页表属性
	uint32_t *pg_dir_ptr = swapper_pg_dir; // 页目录表项指针
	uint32_t *pg0_ptr = pg0;  // 页表项指针
	
	for (;;) {
		// 设置页目录项,同时映射两个地址,让物理地址和虚拟地址都能访问,
		*pg_dir_ptr = pg0 | PAGE_FLAGS;     // 0, 1
		*(uint32_t *)((char *)pg_dir_ptr + page_pde_offset) = pg0 | PAGE_FLAGS;  // 768, 769
		pg_dir_ptr++;
		
		// 设置页表项目
		for (int i = 0; i < 1024; i++) {
			*pg0++ = addr;
			addr += 0x1000;
		}
		// 退出条件,实际上只映射了两个页目录就退出了(0,1,768, 769)
		if (pg0[INIT_MAP_BEYOND_END] | PAGE_FLAGS) >= addr) {
			init_pg_tables_end = pg0_ptr;
			return;
		}
	}	
};

5.1.4. 设置栈

/* Set up the stack pointer */
	lss stack_start,%esp

ENTRY(stack_start)
	.long init_thread_union+THREAD_SIZE
	.long __BOOT_DS

/* arch/i386/kernel/init_task.c
* Initial thread structure.
*
* We need to make sure that this is THREAD_SIZE aligned due to the
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
union thread_union init_thread_union 
	__attribute__((__section__(".data.init_task"))) =
		{ INIT_THREAD_INFO(init_task) };

内核最初使用的栈是init_task进程的,也就是0号进程的栈,这个进程是系统唯一一个静态定义而不是通过fork()产生的进程。

5.1.5. 设置真正的IDT和GDT

	lgdt cpu_gdt_descr   // 真正的GDT
	lidt idt_descr    //真正的IDT
	ljmp $(__KERNEL_CS),$1f   // 重置CS
1:	movl $(__KERNEL_DS),%eax	# reload all the segment registers
	movl %eax,%ss			# after changing gdt.  // 重置SS

	movl $(__USER_DS),%eax		# DS/ES contains default USER segment
	movl %eax,%ds
	movl %eax,%es

	xorl %eax,%eax			# Clear FS/GS and LDT
	movl %eax,%fs
	movl %eax,%gs
	lldt %ax
	cld			# gcc2 wants the direction flag cleared at all times
	// push一个假的返回地址以满足 start_kernel()函数return的要求
	pushl %eax		# fake return address  

对于IDT先全部初始化成ignore_int例程:

setup_idt:
	lea ignore_int,%edx
	movl $(__KERNEL_CS << 16),%eax
	movw %dx,%ax		/* selector = 0x0010 = cs */
	movw $0x8E00,%dx	/* interrupt gate - dpl=0, present */

	lea idt_table,%edi
	mov $256,%ecx
rp_sidt:
	movl %eax,(%edi)
	movl %edx,4(%edi)
	addl $8,%edi
	dec %ecx
	jne rp_sidt
	ret

ignore_int例程就干一件事,打印一个错误信息"Unknown interrupt or fault at EIP %p %p %p\n"

对于GDT我们最关心的__KERNEL_CS、__KERNEL_DS、__USER_CS、__USER_DS这4个段描述符:

.quad 0x00cf9a000000ffff	/* 0x60 kernel 4GB code at 0x00000000 */
.quad 0x00cf92000000ffff	/* 0x68 kernel 4GB data at 0x00000000 */
.quad 0x00cffa000000ffff	/* 0x73 user 4GB code at 0x00000000 */
.quad 0x00cff2000000ffff	/* 0x7b user 4GB data at 0x00000000 */

至此分段机制、分页机制、栈都设置好了,接下去可以开心的jmp start_kernel了。

6. start_kernel

该函数在linux/init/main.c文件里。我们可以认为start_kernel是0号进程init_task的入口函数,0号进程代表整个linux内核且每个CPU有一个。 这个函数开始做一系列的内核功能初始化,我们重点看rest_init()函数。

6.1.rest_init

这是start_kernel的最后一行,它启动一个内核线程运行init函数后就什么事情也不做了(死循环,始终交出CPU使用权)。

static void noinline rest_init(void)
{
	kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); // 启动init
	……
	/* Call into cpu_idle with preempt disabled */
	cpu_idle();  // 0号进程什么事也不做
}

6.2. init()

该函数的末尾fork了”/bin/init”进程。这样1号进程init就启动了,接下去就交给init进程去做应用层该做的事情了!

// 以下进程启动后父进程都是0号进程
if (ramdisk_execute_command) {
	run_init_process(ramdisk_execute_command);
	printk(KERN_WARNING "Failed to execute %s\n",
			ramdisk_execute_command);
}

/*
 * We try each of these until one succeeds.
 *
 * The Bourne shell can be used instead of init if we are 
 * trying to recover a really broken machine.
 */
if (execute_command) {
	run_init_process(execute_command);
	printk(KERN_WARNING "Failed to execute %s.  Attempting "
				"defaults...\n", execute_command);
}
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

附录1. 启动多核CPU

以上解读的内容只在0号CPU上执行,如果是多CPU的环境,还要初始化其他的CPU。多CPU启动的起点是start_kernel()->rest_init()>init()->smp_init()。而smp_init()函数给每个CPU上调用cpu_up()do_boot_cpu()函数,每个CPU都要再走一遍head.S的流程,然后启动自己的idle进程(内核态0号进程)。

附录2. x64的不同

i386和x64的启动代码主要区别在head.S中。

  • 页表格式不同,i386使用两级页表,x64使用4级页表。
  • 多了兼容32位的代码段和数据段__USER32_CS、__USER32_DS和__KERNEL32_CS
  • x64段寄存器用法和i386的不同:x64下面CS、DS、ES、SS不用了,始终为0。而FS、GS寄存器的用法倒像是实模式下的,主要考虑是保留两个作为基地址好让线性地址计算方便。FS:XX = MSR_FS_BASE + XXGS:XX = MSR_GS_BASE + XX, 不是段描述符索引了(像实模式的分段)。

J2EE框架 Spring

J2EE框架 Spring 推荐

J2EE框架 面向方面AOP/IoC Web框架
Apache
Java
跨平台

Spring Framework 是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最初由 Rod Johnson 和 Juergen Hoeller等开发。Spring Framework 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。

Spring 中包含的关键特性:

  • 强大的基于 JavaBeans 的采用控制翻转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组建更加快捷简易。
  • 一个可用于从 applet 到 Java EE 等不同运行环境的核心 Bean 工厂。
  • 数据库事务的一般化抽象层,允许宣告式(Declarative)事务管理器,简化事务的划分使之与底层无关。
  • 内建的针对 JTA 和 单个 JDBC 数据源的一般化策略,使 Spring 的事务支持不要求 Java EE 环境,这与一般的 JTA 或者 EJB CMT 相反。
  • JDBC 抽象层提供了有针对性的异常等级(不再从SQL异常中提取原始代码), 简化了错误处理, 大大减少了程序员的编码量. 再次利用JDBC时,你无需再写出另一个 ‘终止’ (finally) 模块. 并且面向JDBC的异常与Spring 通用数据访问对象 (Data Access Object) 异常等级相一致.
  • 以资源容器,DAO 实现和事务策略等形式与 Hibernate,JDO 和 iBATIS SQL Maps 集成。利用众多的翻转控制方便特性来全面支持, 解决了许多典型的Hibernate集成问题. 所有这些全部遵从Spring通用事务处理和通用数据访问对象异常等级规范.
  • 灵活的基于核心 Spring 功能的 MVC 网页应用程序框架。开发者通过策略接口将拥有对该框架的高度控制,因而该框架将适应于多种呈现(View)技术,例如 JSP,FreeMarker,Velocity,Tiles,iText 以及 POI。值得注意的是,Spring 中间层可以轻易地结合于任何基于 MVC 框架的网页层,例如 Struts,WebWork,或 Tapestry。
  • 提供诸如事务管理等服务的面向方面编程框架。

在设计应用程序Model时,MVC 模式(例如Struts)通常难于给出一个简洁明了的框架结构。Spring却具有能够让这部分工作变得简单的能力。程序开发员们可以使用Spring的 JDBC 抽象层重新设计那些复杂的框架结构。

雨中的旋律

《雨中的旋律》(Rhythm of the Rain)是欧美经典歌曲,由瀑布合唱团演唱。

英文歌词

Rhythm of the Rain
Listen to the rhythm of the falling rain,
Telling me just what a fool I’ve been.
I wish that it would go and let me cry in vain,
And let me be alone again.
The only girl I care about has gone away.
Looking for a brand new start!
But little does she know that when she left that day.
Along with her she took my heart.
Rain, please tell me now. Does that seem fair for her
To steal my heart away when she don’t care
I can’t love another, when my heart’s somewhere far away.
The only girl I care about has gone away.
Looking for a brand new start!
But little does she know that when she left that day.
Along with her she took my heart.
Rain, won’t you tell her that I love her so
Please ask the sun to set her heart aglow
Rain in her heart and let the love we knew start to grow.
Listen to the rhythm of the falling rain,
Telling me just what a fool I’ve been.
I wish that it would go and let me cry in vain,
And let me be alone again.
Oh, listen to the falling rain–pitter-patter…

歌词大意

听那淅淅沥沥的雨声,它好像在说,我是个傻瓜。 我真希望雨停下来。 让我无望地哭泣, 让我再次孤身单影。
我唯一在乎的姑娘已经离去, 去寻找她的新生活。 然而,她不知道, 当她离去的那天, 也将我的心带走。
雨呀,请告诉我,那样公平吗?她偷走了我的心, 居然毫不在乎。 我无法再爱别人, 我的心已远远漂向异地。
雨呀,你就不能告诉她 我多么地爱她, 请让太阳燃起她心中的爱苗, 让雨滋润她的心田。 让我们爱情之花重新盛开。
哦,听那雨声, 噼哩啪啦。
歌词、句型分析
1、Listen to the rhythm Of the falling rain,telling me just what a fool I have been.
= As I listen to the rhythm of the falling rain, it seems that it is telling me that I’ve been a stupid guy.
听那淅淅沥沥的雨声,它好像在说,我是个傻瓜。
2、I wish that it would go and let me cry in vain….
=I wish that the rain would stop and let me cry in vain…
我真希望雨停下来,让我无望地哭泣,
in vain 徒然,白费,无效,徒劳的
eg: All our efforts were in vain, which made us very angry.
我们所有的努力都白费了,真令人生气。
3、The only girl I care about has gone away, looking for a brand-new start!
=The only girl that I love has left me and is looking for a new life!
我唯一在乎的姑娘已经离去,去寻找她的新生活。
Care about 喜欢,在乎
eg: She doesn’t care about being ladylike
她不在乎淑女仪态
brand-new a. 全新的
eg: Peter is showing off his brand-new motorcycle to his friends
彼得正在对他的朋友们炫耀他的新摩托车。
4、But little does she know that when she left that day,along with her she took my heart.
=But she doesn’t know that when she left that day,she also took my heart with her.
然而,她不知道,当她离去的那天,也将我的心带走。
But little does she know…此为否定倒装句型。
eg: He was hardly able to tell right from wrong
=Hardly was he able to tell right from wrong

中文版

(红苹果演唱)
歌词:
大雨哗啦啦淋湿我的梦
你我曾经相遇在雨中
那青春年少无知可爱的笑容
像雨后美丽的彩虹
等大雨再次击醒你我的美梦
你却消失无影踪
等心中攒成点点滴滴的感动
有星光闪烁在夜空
也许你我生来太轻松
初恋故事短暂而冲动
我也幻想成为你的大英雄 谁能够
等大雨再次击醒你我的美梦
你却消失无影踪
等心中攒成点点滴滴的感动
有星光闪烁在夜空
等大雨再次击醒你我的美梦
你却消失无影踪
等心中攒成点点滴滴的感动
有星光闪烁在夜空
也许你我生来太轻松
初恋故事短暂而冲动
我也幻想成为你的大英雄 谁能够
噢 听那大雨还在下
哗啦啦啦哗啦啦啦噢
啦啦啦啦啦啦还在下
啦啦啦啦啦啦啦.
啦啦啦啦还在下.
啦啦啦啦啦啦啦
噢 听那大雨还在下
啦啦啦啦啦啦啦啦噢
啦啦啦啦啦啦还在下

卡巴斯基悲催:美国全力封杀全球第一杀软

虽然在AV-TEST最新杀软评测中,卡巴斯基得到了满分成为第一,但美国依然不允许它出现在政府采购名录中,而这个封杀的事态还在加剧。

据外媒CNET报道称,除了美国的政府机构外,FBI也在悄悄暗示那些私营机构停止使用卡巴斯基,情况十分严重。

报道中提到,能源行业以及使用工业控制系统等企业,都在被警告的名单中,而按照美国的意思,就是先让该国企业尽可能快的从其系统中移除卡巴斯基。

虽然卡巴严正否认自己进行涉嫌收集不法信息的“间谍”活动,甚至可以交出软件源代码,但目前的情况是,这丝毫没有打动当局控制者,而消息中还透露,俄罗斯也正努力移除美国科技公司如微软的操作系统。

对于微软来说,这件事他们暗地里非常开心,因为这样可以让更多的用户来换用Windows Defender,尤其是随着创意者更新全面升级的“新安全中心”。

来自:驱动之家

转自:https://www.oschina.net/news/87919/kaspersky-banned-by-american-government

据说只有程序员才能看懂的时钟 [转]

据说只有程序员才能看懂的时钟,你看明白了吗?

最近发现一个关于程序员的“数学钟”,也就是非常流行的下面这幅图:

以前,只知道其中十一个点钟的分析;对于3点钟,一直没有思路。于是发了一条朋友圈,求助大神解释其中的3点钟。在刘梓溪、贾顾森、黎鸣等大神的指导下,明白了其中是怎么回事。所以这里介绍下这十二个点,应该如何解释。个人观点,仅供参考。

12点

不用说了,1728的立方根。

1点

可能很多人不大知道,这是勒让德常数:

勒让德常数

其中的π(x)表示不大于x的素数的个数,可以用近似。

这个值经过勒让德、高斯等一批数学大佬的努力,最后被数学家Charles Jean证明为1。

2点

无穷递缩等比级数的求和,首项为1,公比为1/2,所以它的和为

3点

在刘梓溪、贾顾森、黎鸣等大神的帮助下,终于知道了。

广泛用于XML、HTML中。&#后面接十进制字符,&#x后面接十六进制字符。相当于转义序列吧。

其中十六进制33,等于十进制51,即’3’。

4点

同余问题(Modular Multiplicative Inverse)

5点

ϕ表示黄金分割比,

黄金分割比在斐波那契数列的通项公式中出现。

不过这个地方,我没搞懂,不知道这是不是这幅图作者的笔误?个人认为应该是 而不是 

6点

不用说了,阶乘。

7点

表示6.999999999…其中9的头上一横,表示循环节是9。

那么,6.9999….为什么等于7呢?恩,还是无穷递缩等比级数的视角来考虑,就老少皆宜了。

6.9999…= 6 + 0.9 + 0.09 + 0.009 + 0.0009 + …

后面的那个,

0.9 + 0.09 + 0.009 + 0.0009 + …

首项为0.9,公比为0.1,收敛于1。

因此6.9999… = 7

8点

代表1000(二进制),因为只有第一个是亮的,其他是暗的。(亮为1,暗为0,bitmap的感觉。可能是盲文),因此为8。

9点

四进制。21(四进制) = 2 * 4 + 1 = 9。

10点

组合数,5! /(2! * 3!) = 10

11点

十六进制,A是10,B是11,C是12。注意,注意,这里是0x0B,不是0x08。哈哈。

点评:知识点有点重复,比如进制就有好几个。

来源:程序师

原标题:程序员的时钟

原文:https://www.oschina.net/news/87686/programmer-clock

IceGrid应用配置[转]

1.  概述1.1 配置目标

本文档是描述Ice中间件中的IceGrid服务的应用配置,通过使用IceGrid服务来实现:

1.  服务器端服务分布式部署。

2.  服务器端服务按需激活。

3.  服务器端服务多节点负载均衡。

4.  注册服务主/从热备(Master/Slaves)

5.  集成IceBox服务

1.2 实验环境

1.  硬件:hp服务器,3台

2.  操作环境:Red Hat 5

3.  服务器程序:ServerApp.jar

4.  说明:实际应用中,服务器节点可任意扩充、操作系统可被更换、服务器程序可用实际项目的服务程序替换,本文档所描述的配置方式具有通用性,适用但不局限于当前实验环境。

1.3 局限

本文档不详细描述IceGrid服务的运行机制和实现原理,不详细介绍服务器端和客户端程序的实现,主要描述IceGrid服务应用的配置步骤、主要配置项及验证配置结果等。

2.  配置过程

2.1  服务器端配置

配置步骤:

1.  创建主注册服务(Master)的配置文件config_master.grid,文件名称可以任意

2.  创建从注册服务(Slave)的配置文件 config_slave.grid, 文件名称可以任意

3.  创建各节点服务的配置文件config.node,文件名称可以任意

4.  创建分布式应用配置文件app.xml,文件名称可以任意,但格式最好定义成xml

5.  运行Ice提供的工具,启动我们的分布式应用,主要有如下两个工具:icegridnode和icegridadmin。详细启动过程如下:

1) icegridnode–Ice.Config=config_master.grid  启动主注册服务

2) icegridnode–Ice.Config=config_slave.grid  启动从注册服务

3) icegridadmin–Ice.Config= config_master.grid -e “application add app.xml”   部署分布式服务

icegridadmin –Ice.Config= config_master.grid-e “application update app.xml”  重新部署分布式服务

4) icegridnode–Ice.Config=config.node  将各节点注册到注册服务的注册表中

配置文件清单:

假设有n个节点(n > 0), 其中从注册服务有x个,(x > 0)

config_master.grid   ———- 主注册服务配置文件 ———  1份

config_slave.grid   ———– 从注册服务配置文件 ———  x份

config.node  —————– 节点配置文件  ————–  n份

app.xml ———————- 部署配置文件  ————–  1份

通常情况下,由于注册服务占用资源很少,所以一般都会和一个节点集成在一起,并且可以和节点服务在一个进程中运行。因此,如果假设服务部署到n个服务器,通常情况下配置文件清单如下:

config_master.grid– 主注册服务配置文件 — 1份  — 主注册服务信息+节点信息

config_slave.grid— 从注册服务配置文件 — x份  — 从注册服务信息+节点信息

config.node——— 节点配置文件 —- n-1-x份  — 节点信息

app.xml————- 部署配置文件 ——– 1份  — 部署信息

其中app.xml要和config_master.grid放在一台服务器上,下面的各章节将详细介绍各配置文件。

2.1.1  主注册服务配置

config_master.grid的内容:

#

# The IceGrid InstanceName

#

IceGrid.InstanceName=IceGridRDDataSource    # 1

 

#

# The IceGridlocator proxy.

#

Ice.Default.Locator=IceGridRDDataSource/Locator:default-h 10.0.5.201 -p 12000:default -h 10.0.5.202-p 12000         #2

 

#

# IceGridregistry configuration.

#

IceGrid.Registry.Client.Endpoints=default-p 12000   #3

IceGrid.Registry.Server.Endpoints=default    #4

IceGrid.Registry.Internal.Endpoints=default   #5

IceGrid.Registry.Data=master      #6

IceGrid.Registry.PermissionsVerifier=IceGridRDDataSource/NullPermissionsVerifier     #7

IceGrid.Registry.AdminPermissionsVerifier=IceGridRDDataSource/NullPermissionsVerifier#8

IceGrid.Registry.SSLPermissionsVerifier=IceGridRDDataSource/NullSSLPermissionsVerifier#9

IceGrid.Registry.AdminSSLPermissionsVerifier=IceGridRDDataSource/NullSSLPermissionsVerifier    #10

 

#

# IceGrid SQLconfiguration if using SQL database.

#

#Ice.Plugin.DB=IceGridSqlDB:createSqlDB     #11

#IceGrid.SQL.DatabaseType=QSQLITE      #12

#IceGrid.SQL.DatabaseName=register/Registry.db       #13

#

 

#

#Ice Error andStandard output Set

#

#Ice.StdErr=master/stderr.txt                  #14

#Ice.StdOut= master/stdout.txt    #15

 

#

#Trace Registryproperties

#

Ice.ProgramName=Master     #16

IceGrid.Registry.Trace.Node=3        #17

IceGrid.Registry.Trace.Replica=3    #18

 

#

# IceGrid nodeconfiguration.

#

IceGrid.Node.Name=node_1                              #19

IceGrid.Node.Endpoints=default                         #20

IceGrid.Node.Data=node_1               #21

IceGrid.Node.CollocateRegistry=1                      #22

#IceGrid.Node.Output=node_1            #23

#IceGrid.Node.RedirectErrToOut=1         #24

 

# Traceproperties.

#

IceGrid.Node.Trace.Activator=1             #25

#IceGrid.Node.Trace.Adapter=2             #26

#IceGrid.Node.Trace.Server=3              #27

 

#

# Dummy usernameand password for icegridadmin.

#

IceGridAdmin.Username=mygrid           #28

IceGridAdmin.Password=mygrid            #29

配置项说明:

#1 为这个应用实例指定一个唯一的标识

# 2  注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到

# 3  客户端访问注册服务器的端点信息

# 4  服务访问注册服务器的端点信息,通常是default

# 5  内部访问端点信息,通常是default,节点用这个端口和注册服务通信

# 6  注册服务的数据目录的路径

# 7  设定防火墙安全代理,从而控制客户端访问注册表时可用的权限

# 8  设定防火墙安全代理,从而控制注册表管理者可用的权限

# 9  设定SSL安全代理,从而设定客户端访问注册表时的SSL安全访问机制

# 10  设定SSL安全代理,从而设定注册表管理者的SSL安全访问机制

# 11  指定Ice对象序列化的机制,如果不设置,默认用Freeze机制

# 12  指定使用数据库的类型

#13  指定使用数据库的名称

#14  指定标准错误输出文件

#15  指定标准输出文件

#16  指定主注册服务的名称

#17  指定主注册服务跟踪节点信息的级别(0~3),默认为0

#18  指定主/从热备注册服务的跟踪级别(0~3),默认为0

# 19  定义节点的名称,必须唯一

# 20 节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default

# 21  节点的数据目录的路径

# 22  定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置

# 23  节点标准输出信息重定向蹈的目录路径,会自动生成输出文件

# 24  节点上的服务程序的标准错误重定向到标准输出

# 25  激活器跟踪级别,通常有0,1,2,3级,默认是0

# 26  对象适配器跟踪级别,通常有0,1,2,3级,默认是0

# 27  服务跟踪级别,通常有0,1,2,3级,默认是0

# 28  IceGrid管理器登录该应用的用户名

# 29  IceGrid管理器登录该应用的密码

未涉及的属性还有一些,如果需要请参考官方文档。

2.1.2  从注册服务配置

config_slave.grid的内容:

 

#

# The IceGridlocator proxy.

#

Ice.Default.Locator=IceGridRDDataSource/Locator:default-h 10.0.2.241 -p 12000:default -h 10.0.2.242-p 12000         #1

 

#

# IceGridregistry configuration.

#

IceGrid.Registry.Client.Endpoints=default-p 12000   #2

IceGrid.Registry.Server.Endpoints=default    #3

IceGrid.Registry.Internal.Endpoints=default   #4

IceGrid.Registry.Data=slave_1        #5

IceGrid.Registry.ReplicaName=slave_1   #6

IceGrid.Registry.PermissionsVerifier=IceGridRDDataSource/NullPermissionsVerifier     #7

IceGrid.Registry.AdminPermissionsVerifier=IceGridRDDataSource/NullPermissionsVerifier#8

IceGrid.Registry.SSLPermissionsVerifier=IceGridRDDataSource/NullSSLPermissionsVerifier#9

IceGrid.Registry.AdminSSLPermissionsVerifier=IceGridRDDataSource/NullSSLPermissionsVerifier    #10

 

#

# IceGrid SQLconfiguration if using SQL database.

#

#Ice.Plugin.DB=IceGridSqlDB:createSqlDB     #11

#IceGrid.SQL.DatabaseType=QSQLITE      #12

#IceGrid.SQL.DatabaseName=register/Registry.db       #13

#

 

#

#Ice Error andStandard output Set

#

#Ice.StdErr=slave_1/stderr.txt                 #14

#Ice.StdOut=slave_1/stdout.txt     #15

 

#

#Trace Registryproperties

#

Ice.ProgramName=Slave_1     #16

IceGrid.Registry.Trace.Node=3        #17

IceGrid.Registry.Trace.Replica=3    #18

 

#

# IceGrid nodeconfiguration.

#

IceGrid.Node.Name=node_2                              #19

IceGrid.Node.Endpoints=default                         #20

IceGrid.Node.Data=node_2               #21

IceGrid.Node.CollocateRegistry=1                      #22

#IceGrid.Node.Output=node_2            #23

#IceGrid.Node.RedirectErrToOut=1         #24

 

# Traceproperties.

#

IceGrid.Node.Trace.Activator=1             #25

#IceGrid.Node.Trace.Adapter=2             #26

#IceGrid.Node.Trace.Server=3              #27

 

#

# Dummy usernameand password for icegridadmin.

#

IceGridAdmin.Username=mygrid           #28

IceGridAdmin.Password=mygrid            #29

配置项说明:

其实这个文件和主注册配置文件基本一样,差别只有一点:

1.       没有指定应用实例名,因为在主注册服务中已经有了定义

2.       多了第6行,IceGrid.Registry.ReplicaName=slave_1,指定从注册服务的名称

其它的基本就没有差别了,大部分属性项在config_master.grid里面都有定义,为了方便阅读,下面也将用到的各项给出说明:

# 1  注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到

# 2  客户端访问注册服务器的端点信息

# 3  服务访问注册服务器的端点信息,通常是default

#4  内部访问端点信息,通常是default,节点用这个端口和注册服务通信

# 5  注册服务的数据目录的路径

# 6  指定从注册服务的名称

# 7  设定防火墙安全代理,从而控制客户端访问注册表时可用的权限

#8  设定防火墙安全代理,从而控制注册表管理者可用的权限

# 9  设定SSL安全代理,从而设定客户端访问注册表时的SSL安全访问机制

#10  设定SSL安全代理,从而设定注册表管理者的SSL安全访问机制

# 11  指定Ice对象序列化的机制,如果不设置,默认用Freeze机制

# 12  指定使用数据库的类型

#13  指定使用数据库的名称

#14  指定标准错误输出文件

#15  指定标准输出文件

#16  指定从注册服务运行时程序名称

#17  指定从注册服务跟踪节点信息的级别(0~3),默认为0

#18  指定主/从热备注册服务的跟踪级别(0~3),默认为0

# 19  定义节点的名称,必须唯一

# 20  节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default

# 21  节点的数据目录的路径

# 22  定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置

# 23  节点标准输出信息重定向蹈的目录路径,会自动生成输出文件

# 24  节点上的服务程序的标准错误重定向到标准输出

# 25  激活器跟踪级别,通常有0,1,2,3级,默认是0

# 26  对象适配器跟踪级别,通常有0,1,2,3级,默认是0

# 27  服务跟踪级别,通常有0,1,2,3级,默认是0

# 28  IceGrid管理器登录该应用的用户名

# 29  IceGrid管理器登录该应用的密码

2.1.3  应用部署配置

app.xml配置文件内容:

1<icegrid>

2  <application name=“RTDSSystem”>

3    <server-template id=“RTDSSystemServer”>

4      <parameter name=“index”/>

5      <server id=“RTDSSystemServer-${index}”exe=Java                                          activation=“on-demand”>

6        <adapter name=“RTDataSysytem” endpoints=“tcp”                                          replica-group=“ReplicatedRTDataSysytemAdp”/>

7        <option>-jar</option>

8        <option>ServerApp.jar</option>

9      </server>

10    </server-template>

11

12    <replica-group id=“ReplicatedRTDataSysytemAdp”>

13      <load-balancing type=“round-robin”/>

14      <object identity=“RTDataSource”                                                      type=“::RTDataSystem::RTDataSource”/>

15    </replica-group>

16

17    <node name=“node_1”>

18      <server-instance template=“RTDSSystemServer” index=“1”/>

19      <server-instance template=“RTDSSystemServer” index=“11”/>

20      <server-instance template=“RTDSSystemServer” index=“111”/>

21    </node>

22    <node name=“node_2”>

23      <server-instance template=“RTDSSystemServer” index=“2”/>

24      <!–server-instancetemplate=”RTDSSystemServer” index=”22″/–>

25      <!–server-instancetemplate=”RTDSSystemServer” index=”222″/–>

26    </node>

27    <node name=“node_3”>

28      <server-instance template=“RTDSSystemServer” index=“3”/>

29      <!–server-instancetemplate=”RTDSSystemServer” index=”33″/–>

30      <!–server-instancetemplate=”RTDSSystemServer” index=”333″/–>

31    </node>

32  </application>

33</icegrid>

配置文件结构分析:

IceGrid里,部署是一个在注册服务中表述一个应用(Application)的过程,而部署配置文件就是来描述这些配置信息的文件,这个配置文件是用xml标记性语言来描述的。通常一个部署应该包含如下信息:

1.  应用标签(application),name属性定义这个应用的名字

2.  服务(server), 一个逻辑上的服务器,能够通过exe命令而启动的一个服务程序。activation属性,是设置服务的启动方式,on-demand是最常用的方式,另外还有always等启动方式;option标签是exe执行命令命令行的参数;

3.  适配器(adpter),定义服务器端的适配器。

name属性唯一标志这个适配器;

endpoints属性指定端点信息;

replica-group属性标示该适配器是个可复制组集群,并指定这个可复制组的名称;

register-process属性定义了是否这个节点是否可以被icegrid关闭;

4.  节点(node),它应该代表了一个物理上的节点。

name属性指定节点的名字,并且是唯一的。

5.  可复制组(replica-group),一组对象适配器的集合。

id属性唯一标识一个可复制组;

load-balancing子项中type属性指定负载均衡策略,icegrid提供了四种负载均衡策略: Random (随机方式)

       Adaptive(适配方式)

       Round Robin(最近最少使用)

       Ordered(顺序方式)

object子项定义适配器绑定的服务对象信息。其中identity属性指定对象的标识,type属性指定了对象的层次结构类型。这两个属性都可以唯一的标识一个服务对象。

6.  服务模板(server-temple),服务模板是对服务的一个抽象,避免了重复定义。这样,在节点中描述服务时只需要实例化它的服务模板就可以了。

id属性唯一标识一个服务模板;

parameter子项定义服务模板的参数,可包含多个,主要实例化服务时用;

server子项就是上面2中的服务定义;

另外还有一些特殊的服务模板,比如:icebox服务模板,它的定义和通用的服务模板的定义不太一样。

解析app.xml文件:

通过对配置文件结构的分析,来解析一下app.xml。

第1行,标识这是一个icegrid的配置文件;

第2行,标识应用的名称为RTDSSystem,这个名称是唯一的;

第3~10行,定义了一个服务模板RTDSSystemServer,并有一个参数index;

          其中5~9定义了这个模板包含的服务定义,第6行是这个服务包含的对象适配器

          的定义;

第12~15行,是对可复制组的定义,包括服务对象的定义和负载均衡策略;

第17~21行,是对节点node_1的定义,指定了节点的名称,包含的服务(3个服务);

第22~26行,是对节点node_2的定义

第27~31行,是对节点node_3的定义

最后两行是闭合标签,至此一个icegrid的分布式部署配置文件就完成了。

部署配置文件的扩展:

app.xml中对服务模板、适配器、服务对象等的配置都是一个,事实上这些可以在文件中定义多个,比如可以有多个服务模板,一个服务里可以有多个适配器,可以有多个可复制组,一个节点里可以有多个不同类型的服务等。

另外,app.xml可以包含其它的xml。

2.1.4  节点配置

config.grid文件的内容:

#

# The IceGridlocator proxy.

#

Ice.Default.Locator=IceGridRDDataSource/Locator:default-h 10.0.2.241 -p 12000:default -h 10.0.2.242-p 12000         #1

 

#

# IceGrid nodeconfiguration.

#

IceGrid.Node.Name=node_2                  #2

IceGrid.Node.Endpoints=default              #3

IceGrid.Node.Data=node_2                       #4

IceGrid.Node.Output=node_2             #5

IceGrid.Node.RedirectErrToOut=1           #6

 

# Trace properties.

#

IceGrid.Node.Trace.Activator=1             #7

#IceGrid.Node.Trace.Adapter=2             #8

#IceGrid.Node.Trace.Server=3              #9

配置项说明:

事实上,这个文件里面的配置项,在config_slave.grid中都有描述,但这里也列出来,方便阅读。

#1   注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到

#2   定义节点的名称,必须唯一

#3   节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default

#4   节点的数据目录的路径

#5   节点标准输出信息重定向的目录路径,会自动生成输出文件

#6 节点上的服务程序的标准错误重定向到标准输出

#7   激活器跟踪级别,通常有0,1,2,3级,默认是0

#8   对象适配器跟踪级别,通常有0,1,2,3级,默认是0

#9   服务跟踪级别,通常有0,1,2,3级,默认是0

2.2     客户端配置

客户端的配置很简单,和分布式相关的配置就一项,添加如下:

#

# The IceGridlocator proxy.

#

Ice.Default.Locator=IceGridRDDataSource/Locator:default-h 10.0.2.241 -p 12000:default -h 10.0.2.242-p 12000 #注册服务的端点信息(主注册服务和所有的从注册服务),用于定位

3. 结果验证

3.1  程序方式

1. 启动服务器

1) icegridnode–Ice.Config=config_master.grid  启动主注册服务和节点1

2) icegridnode–Ice.Config=config_slave.grid   启动从注册服务和节点2

3) icegridadmin–Ice.Config=config_master.grid -e “application add app.xml”   部署分布式服务

4) icegridnode–Ice.Config=config.node 启动节点3

2. 启动客户端,进行多次远程调用,根据执行情况就可以判断服务器端是否配置成功。

3.2  工具方式

用Ice官方提供的可视化管理工具IceGridGUI.jar来验证和管理icegrid的部署。

打开dos窗口,在命令行下进入C:\Program Files\ZeroC\Ice-3.4.1\bin目录下,然后运行“java –jar IceGridGUI.jar”,弹出IceGrid Admin的主界面

1. 高级应用配置

4.1  集成IceBox

在文档《IceBox开发和配置》(当前是1.0版)中,介绍了一个IceBox服务程序的开发方法和单独应用中配置和管理的过程。在实际的应用中,IceBox服务通常集成到IceGrid中,并通过IceGrid进行激活和部署。

本章节中IceBox服务是集成在IceGrid中,并通过IceGrid进行部署,所以IceBox服务的配置信息不再同《IceBox开发和配置》中一样在config.icebox中描述,而是直接配置在部署文件app.xml中。那也就是说,IceGrid集成IceBox服务,只需要在app.xml文件中添加Icebox服务相关的配置信息就可以了。事实上,有关Ice所有的配置信息(除IceGrid自身的配置信息),都可以添加到app.xml中,并通过icegrid部署后生效。

下面各节详细描述IceBox服务的集成过程。

4.1.1  IceBox服务程序编写

请参考文档《IceBox开发和配置》,这里不再详述。由于IceBox服务相关的配置信息都放在了app.xml中,并且服务是通过IceGrid按需激活的,因此这里程序代码略有调整。下面列出IceBox服务的实现代码:

文件名:ServerService.java

import main.java.DataSource;

import IceBox.Service;

public class ServerService implements IceBox.Service {

    /**

    * @param name 配置文件中的service名称

    * @param communicator对象,由IceBox.ServiceManager负责创建和销毁。

    *          可能同时被其他服务共享使用(由配置文件决定),object Adapter的名

    *          称必须是唯一的;

    * @param args  配置文件中的参数列表

    * @Override

     **/

    public void start(String name,Ice.Communicator communicator,

                      String[] args){

       //创建objectAdapter,名称有配置文件决定

       Adapter =communicator.createObjectAdapter(

                            “RTDataSystem-“+name);

       //创建servant

       StringRTDataSourceIdentity = communicator.getProperties().

                                  getProperty(“RTDataSource.Identity”);

       DataSourceobjDataSrc = new DataSource(“dataSource”);

        Adapter.add(objDataSrc,

           communicator.stringToIdentity(RTDataSourceIdentity));

        Adapter.activate();

    }

    /**

     *

    * @param args

    * @Override

     *

    **/

    public void stop()

    {

       Adapter.destroy();

    }

    private Ice.ObjectAdapter Adapter;

}

4.1.2  IceGrid集成IceBox服务

IceGrid集成IceBox只和部署文件(app.xml)有关,IceBox服务(service)的粒度和普通的server是一样的,因此IceBoxservice的部署和普通的server非常类似,它同样有模板、服务(service)和实例化的概念,可以将IceBox service理解为一个特殊的server。

为了能更清楚的描述这个集成配置的过程,在IceGrid配置的基础上,添加IceBox服务。具体目标如下:

1.      集成ServerService服务(service),并且ServerService服务(service)使用的服务对象和之前server的服务对象使用同一个(type–::RTDataSystem::RTDataSource)

2.      在节点1(node_1)上添加IceBox服务功能(IceBox-Node1),这个IceBox服务包含了5个ServerService服务;同样的在节点2(node_2)上也添加一个IceBox服务功能(IceBox-Node2),也包含了5个ServerService服务

3.      这些IceBox服务中分布的多个服务(service)和之前已经存在的服务(server)一起通过IceGrid实现负载均衡

为了实现上述的功能,需要添加IceBox服务的相关配置,首先看一下此时app.xml的变化,变化和添加部分用浅灰阴影标出。

app.xml

<?xml version=”1.0″encoding=”UTF-8″ ?>

<icegrid>

<applicationname=”RTDSSystem“>

<server-templateid=”RTDSSystemServer“>

<parameter name=”index“/>

<server id=”RTDSSystemServer-${index}” exe=”java“activation=”on-demand“>

<adapter name=”RTDataSysytem“endpoints=”tcp

replica-group=”RTDataSystemGroup“/>

<option>jar</option>

<option>ServerApp.jar</option>

</server>

</server-template>

 

<!— begin服务模板定义–>

1   <service-templateid=”RTDSystemService“>

2       <parameter name=”name“/>

3       <service name=”${name}” entry=”ServerService“>

4           <description>A simple service named after ${name}</description>

5           <properties>

6             <property name=”RTDataSource.Identity” value=”RTDataSource“/>

7           </properties>

8           <adapter name=”RTDataSystem-${name}” endpoints=”tcp

id=”RTDataSystem-${name}” replica-group=”RTDataSystemGroup

server-lifetime=”false“/>

11      </service>

12  </service-template>

<!– end服务模板定义–>

 

<replica-groupid=”RTDataSystemGroup“>

<load-balancingtype=”round-robin“/>

<!–load-balancingtype=”ordered” /–>

<!–load-balancingtype=”adaptive” /–>

<!–load-balancingtype=”random” n-replicas=”0″/–>

<object identity=”RTDataSource” type=”::RTDataSystem::RTDataSource“/>

</replica-group>

 

 

<node name=”node_1“>

<server-instancetemplate=”RTDSSystemServer” index=”1“/>

<server-instancetemplate=”RTDSSystemServer” index=”11“/>

<server-instancetemplate=”RTDSSystemServer” index=”111“/>

<!— begin IceBox服务配置 IceBox-Node1–>

1     <icebox id=”IceBox-Node1” activation=”on-demand“exe=”java”>

2        <description>Asample IceBox server IceBox-Node1</description>

3        <option>IceBox.Server</option>

4        <properties>

5           <property name=”IceBox.InstanceName” value=”${server}“/>

6           <property name=”Ice.Admin.Endpoints” value=”tcp -h 10.0.2.241“/>

7           <property name=”IceBox.Trace.ServiceObserver” value=”1“/>

8        </properties>

9        <service-instance template=”RTDSystemService” name=”one“/>

10       <service-instancetemplate=”RTDSystemService” name=”two“/>

11       <service-instancetemplate=”RTDSystemService” name=”three“/>

12       <service-instancetemplate=”RTDSystemService” name=”four“/>

13       <service-instancetemplate=”RTDSystemService” name=”five“/>

14     </icebox>

<!— end IceBox服务配置 IceBox-Node1–>

</node>

<node name=”node_2“>

<server-instancetemplate=”RTDSSystemServer” index=”2“/>

<server-instancetemplate=”RTDSSystemServer” index=”22“/>

<server-instancetemplate=”RTDSSystemServer” index=”222“/>

<!— begin IceBox服务配置 IceBox-Node2–>

1     <icebox id=”IceBox-Node2” activation=”on-demand“exe=”java“>

2        <description>Asample IceBox server IceBox-Node2</description>

3        <option>IceBox.Server</option>

4        <properties>

5           <property name=”IceBox.InstanceName” value=”${server}“/>

6           <property name=”Ice.Admin.Endpoints” value=”tcp -h 10.0.2.242“/>

7           <property name=”IceBox.Trace.ServiceObserver” value=”1“/>

8        </properties>

9        <service-instancetemplate=”RTDSystemService” name=”2-one”/>

10       <service-instancetemplate=”RTDSystemService” name=”2-two“/>

11       <service-instancetemplate=”RTDSystemService” name=”2-three“/>

12       <service-instancetemplate=”RTDSystemService” name=”2-four“/>

13       <service-instancetemplate=”RTDSystemService” name=”2-five“/>

14     </icebox>

<!— begin IceBox服务配置 IceBox-Node2–>

</node>

<node name=”node_3“>

<server-instancetemplate=”RTDSSystemServer” index=”3“/>

</node>

</application>

</icegrid>

app.xml中增加的IceBox服务相关的配置部分如下:

n  服务摸板(Service Template):

可以对比一下servertemplate的定义,两者基本上没有什么区别,最大的不同是

Server template中server是指定一个可执行的程序,而service中指定的是动态加载

的组件入口。以下解释上述配置中的服务模板的定义:

第1行指定定义模板的id,唯一标志一个服务模板,第12是闭合标签;

第2行定义了一个参数name,默认值是“name”;

第3~11行定义了模板中使用的服务(service),并在该service中指定了名称、

入口、描述信息、配置属性,定义了一个对象适配器;

第4行,是该服务的描述信息;

第5~7行,是属性定义列表,这里定义了一个属性RTDataSource.Identity,并

指定其值为RTDataSource;

第8行,定义了一个对象适配器,指定了其name、endpoints、id、replica-group

等属性信息,这个基本上和server中adapter的定义没有什么区别

 

以上内容就是service模板的定义。

n  IceBox服务(IceBox-Node1):

                 icebox服务的定义被包含在分布的服务器节点中,主要包括三部分的信息:

1.      IceBox服务的启动配置信息

2.      IceBox的属性配置信息

3.      Service服务实例化列表

下面解释这块内容:

第1~3行,指定了IceBox服务的名称,启动方式,启动执行程序等

第4~8行,指定了IceBox服务的属性配置列表,这里定义了IceBox服务的实

例名称、管理器访问端点以及service被跟踪的级别

第9~13行,实例化了5个service服务

至此,一个包含了5个serverservice服务的IceBox服务被集成在node1中。

n  IceBox服务(IceBox-Node2)

同IceBox服务(IceBox-Node1)中描述,只是具体value有所不同,这里不再解释。

  4.1.3  测试验证

验证方式同第3章,这里不再赘述。部署完成后,就可以通过IceGridGUI.jar程序来进行管理

来源:http://blog.csdn.net/educast/article/details/9414789

struts2 upgrade 2.3 to 2.5 migration 升级向导

Dependencies

Update Struts dependencies to 2.5.

Remove the following plugin dependencies because they were dropped and aren’t supported anymore.

  • Dojo Plugin
  • Codebehind Plugin
  • JSF Plugin
  • Struts1 Plugin

StrutsPrepareAndExecuteFilter

The org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter was moved to org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.

In web.xml replace this:

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

with that:

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

There were other package changes, please read Version Notes 2.5 for more details.

DTD

Struts DTD was updated to 2.5 version.

In struts.xml replace 2.3 DTD version:

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"

with 2.5:

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

Tags attributes

The id attribute was replaced with var attribute in the following tags.

  • <s:action>
  • <s:append>
  • <s:bean>
  • <s:date>
  • <s:generator>
  • <s:iterator>
  • <s:merge>
  • <s:number>
  • <s:set>
  • <s:sort>
  • <s:subset>
  • <s:text>
  • <s:url>

If you have something like that in your code:

<s:url id="url" action="login">

change it to:

<s:url var="url" action="login">

The <s:set> tag name attribute is replaced with var attribute.

From:

<s:set id="str1" value="'string1 value'" />
<s:set name="str2" value="'string2 value'" />

to:

<s:set var="str1" value="'string1 value'" />
<s:set var="str2" value="'string2 value'" />

Also escape attribute was renamed to escapeHtml attribute.

From:

<s:property escape="true" var="someProperty"/>

to:

<s:property escapeHtml="true" var="someProperty"/>

Div tag

The <s:div> tag was dropped.

Replace <s:div> with plain HTML <div> tag.

Field names

If you have field names which starts with single lower case letter, for example:

private String sTrng;
public String getSTrng() {...}
public void setSTrng(String str) {...}

change accessors to getsTrng and setsTrng.

Or better yet, change field names to not contain single lower case letter:

private String strng;
public String getStrng() {...}
public void setStrng(String str) {...}

For additional info see WW-3909.

Tiles

Depending on from which version of struts you upgrade and whether you used tiles-plugin or tiles3-plugin you may need to do different steps.

Struts 2.5 just provides a tiles-plugin which uses Tiles3. So support for Tiles2 has been dropped as well as the name tiles3-plugin.

Now the only maven dependency looks like this:

maven dependecy for tiles-plugin
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-tiles-plugin</artifactId>
    <version>${struts2.version}</version>
</dependency>

You may need to update DTD in your tiles.xml files to Tiles3:

tiles3 dtd
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"

A Listener in web.xml is required. It is not necessary to configure paths to tiles.xml files here as they are picked up automatically.

StrutsTilesListener in web.xml
<listener>
  <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>

Optionally you may remove TilesDefinitions from XML and annotate actions instead. See Tiles Plugin for more details.

Temp/Work directory of ApplicationServer/ServletContainer

Users reported it was necessary for them to remove temp/work directory of their ApplicationServer/ServletContainer. Likely to force server to recompile JSPs.

来源:https://cwiki.apache.org/confluence/display/WW/Struts%202.3%20to%202.5%20migration

WordPress错误:无法安装这个包。PCLZIP_ERR_MISSING_FILE (-4) : Missing archive file

WordPress更新或是上传插件或主题错误时出现“无法安装这个包。PCLZIP_ERR_MISSING_FILE (-4) : Missing archive file”错误在某些配置不够完善的主机中可能会出现这种情况。这是因为空间中temp目录没有设置访问权限的问题,需要空间商为你设置目录访问权限,一般这种要求他们是不会理的,所以我们只能改变WordPress的上传临时目录。

解决方法如下

1. 通过网站FTP打开WordPress根目录下的 wp-config.php 文件,找到如下代码:

/** WordPress 目录的绝对路径。 */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');

2. 在下面增加如下代码即可:

/** 指定WordPress的临时目录 */
define('WP_TEMP_DIR', ABSPATH . 'wp-content/temp');

3. 最后在 /wp-content/ 文件夹下新建个一个名为 temp 的文件夹,然后再重新上传或者更新下载插件和主题就可以了。

最好叫 temp 权限和系统中一致为777

Go 1.8 正式发布,编译时间比 Go 1.7 提高约 15%

今天Go 团队很高兴地宣布Go 1.8发布了。现已提供下载。整个标准库有了显著的性能提升和变化。该版本主要的更新内容如下:

  • Go 1.7中为64位x86引入的编译器后端现在用于所有体系结构,这些体系结构将会有显著的性能改进。例如,我们的基准程序所需的CPU时间在32位ARM系统上减少了20-30%。在此版本中,64位x86系统还有一些性能改进,编译器和链接器更快了,编译时间应该比Go 1.7提高约15%。但是在这一领域还有很长的路要走:我们希望在未来版本中实现更快的编译速度。
  • 垃圾收集暂停时间明显更短,通常在100微秒以下,有时候甚至低至10微秒。
  • HTTP服务器添加对 HTTP/2 Push的支持,允许服务器抢先发送响应到客户端。这对于通过消除往返行程来最小化网络延迟非常有用。HTTP服务器现在还支持正常关机了,允许服务器通过在服务所有正在运行的请求之后关闭,而最小化停机时间。
  • 上下文(添加到Go 1.7中的标准库)提供了取消和超时机制。Go 1.8在标准库中添加了更多对上下文的支持,包括数据库/ sql和net包以及net / http包中的Server.Shutdown。
  • 现在使用新添加的Slice函数在排序包中对切片进行排序更简单。例如,要通过“名称”字段对结构体片段进行排序:
sort.Slice(s,func(i,j intbool {return s [i] .Name <s [j] .Name})

更多新版本的添加、改进和修复内容,以及上面列出的改进的详细信息请查看Go 1.8发行说明。

为了庆祝发布,世界各地的Go用户组都在本周举办发布会,这已经成为Go社区的一个传统,所以如果你错过了这一次,那么请在 GO 1.9 发布前留意。

via:https://blog.golang.org/go1.8

Java 9进入第一轮问题修复阶段

来源:infoq.com  作者:Abraham Marín Pérez ,译者 尚剑

Java 9功能特性正式完成,这意味着第一个问题修复阶段已经开始。HTTP/2客户端没有在截止日期前完成,现已降级为孵化器功能。由于现在的目标是在7月准备好可发布的Java 9,所以目前不太可能添加任何新的JEP。

InfoQ此前的报道中提到,第一轮问题修复阶段,或者说“启动Rampdown”阶段的目的是解决P1至P3级别的问题。其中,根据Java平台的首席架构师Mark Reinhold提出的流程,问题修复应该优先考虑Java 9中的新问题,而不是影响Java 9但已经存在于Java 8或更早版本Java中的问题,之所以这么做,可能是因为相对于新的问题,公众更容易忍受已经存在的问题。Reinhold提供的缺陷列表显式地过滤掉了只与文档、演示和测试相关的缺陷,这似乎表明了他们对用户体验的关注。在撰写本文时,该列表中有194个缺陷。

这一阶段还包括一个规定,如果有正当理由,可以留下一些未解决的P1至P2级别的问题。希望推迟其解决方案的问题所有者必须在错误报告中指出其请求的原因(复杂性、风险、时间不足等),然后相关区域负责人、小组负责人和JDK 9 Project 负责人将分析这些数据并同意或拒绝延期。在写这篇文章的时候,这个列表中暂时还没有推迟请求,但以后可能会出现。

这个Rampdown阶段在特定的扩展功能完成阶段之后进行,以给予一些JEP完成的时间。HTTP/2客户端以及增强弃用、jlink、和新的HotSpot编译系统都是在2016年7月出现风险的功能。其中,HTTP/2 Client是唯一一个没有最终做出来的功能,转而成为孵化器功能。这意味着,尽管HTTP/2 Client将包含在Java 9中,但默认情况下不可访问:该功能将被打包在前缀为jdk.incubator.的模块下,开发人员必须显式地使用–add-mod标记才能访问该功能。然而,如果开发人员选择这样做,他们将需要考虑到孵化器功能不是标准API的一部分,因此该功能可能随时被修改。

阅读英文原文Java 9 Enters First Bug Fixing Round

Linux Kernel 3.18 LTS 终止支持 请升至 4.9 或 4.4 分支

在发布最后一个维护版本更新之后,Linux 稳定版内核维护者 Greg Kroah-Hartman 宣布 Linux Kernel 3.18 分支走到了生命的尽头。而 3.18 LTS 原计划于今年 1 月终止支持。

Linux Kernel 3.18.48 LTS 是该分支的最后版本,根据短日志显示该版本共计调整了 50 个文件,插入 159 处删除 351 处。升级网络堆栈的同时改善了 Bluetooth, Bridge, IPv4, IPv6, CAIF 和 Netfilter,并升级了 USB, SCSI, ATA, media, GPU, ATM, HID, MTD, SPI 和网络(有线和无线)驱动。新发布的 3.18.48 还修正了 3.18.47 和 3.18.27 中的一个 bug。

LTS 版通常会提供大约两年的支持时间,3.18 是在 2014 年 12 月发布的。如果你当前还在使用该内核分支,那么现在你应该升级至更新的 LTS 版本,例如 Linux Kernel 4.9 或者 4.4,这两个版本要比 3.18 更加的安全和强悍。不过 Linux Kernel 3.18 主要被 Google 和其他供应商应用于一些 Android 设备、部分 Chromebook 上,Kroah-Hartman 建议用户拒绝购买仍然使用 3.18 LTS 的供应商的设备。如果无法升级内核开发者也提供了一些建议。

“如果你在使用 Linux Kernel 3.18 中有困难,那么我可以给你提供一些帮助。首先,你需要和硬件供应商反馈,要求尽快升级否则不再购买他们的产品。如果供应商还是不升级,请致信我们让我们出面和厂商进行沟通,出现这个问题的肯定不止你一个人。”

来源:http://www.oschina.net/news/81799/linux-kernel-3-18-48-released

喝酒与开发,新年了还是喝酒庆祝一下好了

新的一年了,还是喝酒庆祝一下好了。

大家喝的是啤酒。这时你入座了。
你给自己倒了杯可乐,这叫低配置。
你给自已倒了杯啤酒,这叫标准配置。
你给自己倒了杯茶水,这茶的颜色还跟啤酒一样,这叫木马。
你给自己倒了杯可乐,还滴了几滴醋,不仅颜色跟啤酒一样,而且不冒热气还有泡泡,这叫超级木马。
你的同事给你倒了杯白酒,这叫推荐配置。

人到齐了,酒席开始了。
你先一个人喝了一小口,这叫单元测试。
你跟旁边的人说哥们咱们随意,这叫交叉测试。
但是他说不行,这杯要干了,这叫压力测试。
于是你说那就大家一起来吧,这叫内部测试。
这个时候boss向全场举杯了,这叫公开测试。

菜过三巡,你就不跟他们客气了。
你向对面的人敬酒,这叫p2p.
你向对面的人敬酒,他回敬你,你又再敬他……,这叫tcp.
你向一桌人挨个敬酒,这叫令牌环。
你说只要是兄弟就干了这杯,这叫广播。
可是你的上司jj听了不高兴了,只有兄弟么,罚酒三杯。这叫炸弹。
可是你的下级mm听了不高兴了,我喝一口,你喝一杯,这叫恶意攻击。
有一个人过来向这桌敬酒,你说不行你先过了我这关,这叫防火墙。
你的小弟们过来敬你酒,这叫一对多。
你是boss,所有人过来敬你酒,这叫服务器。

酒是一样的,可是喝法是不同的。
你喝了一杯,boss喝了一口,这叫c#。
你喝了一杯,mm喝了一口,这叫vb。
你喝了一杯,你大哥喝了半杯,这叫c++。
你喝了半杯,你小弟喝了一杯,这叫汇编。
你喝了一杯,你的搭档也喝了一杯,这叫c。

酒是一样的,可是喝酒的人是不同的。
你越喝脸越红,这叫频繁分配释放资源。
你越喝脸越白,这叫资源不释放。
你已经醉了,却说我还能喝,叫做资源额度不足。
你明明能喝,却说我已经醉了,叫做资源保留。
你喝一段时间就上厕所,这叫cache。

酒过三巡,你也该活动活动了。
你一桌一桌的走,这叫轮巡。
你突然看到某一桌的漂亮mm,走了过去,这叫优先级。
你去了坐下来就不打算走了,这叫死循环。
你的老大举杯邀你过去,你只好过去,这叫启动事件。
你向一桌敬酒,他们说不行不行我们都喝白的,于是你也喝白的,这叫本地化。
你向boss敬酒,可是boss被围了起来,你只能站在外圈,这叫排队。
你终于到了内圈,小心翼翼的向前一步,这叫访问临界区。
你拍着boss的肩膀说哥们咱们喝一杯,这叫越界。
你不知喝了几圈了,只会说两个字,干了,这叫udp。
可是还有人拿着酒瓶跑过来说,刚才都没跟你喝,这叫丢包。

喝酒喝到最后的结果都一样
你突然跑向厕所,这叫捕获异常。
你在厕所吐了,反而觉得状态不错,这叫清空内存。
你在台面上吐了,觉得很惭愧,这叫程序异常。
你在boss面前吐了,觉得很害怕,这叫系统崩溃。
你吐到了boss身上,只能索性晕倒了,这叫硬件休克。

喝挂了,宕机

响应了国家号召不喝高度酒,都把白酒换成了白葡萄酒,这叫最佳实践

不喝不准走,这叫锁,喝了才让走,这叫解锁

边喝边吐是不是叫溢出呢?

边喝边尿叫多线程?

来源:https://my.oschina.net/xxiaobian/blog/818235

Firebug 宣布不再维护,讲不出再见!

Firebug 在其官方网站上宣布 —— “Firebug 扩展不再进行开发或维护,我们邀请您使用 Firefox 的内置开发工具以代替”。

Firebug 是 Firefox 下的一款开发类插件,现属于 Firefox 的五星级强力推荐插件之一。它集 HTML 查看和编辑、Javascript 控制台、网络状况监视器于一体,是开发 JavaScript、CSS、HTML 和 Ajax 的得力助手。Firebug 如同一把精巧的瑞士军刀,从各个不同的角度剖析 Web 页面内部的细节层面,给 Web 开发者带来很大的便利。

来自:http://getfirebug.com/

WordPress 4.7 “Vaughan”发布,内容管理系统

WordPress 开发团队发布了 WordPress 4.7 正式版 —“Vaughan” 。取名“Vaughan”以纪念传奇的爵士乐歌手Sarah“Sassy”Vaughan。现在可以更新了。新版带来全新的默认主题,定制器加入了新功能,REST API 内容端点,更多开发者工具。

更新如下:

  • 新的主题 — Twenty Seventeen。全新的默认主题可让您的网站通过引人入胜的精选图片和视频头部生动呈现。

  • WordPress 4.7 为自定义程序添加了新功能,帮助您完成主题的初始设置,在一个不间断的工作流程中对所有更改进行非破坏性实时预览。
  • WordPress 4.7 带来了针对帖子、评论、条款、用户,元和设置的 REST API 端点。

来源

下载地址:https://wordpress.org/download/

php-fpm添加service服务

Nginx通过FastCGI运行PHP比Apache包含PHP环境有明显的优势,最近有消息称,PHP5.4将很有可能把PHP-FPM补丁包含在内核里,nginx服务器平台上运行PHP将更加轻松,下面我们就来看一篇php-fpm平滑启动并配置服务例子。

我的PHP是源码安装的。php-fpm在PHP 5.3.2以后的版本不支持以前的php-fpm (start|restart|stop|reload) ,那么如果将php-fpm配置成服务,并添加平滑启动/重启。

配置php-fpm.conf(vi  php-7.1.0/etc/php-fpm.conf),将pid(;pid = run/php-fpm.pid)前的;去掉。

因为编译安装php的,所以会在php目录生成很多二进制文件,找到init.d.php-fpm,拷贝到init.d下。

cp  php-7.1.0/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm

设置权限,并添加服务

chmod +x /etc/init.d/php-fpm
chkconfig –add php-fpm

以后可以使用如下命令管理php-fpm了

service php-fpm status

service php-fpm start
service php-fpm restart
service php-fpm reload

service php-fpm stop

2015 年开源前端框架盘点 TOP 20

2015年已经过去了,作为一个前端开发者,我觉得有必要把过去一年帮助过我或朋友们的优秀开源前端框架做个盘点,希望这些项目能够越来越好,帮助到更多的前端开发者们。

此榜单根据github上star数作为排名依据,一个人力量有限,如果收集有遗漏欢迎补充。

 

1、名称:Bootstrap

类别/语言:HTML、CSS、JavaScript

创建者: Twitter

人气:在Github上有91007 stars

描述:主流框架中毋庸置疑的老大,Bootstrap 是基于 HTML、CSS、JavaScript 的,它简洁灵活,使得 Web 开发更加快捷。

核心概念/原则: RWD 和移动优先制。

浏览器支持: Firefox, Chrome, Safari, IE8+ (你需要 Respond.js for IE8)

响应式: Yes

模块化: Yes

官网地址:http://getbootstrap.com/

Github地址:https://github.com/twbs/bootstrap

 

2、名称:html5-boilerplate

类别/语言:HTML、CSS、JavaScript

创建者:Paul Irish

人气:在Github上有32,349 stars

描述:HTML5 Boilerplate 帮你构建 快速, 健壮, 并且 适应力强 的web app或网站。

核心概念/原则:响应式

浏览器支持:Firefox, Chrome, Safari, IE8+,Edge,Opera

预处理器:None

响应式:Yes

模块化:Yes

官网地址:https://html5boilerplate.com/

Github地址:https://github.com/h5bp/html5-boilerplate

 

3、名称:Meteor

类别/语言:HTML、CSS、JavaScript

创建者:immir

人气:在Github上有31,092 stars

描述:Meteor是新一代的开发即时web应用的开源框架,它能帮助你在最少的时间内完成开发。

核心概念/原则:响应式

预处理器: Less

响应式: Yes

模块化: Yes

官网地址:https://www.meteor.com

Github地址:https://github.com/meteor/meteor/

4、名称:Semantic UI

类别/语言:HTML、CSS、JavaScript

创建者: Jack Lukic

人气: 在Github上有22,325 stars

描述: “基于自然语言有效原则的UI组件框架”

核心概念/原则: 语义,标签的矛盾性、响应式

浏览器支持:Firefox, Chrome, Safari, IE10+ (IE9 with browser prefix only), Android 4, Blackberry 10。

预处理器: Less

响应式: Yes

模块化: Yes

官网地址:http://semantic-ui.com/

Github地址:https://github.com/Semantic-Org/Semantic-UI

5、名称:Foundation

类别/语言:HTML、CSS、JavaScript

创建者: ZURB
人气: 在Github上有22,206+ stars
描述: “世界上最优秀的响应式前端框架”
核心概念/原则: RWD 、手机优先、语义的

浏览器支持: Chrome, Firefox, Safari, IE9+; iOS, Android, Windows Phone 7+
预处理器: Sass
响应式: Yes
模块化: Yes

官网地址:http://foundation.zurb.com/

Github地址:https://github.com/zurb/foundation-sites

6、名称:Materialize

类别/语言:CSS

创建者:Google

人气:在Github上有15,288stars

描述:Materialize是一个个基于材料设计的一个现代化的响应式前端框架。他们做了最繁重的工作,为您提供默认的样式,结合了您的自定义组件。此外,他们还改进动画和过渡,为开发人员提供流畅的体验。

核心概念/原则:响应式

预处理器:Sass

响应式:Yes

模块化:Yes

官网地址:http://materializecss.com

Github地址:https://github.com/Dogfalo/materialize

浏览器支持:Chrome 35+, Firefox 31+, Safari 7+, IE 10+

7、名称:Pure

类别/语言:CSS

创建者: Yahoo

人气: 在Github上有13,161 stars

描述: “您可以在每一个web项目中使用的一组小的和响应式的CSS模块”

核心概念/原则:SMACSS,极简的.

浏览器支持:Firefox的最新版本, Chrome, Safari; IE7+; iOS 6.x, 7.x; Android 4.x

预处理器: None

响应式: Yes
模块化: Yes

官网地址:http://purecss.io/

Github地址:https://github.com/yahoo/pure

 

8、名称:Vue

类别/语言:CSS、JavaScript

创建者:尤雨溪

人气:在Github上有12,214 stars

描述:Vue.js 是用于构建交互式的 Web 界面的库。它提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API。

核心概念/原则:响应式

浏览器支持:Firefox, Chrome, Safari, IE10+,Android 4.2+,iOS 7+

预处理器:None

响应式:Yes

模块化:Yes

官网地址:http://vuejs.org/

Github地址:https://github.com/vuejs/vue

9、名称:Skeleton

类别/语言:CSS、JavaScript

创建者:Dave Gamache

人气:在Github上有10,622stars

描述:Skeleton 是一个小的 JS 和 CSS 文件的集合,可帮你快速开发漂亮的网站,适合各种屏幕设备包括手机。Skeleton 基于 960 grid 开发。它是一个 UI 框架。

核心概念/原则:响应式

浏览器支持:Firefox, Chrome, Safari, IE10+,Opera

预处理器:None

响应式:Yes

模块化:Yes

官网地址:http://www.getskeleton.com

Github地址:https://github.com/dhg/Skeleton

10.名称: Amaze UI

类别/语言:HTML、CSS、JavaScript

创建者:云适配

最后更新时间:2015年12月

人气:在Github上有6425 stars

描述:国内首个开源HTML5跨屏前端框架,中文排版支持更优、本土化组件丰富。

并在2015年11月推出基于 React.js 的专属移动端 Web 组件库Amaze UI touch。

核心概念/原则:组件化、移动优先、轻量级、高性能。

浏览器支持: Firefox, Chrome, Safari, IE8+

响应式: Yes

模块化: Yes

官网地址:http://amazeui.org/

Github地址:https://github.com/amazeui/amazeui

 

11、名称:UIkit

类别/语言:HTML、CSS、JavaScript

创建者: YOOtheme

人气: 在Github上有6,050+ stars

描述: “一个轻量级的和模块化的前端框架,用于快速开发和功能强大的web接口。”

核心概念/原则:RWD, 手机优先.

预处理器: Less, Sass

响应式: Yes

模块化: Yes

官网地址:http://getuikit.com/

Github地址:https://github.com/uikit/uikit

浏览器支持: Chrome, Firefox, Safari, IE9+

12、名称:Yui

类别/语言:CSS、JavaScript

创建者:Yahoo

人气:在Github上有3,200+ stars

描述:Yahoo! UI Library (YUI) 是一个开放源代码的 JavaScript 函数库,为了能建立一个高互动的网页,它采用了AJAX, DHTML 和 DOM 等程式码技术。它也包含了许多 CSS 资源。使用授权为 BSD许可证

核心概念/原则:响应式

预处理器: None

响应式:Yes

模块化:Yes

官网地址:http://yuilibrary.com/

Github地址:https://github.com/yui/yui3

浏览器支持:Firefox, Chrome, Safari, IE10+,Opera

13.名称:kissy

类别/语言: JavaScript

创建者:淘宝前端

最后更新时间:2015年7月

人气:在Github上有2035 stars

描述:KISSY 是一款跨终端、模块化、高性能、使用简单的 JavaScript 框架。

框架大小: 37 KB

核心概念/原则: 模块化,跨终端,高扩展性

模块化: Yes

官网地址:http://docs.kissyui.com/

Github地址:https://github.com/kissyteam/kissy/

14.名称:MUI

类别/语言: HTML、CSS、JavaScript

创建者:Dclould

最后更新时间:2016年1月

人气:在Github上有2012 stars

描述:MUI-最接近原生App体验的前端框架框架。

核心概念/原则: 多端发布、高性能

响应式: NO

模块化: Yes

官网地址:http://dev.dcloud.net.cn/mui/

Github地址:https://github.com/dcloudio/mui

15.名称:Arale

类别/语言: JavaScript

创建者:支付宝前端

最后更新时间:2015年7月

人气:在Github上有1252 stars

描述:Arale 是一个开放、简单、易用的前端基础类库。

框架大小:未知

核心概念/原则: 开放、简单、易用

浏览器支持:Firefox, Chrome, Safari, IE6+

响应式: Yes

模块化: Yes

官网地址:http://aralejs.org/

Github地址:https://github.com/aralejs/aralejs.org/

16.名称:JX

类别/语言:Javascript

创建者:腾讯前端

最后更新时间:2015年12月

人气:在Github上有952 stars

描述:JX 是模块化的非侵入式Web前端框架,特别适合构建和组织大规模、工业级的Web App。

框架大小: 未知

核心概念/原则: 保持最优执行效率

浏览器支持: 兼容主流浏览器

模块化: Yes

官网地址:http://alloyteam.github.io/JX/

Github地址:https://github.com/AlloyTeam/JX

 

17.名称:GMU

类别/语言:HTML、CSS、JavaScript

创建者:百度前端

最后更新时间:2015年12月

人气:在Github上有940stars

描述:GMU是基于zepto的mobile UI组件库,提供webapp、pad端简单易用的UI组件! Web App。

核心概念/原则: 简单易用、轻量级

模块化: Yes

官网地址:http://gmu.baidu.com/

Github地址:https://github.com/fex-team/GMU

 

18.名称:ZUI

类别/语言: HTML、CSS、JavaScript

创建者:蝉道

最后更新时间:2015年7月

人气:在Github上有616 stars

描述:开源HTML5前端框架

核心概念/原则:简单易用、轻量级、易于定制

浏览器支持:未知

官网地址:http://zui.sexy/

Github地址:https://github.com/easysoft/zui

19.名称:Clouda Touch.js

类别/语言:JavaScript

创建者:百度云

人气:在Github上有387 stars

描述:Touch.js是移动设备上的手势识别与事件库,也是在百度内部广泛使用的开发。

核心概念/原则: 无入侵设计、媲美原生的交互、极简的API

模块化: Yes

官网地址:http://touch.code.baidu.com/

Github地址:https://github.com/Clouda-team/touch.code.baidu.com

20.名称:Arkui

类别/语言:HTML、CSS、JavaScript

创建者:豆瓣

人气:在Github上有129 stars

模块化: Yes

官网地址:http://mockee.com/arkui/

Github地址:https://github.com/mockee/arkui

来源:http://www.oschina.net/news/69788/2015-opensource-frontend-framework-top20

打造你的php安全程序第一步:禁止掉不安全的php函数(php.ini)

为了使php程序更安全,很多站长都选择了禁用一些比较敏感的函数,那影响php安全的函数到底有哪些呢,下面我们列出了一些:
1、phpinfo()
功能描述:输出 PHP 环境信息以及相关的模块、WEB 环境等信息。
危险等级:中
2、passthru()
功能描述:允许执行一个外部程序并回显输出,类似于 exec()。
危险等级:高
3、exec()
功能描述:允许执行一个外部程序(如 UNIX Shell 或 CMD 命令等)。
危险等级:高
4、system()
功能描述:允许执行一个外部程序并回显输出,类似于 passthru()。
危险等级:高
5、chroot()
功能描述:可改变当前 PHP 进程的工作根目录,仅当系统支持 CLI 模式
PHP 时才能工作,且该函数不适用于 Windows 系统。
危险等级:高
6、scandir()
功能描述:列出指定路径中的文件和目录。
危险等级:中
7、chgrp()
功能描述:改变文件或目录所属的用户组。
危险等级:高
8、chown()
功能描述:改变文件或目录的所有者。
危险等级:高
9、shell_exec()
功能描述:通过 Shell 执行命令,并将执行结果作为字符串返回。
危险等级:高
10、proc_open()
功能描述:执行一个命令并打开文件指针用于读取以及写入。
危险等级:高
11、proc_get_status()
功能描述:获取使用 proc_open() 所打开进程的信息。
危险等级:高
12、error_log()
功能描述:将错误信息发送到指定位置(文件)。
安全备注:在某些版本的 PHP 中,可使用 error_log() 绕过 PHP safe mode,
执行任意命令。
危险等级:低
13、ini_alter()
功能描述:是 ini_set() 函数的一个别名函数,功能与 ini_set() 相同。
具体参见 ini_set()。
危险等级:高
14、ini_set()
功能描述:可用于修改、设置 PHP 环境配置参数。
危险等级:高
15、ini_restore()
功能描述:可用于恢复 PHP 环境配置参数到其初始值。
危险等级:高
16、dl()
功能描述:在 PHP 进行运行过程当中(而非启动时)加载一个 PHP 外部模块。
危险等级:高
17、pfsockopen()
功能描述:建立一个 Internet 或 UNIX 域的 socket 持久连接。
危险等级:高
18、syslog()
功能描述:可调用 UNIX 系统的系统层 syslog() 函数。
危险等级:中
19、readlink()
功能描述:返回符号连接指向的目标文件内容。
危险等级:中
20、symlink()
功能描述:在 UNIX 系统中建立一个符号链接。
危险等级:高
21、popen()
功能描述:可通过 popen() 的参数传递一条命令,并对 popen() 所打开的文件进行执行。
危险等级:高
22、stream_socket_server()
功能描述:建立一个 Internet 或 UNIX 服务器连接。
危险等级:中
23、putenv()
功能描述:用于在 PHP 运行时改变系统字符集环境。在低于 5.2.6 版本的 PHP 中,可利用该函数
修改系统字符集环境后,利用 sendmail 指令发送特殊参数执行系统 SHELL 命令。
危险等级:高

禁用方法如下:
打开/etc/php.ini文件,
查找到 disable_functions ,添加需禁用的函数名,如下:
phpinfo,eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status

看过这些函数,站长们应该去检查一下自己的php.ini 看看这些函数是否禁用了。

当然禁止了这些可能会引起安全因素的php函数。你还必须在php.ini里,进一步把php的错误给关闭,这样才更加有针对性的排除你的php被别人利用错误信息进行攻击。
在php.ini里把
display_error = On
改为:
display_error = Off 即可;

WordPress元老Alex King逝世 与癌症抗争两年半

wordpress alex king

WordPress初期开发者Alex King

北京时间9月29日下午消息,WordPress初期开发者Alex King昨天夜间在家中逝世。Alex King于2013年1月被诊断出癌症,与癌症抗争了两年半。

Alex King在WordPress生态系统中有着巨大的影响力,他参与了从该网站前身b2到现在的WordPress的重建,也参与构建了WordPress 第一个客户端,还建立了第一家针对WordPress的咨询机构。他为大量WordPress功能的开发奠定了基础,甚至包括如今广泛使用的“一键分享” 图标的原型。

8月24日,Alex King在博客上公布了他的遗愿,希望其他人写下对他以及他工作成就的印象,并提交给他的妻子。(李林)

Beanstalkd 使用

一、安装

1、官网

https://kr.github.io/beanstalkd/

2、安装

yum install beanstalkd --enablerepo=epel

3、启动

/usr/bin/beanstalkd -l 0.0.0.0 -p 11300 -b /var/lib/beanstalkd/binlog -F

-b 开启binlog,断电后重启会自动恢复任务。

二、基本概念

1、Beanstalkd设计里面的核心概念:

  • job :一个需要异步处理的任务,是 Beanstalkd 中的基本单元,需要放在一个 tube 中。
  • tube :一个有名的任务队列,用来存储统一类型的 job,是 producer 和 consumer 操作的对象。
  • producer :Job 的生产者,通过 put 命令来将一个 job 放到一个 tube 中。
  • consumer :Job的消费者,通过 reserve/release/bury/delete 命令来获取 job 或改变 job 的状态。

2、job 的生命周期

Beanstalkd job life circle

当producer直接put一个job时,job就处于READY状态,等待consumer来处理,如果选择延迟put,job就先到 DELAYED状态,等待时间过后才迁移到READY状态。consumer获取了当前READY的job后,该job的状态就迁移到RESERVED, 这样其他的consumer就不能再操作该job。

当consumer完成该job后,可以选择delete, release或者bury操作;delete之后,job从系统消亡,之后不能再获取;release操作可以重新把该job状态迁移回READY(也 可以延迟该状态迁移操作),使其他的consumer可以继续获取和执行该job;有意思的是bury操作,可以把该job休眠,等到需要的时候,再将休 眠的job kick回READY状态,也可以delete BURIED状态的job。

正是有这些操作和状态,才可以基于此做出很多意思的应用,比如要实现一个循环队列,就可以将RESERVED状态的 job休眠掉,等没有READY状态的job时再将BURIED状态的job一次性kick回READY状态。

  • READY – 需要立即处理的任务,当延时 (DELAYED) 任务到期后会自动成为当前任务;
  • DELAYED – 延迟执行的任务, 当消费者处理任务后, 可以用将消息再次放回 DELAYED 队列延迟执行;
  • RESERVED – 已经被消费者获取, 正在执行的任务。Beanstalkd 负责检查任务是否在 TTR(time-to-run) 内完成;
  • BURIED – 保留的任务: 任务不会被执行,也不会消失,除非有人把它 “踢” 回队列;
  • DELETED – 消息被彻底删除。Beanstalkd 不再维持这些消息。

3、一些特性

优先级

任务 (job) 可以有 0~2^32 个优先级, 0 代表最高优先级,默认优先级为1024。

持久化

可以通过binlog将job及其状态记录到文件里面,在Beanstalkd下次启动时可以通过读取binlog来恢复之前的job及状态。

分布式容错

分布式设计和Memcached类似,beanstalkd各个server之间并不知道彼此的存在,都是通过client来实现分布式以及根据tube名称去特定server获取job。

超时控制

为了防止某个consumer长时间占用任务但不能处理的情况,Beanstalkd为reserve操作设置了timeout时间,如果该consumer不能在指定时间内完成job,job将被迁移回READY状态,供其他consumer执行。

三、Client Libraries For PHP

项目地址: https://github.com/pda/pheanstalk/

1、Producer 示例:向队列中添加job

$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');

$pheanstalk ->useTube('tubeName') ->put($jobData);

2、Consumer 示例:从队列中取出job

$job = $pheanstalk ->watch('tubeName') ->ignore('default') ->reserve();

echo $job->getData();

$pheanstalk->delete($job);

3、检查服务状态

$isAlive = $pheanstalk->getConnection()->isServiceListening(); //返回 true 或 false

4、获取某一 tube 的数据

try{
    $tubeStatus = $pheanstalk->statsTube('tubeName');
} catch (Exception $e){
    if($e->getMessage()=='Server reported NOT_FOUND'){     //tube 不存在
        $current_jobs_ready = 0;
    }
}

四、其他

1、PHP 版控制台

https://github.com/ptrofimov/beanstalk_console

2、Chrome 插件

https://chrome.google.com/webstore/detail/beanstalkd-dashboard/dakkekjnlffnecpmdiamebeooimjnipm

原文:segmentfault.com

移动端html5之IOS篇

一、在移动端head 中都会加入如下一些app专属的Meta元素

  1. <meta name=”viewport” content=”width=device-width, initial-scale=1,  maximum-scale=1, minimum-scale=1.0,  user-scalable=no”>
  2. <meta name=”apple-mobile-web-app-title” content=“iOS title”>
  3. <meta name=”apple-mobile-web-app-capable” content=”yes”>
  4. <meta name=”apple-mobile-web-app-status-bar-style” content=”black”>
  5. <meta name=”format-detection” content=”telephone=no”>
  6. <meta name=”format-detection” content=”address=no”>
  7. <meta name=”format-detection” content=”email=no”>
  8. <link href=”/images/apple-touch-icon-57×57.png” rel=”apple-touch-icon”>
  9. <link media=”(device-height:480px)” href=”startup/apple-touch-startup-image-640×920.png” rel=”apple-touch-startup-image”>


1、viewport 
width :这个还用说么,,你可以自己手动设置数值,也可等同于设置宽device-width
initial-scale :表示页面初始的缩放比例1:1
maximum-scale:表示允许用户缩放的最大比例
minimum-scale:表示允许用户缩放的最小比例
user-scalable:是否允许用户进行手动缩放(yes/no)

2、apple-mobile-web-app-title
网页默认的title 是不是太长了,可以自己定义一个类似ios app 名

3、apple-mobile-web-app-capable
添加到主屏后,点击图标启动后会隐藏导航和工具栏

4、apple-mobile-web-app-status-bar-style
这个我一直以为是隐藏手机顶部的条,好吧我面壁去了。
其实就是一个背景颜色,默认为白色,可以设置black 和灰色半透明 black-translucent
设置为“black-translucent”将会占据页面px位置,浮在页面上方(会覆盖页面20px高度,iphone4和itouch4的Retina屏幕为40px)

5、format-detection——telephone
默认为识别数字为电话号码,telephone=no 为禁止

6、format-detection——address
禁止跳转为地图 address=no

7、format-detection——email
禁止设置识别邮箱,email=no

8、apple-touch-icon 
设置保存到主屏的icon 图标,如果不设置默认为整个页面截图,亲测真的丑到爆好么。
<link href=”/images/apple-touch-icon-114×114.png” rel=”apple-touch-icon” sizes=”114×114″>
<link href=”/images/apple-touch-icon-120×120.png” rel=”apple-touch-icon” sizes=”120×120”>
图片尺寸可以设定为57*57(px)或者Retina可以定为114*114(px),ipad尺寸为72*72(px)

9、apple-touch-startup-image
为了高逼格,当然少不了启动动画,模拟的当然要真一些嘛。
<link media=”(device-height:480px)” href=”startup/apple-touch-startup-image-640×920.png” rel=”apple-touch-startup-image”>
<link media=”(device-height:568px)” href=”startup/apple-touch-startup-image-640×1096.png” rel=”apple-touch-startup-image”>
media
设备高度为480px 代表iPhone4/4s
设备高度为568px 代表iPhone5

二、一些元素技巧

10、文件上传
<input type=”file”> 单文件
<input type=“file” multiple > 多文件

11、直接呼出数字键盘
<input type=”tel”>

12、呼出email键盘
<input type=“email”>

13、打电话
<a href=”tel:12345654321″>打电话给我</a>

14、发短信
<a href=”sms:12345654321″>发短信</a>

10个令人惊讶的NodeJS开源项目

在几年的时间里,NodeJS逐渐发展成一个成熟的开发平台,吸引了许多开发者。有许多大型高流量网站都采用NodeJS进行开发,像PayPal,此外,开发人员还可以使用它来开发一些快速移动Web框架。

除了Web应用外,NodeJS也被应用在许多方面,本文盘点了NodeJS在其它方面所开发的十大令人神奇的项目,这些项目涉及到应用程序监控、媒体流、远程控制、桌面和移动应用等等。

  1.NodeOS

NodeOS是采用NodeJS开发的一款友好的操作系统,该操作系统是完全建立在Linux内核之上的,并且采用shell和NPM进行包管理,采用 NodeJS不仅可以很好地进行包管理,还可以很好的管理脚本、接口等。目前,Docker和Vagrant都是采用NodeOS的首个版本进行构建的。

 

  2.Noduino

许多硬件黑客希望通过Web页面即可控制他们的Arduino,Noduino就是这样的一个项目,一个简单灵活的JavaScript和NodeJS 框架,通过使用HTML5、Socket.IO和NodeJS的Web应用来控制Arduino。目前,该项目刚刚启动,支持一些常用功能,比如从 Arduino中捕获事件(例如点击按钮)等。

  3.Node-WebKit

Node-Webkit是一个基于Chromium与NodeJS的应用程序运行器,允许开发者使用Web技术编写桌面应用。它是NodeJS与WebKit技术的融合,提供一个跨Windows、Linux平台的客户端应用开发的底层框架。

跨平台开发并非易事,其中一种方式便是使用Web技术和Node-Webkit开发桌面应用来代替那些庞大且笨重的开发框架。

  4.PDFKit

PDFKit是采用NodeJS开发的一款PDF文档生成库,它使用一个“HTML5 canvas-like API”来创建矢量图形和字体嵌入,并且支持许多标准的PDF功能,如文件的安全性、表的创建、文本换行、项目符号、高亮提示、注释等PDF功能。

注意,PDFKit是一款PDF生成工具,而不是一个文档转换系统。如果你想对现有的PDF文档进行操作,你可以使用另一个NodeJS项目—— Scissors

  5.Log.io

Log.io是一个基于NodeJS开发的实时日志监控项目,在浏览器里访问。需要注意的是,Log.io只监视日志变动并不存储日志,不过这个没关系,只要知道日志存储在哪个机器上。

Log.io使用 Socket.io库发 送活动报告的,和其他的监控工具一样,Log.io也采用服务器-客户端的模式。Log.io由两部分组成:server和 harveste,server运行在机器 A(服务器)上监视和纪录其他机器发来的日志消息;log harvester 运行在机器 B(客户端)上用来监听和收集机器 B上的日志改动,并将改动发送给机器 A,每个需要纪录日志的机器都需要一个harvester。

  6.NodecastLeapcast

受谷歌Chromecast技术的启发,开发者使用NodeJS开发出不少Chromecast仿真应用。如Nodecast或Leapcast。在 PC上运行Nodecast或Leapcast,启动移动设备,选择一个支持Chromecast的应用程序,然后你就可以把移动广播上的内容映射到电脑 上了,把电脑当成一个流媒体使用。

在这两个应用中,Nodecast比较简单些,但相应的功能也比较少,它仅经过了YouTube和Google Music的测试( DEMO)。注意,大家不要把Nodecast与 Nodecast库混淆,后者使用DIAL发现协议提供链接设备(类似Chromecast)。

  7.Nexe

Nexe是一款小巧却非常实用的NodeJS工具,它可以为NodeJS应用创建单一可执行的文件,并且无需安装运行时,这样,一些非技术终端的用户就 无需变动NodeJS应用的所有依赖程序。如果你想发布一个NodeJS应用程序,并且没有GUI,Nexe则是您的最佳选择。目前该应用程序的一个弊端 是不能在Windows平台上工作,只适用于Linux和Mac OS X平台,并且它也不支持本地NodeJS模块。

  8.Hyro

Hyro是使用NodeJS开发的一款实时HTML5编辑器,如下图所示,左边显示HTML源码,右边显示内容。语法高亮由 CodeMirror提供。Hyro并不打算成为一款成熟的Web IDE,更像是一款轻量级的HTML或CSS记事本。

  9.Haroopad

Haroopad是一款Linux上的markdown编辑器,使用Chromium作为UI,支持Windows、Mac OS X和Linux。主题样式丰富,语法标亮支持54种编程语言。 如下图所示,一边是代码编辑窗口,一边是预览窗口,可以实时更新。其邮件导出功能可以将文档发送到Tumblr和Evernote。

  10.TiddlyWiki5

TiddlyWiki是一款交互式的wiki,非常灵活,它也可以在浏览器里作为单一的HTML文件或者是一款功能强大的NodeJS应用程序。

TiddlyWiki5是全新设计的5.0版本,它可以直接集成NodeJS解锁一系列的功能,但在单机模式下是不可用的。目前,TiddlyWiki5仍处于测试阶段。

来自: InfoWorld

 

社会拜金对策

一天,一位其貌不扬的男士,带着一位十分艳丽的OL,来到Causeway Bay一家LV店。他为OL选了一价值6万5元的LV handbag。 付款时,男士掏出支票本,十分潇洒地签了一张支票。店员有些为难,因为这对夫妇是第一次来店购物。
男士看穿了店员的心思,十分冷静地对店员说: "我感觉到,您担心这是一张是空头支票,对吗?今天是周六,银行关门。我建议您把支票和handbag都留下。等到星期一支票兑现之后,再请你们把 handbag 送到这位小姐的府上。您看这样行不行?"
店员放了下心来,欣然地接受了这个建议,并且大方的承诺,递送handbag的费用由该店承担,他本人将会亲自把这件事情给办妥。
星期一,店员拿着支票去银行入账,支票果真是张空头支票!愤怒的店员打电话给那位顾客,客户对他说: "这没有什么要紧啊!你和我都没有损失。上星期六的晚上我已经同那个女孩上床了!哦,多谢您的合作。 "

当工作烦燥无聊时候看看这个

jiong

世界朋友感恩节特供,喜欢的朋友顶一下哈

 

另送

中国版“弱密码”TOP25出炉:超7成为6位字符

国外安全机构SplashData最近针对英语人群总结出2011年度最烂、最易被盗取的25个“弱密码”。11月22日,国内最大的网络安全厂商360安全中心也发布了《密码安全指南》,并根据国内流行的密码破解字典软件破解列表,整理结出中国网民最常用的25个“弱密码”。

据360安全专家介绍,中国网民常用的TOP25 “弱密码”中,有9个与国外网民使用习惯完全相同。其中,除password、abc123、iloveyou、qwerty等全球网民通用“弱密码”外,其余均为数字组合。而简单的数字组合,似乎更是中国网民最爱,占了榜单近半数。比如“666666”和“888888”这样的吉利数,几乎是所有中国黑客密码字典中的必备项,而“5201314”(我爱你一生一世)显然被国人寄予了浓厚的感情色彩,为中国特色“弱密码”。

据统计,网民常用的“弱密码”主要包括简单数字组合、顺序字符组合、临近字符组合以及特殊含义组合等四大类别。而从中国版“弱密码”榜单来看,国内网民更习惯设置6位字符密码,TOP25中竟有18个是6位字符,所占比例高达72%。此外,“a1b2c3”和“p@ssword”这类组合型密码看似复杂,其实也在黑客重点关注的密码列表中。

360安全专家警告称,如果系统帐号或其他网络帐号采用上述“弱密码”,很容易被黑客利用密码字典自动“蒙中”,从而造成个人隐私信息泄漏甚至财产损失。针对部分用户为系统设置简单“弱密码”的登录习惯,新版360安全卫士增加了“黑客入侵防护”功能,可以为用户检测近千个弱密码,并在系统遭受入侵攻击时提示用户修改高强度密码。

与此同时,360安全中心还针对中国网民密码使用习惯发布了《密码安全指南》,建议网民从以下四个方面保护帐号安全:

第一、尽量使用“字母+数字+特殊符号”形式的高强度密码;

第二、网银、网上支付、常用邮箱、聊天帐号单独设置密码,切忌“一套密码到处用”;

第三、按照帐号重要程度对密码进行分级管理,重要帐号定期更换密码;

第四、避免以生日、姓名拼音、手机号码等与身份隐私相关的信息作为密码,因为黑客针对特定目标破解密码时,往往首先试探此类信息。

1321938511920

图:中国网民最易被黑客破解的前25位“弱密码”

附:国内外网民常用的25个“弱密码”

国内网民常用的25个弱密码包括:000000、111111、11111111、112233、123123、123321、123456、12345678、654321、666666、888888、abcdef、abcabc、abc123、a1b2c3、aaa111、123qwe、qwerty、qweasd、admin、password、p@ssword、passwd、iloveyou、5201314

国外网民常用的25个弱密码包括:password、123456、12345678、qwerty、abc123、monkey、1234567、letmein、trustno1、dragon、baseball、111111、iloveyou、master、sunshine、ashley、bailey、passw0rd、shadow、123123、654321、superman、qazwsx、michael、football

[译文]史蒂夫.乔布斯是个伪君子

Dusty Wilson 发表了一篇关于史蒂夫.乔布斯 (Steve Jobs) 的评论,转译如下:

丹尼斯.里奇 (Dennis Ritchie) 是 C 语言的共同发明人, 而后者基本上可以说是整个计算机行业的基础. 他也是 UNIX 的共同发明人, 而 UNIX 也是整个计算机行业的基础, 除了 Windows (尽管 Windows 极大得受到了 UNIX 的影响). 苹果的 OS X 是基于 UNIX 的操作系统. 但是, 很多人以为是史蒂夫.乔布斯一个人做了这一切, 所以他是个救世主. 他"借用"他人的想法, 设计和功能, 而当别人这么做的时候他却牢骚满腹. 1996 年, 他说:"我们不知羞耻的窃取伟大的想法. [1]" 2005 年, 他说:"他们无耻的抄袭我们. [2]" 今年, 他说:"我要毁了 Android, 因为它是偷来的. 我不惜为此发动核战. [3]" 而几乎就是紧接着, 他发布了 iOS 5, 而 iOS 5 充满了 Android 中首先出现的功能. 这人就是个混账. 我对于像他这种伪君子毫无耐性可言.
(这是我对下图的回复. 我觉得我也有必要在此分享. 我对此的看法并非什么秘密.)
[1] We have always been shameless about stealing great ideas.
[2] They are shamelessly copying us.
[3] I’m going to destroy Android, because it’s a stolen product. I’m willing to go thermonuclear war on this.
以下为 11 月 5 日的更新:
因为人们在评论前都不看先前的评论 (糟透了!), 因此我在这里附上我的进一步解释.
1) 我的看法是史蒂夫.乔布斯是个伪君子. 这是本文唯一的重点. 他并非孤身一人达到了他的高度. 他窃取他人 (他也承认这点), 而当别人这么做的时候他就牢骚满腹. 这正是伪君子的定义.
2) 我的看法在史蒂夫.乔布斯死之前很久很久就形成了. 我也不打算就因为他死了这点而停止抱怨. 如果这让我变成一个坏人, 那就这样吧. 只要我们还应当在世间享有言论自由, 我会继续善加利用. 只要人们继续分享他们的神圣的史蒂夫的看法, 我也将继续分享我的反对意见.
3) 不准确的话就变成诽谤了. 但是我所说的一切都直接来自他本人. 他曾说他很乐于偷窃, 而后又怒气冲天, 就因为别人也这么做了.
4) 许多人的回复对我的说法添油加醋. 特别是, 有人说我认为史蒂夫.乔布斯或苹果一文不值或是对世界毫无贡献. 这不对, 我从未如此说过. 参见 1).
5) 我有癌症 (但是我战胜了它), 所以别跟我提他的癌症. 我不会为此痛哭流涕的.
6) 有人说我嫉妒苹果. 我有什么可嫉妒的呢? 搞笑.
7) 我认为苹果的问题是他们施加于他们的顾客, 供应商, 开发者和设备的种种限制. 史蒂夫.乔布斯活在控制或被控制的环境中. 而我生在一个共享和相似共享的环境中. 两者全然不搭.
8) 我认为人们应该汲取他人的想法. 否则世界怎么会变好呢? 自私的保有你的想法的意义在哪儿呢? 除了你自己这样还对谁好处? 狗屁.

(本文不代表本站观点,我们每个人都应该有倾听不同意见的度量,不管你是不是果粉,请文明评论)

本站文章除注明转载外,均为本站原创或编译
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区
转载请注明:文章转载自:开源中国社区 [http://www.oschina.net]
本文地址:http://www.oschina.net/news/22898/steve-jobs-is-a-hypocrite

Trick or treat

看到今天好多人都在发万圣节的,我也来发一个~~ 强力版,超级玛丽、机器人总动员、蓝精灵、变形金刚、绿灯侠、钢铁侠

他们遇到南瓜灯后变成了神马! 挑个你喜欢的南瓜灯,大胆呼喊“Trick or treat”!还在犹豫什么

谷歌视频涂鸦:Halloween万圣节快乐

2011-10-31 11:05  来源: webziv.com

今天的Halloween万圣节前夕,Google Doodle在Halloween万圣节到来之前,谷歌涂鸦以6个蓝瓜上面印出万圣节的鬼脸,Halloween万圣节是西方的鬼节,谷歌涂鸦Halloween祝大家万圣节快乐!

Halloween万圣节快乐

在不同的浏览器中,我发现谷歌涂鸦:Halloween万圣节涂鸦不一样,上面Doodle是IE6浏览器上的LOGO,下面是火狐浏览器和Google Chrome上的Halloween万圣节涂鸦,好像是个视频。

Halloween万圣节

Halloween万圣节是西方的鬼节,每年的10月31号,有个Halloween,即是万圣节前夕,谷歌涂鸦值此Halloween万圣节前夕,祝大家Halloween万圣节快乐!

Halloween是All Hallow Eve 的缩写,Halloween是指万圣节(All Hallow‘s Day)的前夕。Hallow来源于中古英语halwen,与holy词源很接近,在北欧的某些区域,万圣节仍然被称为 All Hallow Mas,意思是在纪念所有的圣人(Hallow)那一天,要举行的弥撒仪式,Halloween万圣节也是“鬼节”。

本文出自http://webziv.com/news/1056.html,谢谢大家!

社保卡将全国统一标准 身份证号成社保卡号

核心提示:成都市社保局透露,国家人社部预计在今年内统一发行6亿张社保卡,取代各地自制的社保卡。统一后的社保卡将全部采用身份证号码作为个人参与社会保障的编码。据介绍,新型的社保卡为IC卡,可用于存取支付,简单来说就是社保卡上可直接充值缴费。

今后,全国社保卡将进行统一:身份证号将作为社保卡号,终身不变,跨地区转移就业社保接续障碍有望得到解决。昨日成都市社保局透露,今年7月,国家标准化管理委员会下达的国家标准《社会保险核心业务数据质量规范》的制定工作正式启动,包括成都市社保局在内的8家单位被批准参与起草制定该“国标”。

据了解,国家人社部预计在今年内统一发行6亿张社保卡,取代各地自制的社保卡。届时,成都将根据情况启动社保卡省级换代工作,目前成都正在对社保卡更换进行调研,预计年底形成初稿。

社保卡将全国统一标准

现在的社保卡均为各省、各市州自制,卡的颜色、卡号位数都不相同。“比如我们成都的社保卡就是9位数的自编号,这张卡到省内市州、出省都不能通用,这给社保信息最终实现全国联网、转移接续带来了很大障碍。”成都市社保局有关负责人说,成都参与起草制定“国标”,目的就是实现社保信息的标准化管理,社保卡统一是最明显的特征,只要标准统一了,社保信息全国联网后,在全国任何一个地方,任何一个社保卡都能查询到社保信息,也方便使用。

按照要求,《规范》出来后,我国的社保卡将在全国范围内进行统一,不再出现自编号,全部采用身份证号码作为个人参与社会保障的编码,以方便人员流动。

新社保卡可直接充值缴费

社保卡要实现全国统一,全国通用,参保人员的参保信息就要全国联网。成都社保局有关负责人说,包括参保者的年龄、缴费金额、养老金、参保年限等核心业务数据都将纳入,全国联网,这样有利于参保者在全国范围内的跨地区就业、社保接续转移。该负责人说,有了“国标”后,数据、办理模式统一了。通过记录、跟踪参保人员准确完整的标准数据,真正实现社保服务“记录一生、服务一生、跟踪一生。”

成都人社局信息中心主任周岩说,新型的社保卡为IC卡,与现用的磁卡相比,安全性能更高,并具存储功能,可用于存取支付,简单来说就是社保卡上可直接充值缴费,极大方便参保人员。

(本文来源:四川在线-华西都市报作者: 姚长寿 )

我姐姐让我体验了一次性生活,感觉好低俗

表姐让我体验了一次性生活 表姐今年20出头,虽说不上美女吧,但长的也算上中等了,我们平时很少联系,都是过年过节的时候聚一聚,那天我在商场的餐厅吃饭,正好碰上了她,她刚在商场里买衣服,顺便吃饭,我是个比较内向的人,见了她也不知道说什么,她倒是挺主动的,要请我吃饭,餐厅没啥好吃的,都是快餐,用的都是一次性筷子,一次性纸杯,一次性餐巾,我平时是不怎么来这种地方吃饭,原来这就是“一次性生活”啊,太浪费资源了,我感觉这样不好,我们要爱护环境,尽量不用一次性产品 凡是把“一次性生活”看成了“性生活”的必须留言,并且今年好运连连。

sqlserver 迁移到mysql详细步骤数据库表结构迁移

最近在开发的一个项目,需要从MS SQLServer迁移到MYSQL,以下把迁移过程记录下来,与大家共享!

sqlserver迁移到mysql 在数据库方面的工作主要是表的迁移,以及存储过程的迁移,这里先说说表的迁移.

首先先将MSSQL Server表结构导出为.sql文件. 表迁移,mysql一律不能运行带有[,],dbo.等带有sqlserver特征的脚步, 所以在导出的sqlserver脚步里面,首先要把这些字符全部过滤掉(可使用editplus进行过滤),在表创建方面的不支持的字符如下:[,],[dbo].,GO, on primary,.

在过滤完以上的字符后, 由于导出的sql文件都包含多个表, 为了能够一次性装载完所有的scripts并运行,需要在每个表的create语句后面加上分号, (同时还有加上ENGINE=InnoDB),否则你会发现只能一个一个表的进行运行,比如原来是这样:

CREATE TABLE bmapnamebidsg (
bword nvarchar (100) NOT NULL ,
bids text NULL ,
status int NOT NULL ,
cr_date datetime NOT NULL
)

CREATE TABLE BookStaticSortStatus (
sid int NOT NULL ,
sortStatus int NOT NULL ,
mxReviewStatus int NOT NULL ,
lReviewStatus int NOT NULL ,
up_date datetime NOT NULL
)

改动后是这样的:

CREATE TABLE bmapnamebidsg (
bword nvarchar (100) NOT NULL ,
bids text NULL ,
status int NOT NULL ,
cr_date datetime NOT NULL
)ENGINE=InnoDB ;

CREATE TABLE BookStaticSortStatus (
sid int NOT NULL ,
sortStatus int NOT NULL ,
mxReviewStatus int NOT NULL ,
lReviewStatus int NOT NULL ,
up_date datetime NOT NULL
)ENGINE=InnoDB ;

接下来就是数据类型了!

在数据类型方面,mysql基本对应了sqlserver的数据类型, 向bit,text,varchar,等,都对应得比较好, 但是,mysql并不支持smalldatetime(这个是sqlserver特有的),需要转成datetime,另外, sqlserver中的identity自增长属性在mysql中则表现为auto_increament属性,并且声明该属性的列必须是key!

最后我们看看主键,索引以及缺省值如何对应,一些是MS SQLServer(建一个主键,为两个字段定义缺省值,再为一个字段定义成索引):

ALTER TABLE BookStaticSortStatus WITH NOCHECK ADD
CONSTRAINT PK_BookStaticSortStatus PRIMARY KEY CLUSTERED
(
sid
)

ALTER TABLE BookStaticSortStatus ADD
CONSTRAINT DF_BookStaticSortStatus_status DEFAULT ((-1)) FOR sortStatus,
CONSTRAINT DF_BookStaticSortStatus_up_date DEFAULT (getdate()) FOR up_date

CREATE INDEX [sort2_books] ON [dbo].[books]([s2id]) ON [PRIMARY]

MySQL:

CREATE TABLE `bmapnamebidsg` (
`bword` varchar(100) character set utf8 NOT NULL default ‘1’,
`bids` text NOT NULL,
`status` int(11) NOT NULL,
`cr_date` datetime NOT NULL,
PRIMARY KEY (`bword`),
KEY `bids` (`bids`(1))
) ENGINE=InnoDB DEFAULT CHARSET=latin1

完成以上动作,表结构的迁移就基本完成了!

【UCHome二次开发】模板解析

UCHome模板文件位于/template文件夹下,每个模板文件单独一个文件夹,默认模板文件夹为default。

1、模板的使用配置

在根目录下的config.php中进行配置,确定系统使用的模板,如下:

1

$_SC['template'] = 'default'; //选择模板目录

2、模板的处理

程序中使用到模板文件时,先去模板缓存目录/data/tpl_cache/下查找是否存储模板缓存文件。模板缓存文件命名合适为 “template_模板目录名_模板文件名.php”。如存在则直接使用该缓存的模板文件;如不存在,则先解析对应的模板文件,生成模板缓存文件再进行使用。

3、模板的解析

模板解析是调用/source目录下的function_template.php文件中的parse_template函数来实现的。

解析过程并不复杂,主要是读取模板文件(.htm),用正则表达式替换标记为对应的PHP代码,最终生成一个标准的PHP文件,保存到模板缓存目录/data/tpl_cache/供后续使用。

具体的模板解析过程不做说明,直接查看代码即可。

function parse_template($tpl) {

global $_SGLOBAL;

//包含模板

$_SGLOBAL['sub_tpls'] = array($tpl);

$tplfile = S_ROOT.'./'.$tpl.'.htm';

$objfile = S_ROOT.'./data/tpl_cache/'.str_replace('/','_',$tpl).'.php';

//read

$template = sreadfile($tplfile);

if(empty($template)) {

exit("Template file : $tplfile Not found or have no access!");

}

//模板

$template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie", "readtemplate('\\1')", $template);

//处理子页面中的代码

$template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie", "readtemplate('\\1')", $template);

//解析模块调用

$template = preg_replace("/\<\!\-\-\{block\/(.+?)\}\-\-\>/ie", "blocktags('\\1')", $template);

//解析广告

$template = preg_replace("/\<\!\-\-\{ad\/(.+?)\}\-\-\>/ie", "adtags('\\1')", $template);

//时间处理

$template = preg_replace("/\<\!\-\-\{date\((.+?)\)\}\-\-\>/ie", "datetags('\\1')", $template);

//头像处理

$template = preg_replace("/\<\!\-\-\{avatar\((.+?)\)\}\-\-\>/ie", "avatartags('\\1')", $template);

//PHP代码

$template = preg_replace("/\<\!\-\-\{eval\s+(.+?)\s*\}\-\-\>/ies", "evaltags('\\1')", $template);

//开始处理

//变量

$var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";

$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);

$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);

$template = preg_replace("/(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/s", "\\1['\\2']", $template);

$template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);

$template = preg_replace("/$var_regexp/es", "addquote('<?=\\1?>')", $template);

$template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "addquote('<?=\\1?>')", $template);

//逻辑

$template = preg_replace("/\{elseif\s+(.+?)\}/ies", "stripvtags('<?php } elseif(\\1) { ?>','')", $template);

$template = preg_replace("/\{else\}/is", "<?php } else { ?>", $template);

//循环

for($i = 0; $i < 5; $i++) {

$template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies", "stripvtags('<?php if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\\3<?php } } ?>')", $template);

$template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies", "stripvtags('<?php if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\\4<?php } } ?>')", $template);

$template = preg_replace("/\{if\s+(.+?)\}(.+?)\{\/if\}/ies", "stripvtags('<?php if(\\1) { ?>','\\2<?php } ?>')", $template);

}

//常量

$template = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s", "<?=\\1?>", $template);

//替换

if(!empty($_SGLOBAL['block_search'])) {

$template = str_replace($_SGLOBAL['block_search'], $_SGLOBAL['block_replace'], $template);

}

//换行

$template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);

//附加处理

$template = "<?php if(!defined('IN_UCHOME')) exit('Access Denied');?><?php subtplcheck('".implode('|', $_SGLOBAL['sub_tpls'])."', '$_SGLOBAL[timestamp]', '$tpl');?>$template<?php ob_out();?>";

//write

if(!swritefile($objfile, $template)) {

exit("File: $objfile can not be write!");

}

}

本文链接:http://witmax.cn/uchome-template-analysis.html

Doodle:雕塑大师亚历山大·考尔德诞辰 113 周年

感谢读者 轩辕十四 的提醒。

image

鼠标拖动产生动态效果,下面的影子也同时变化……雕塑大师亚历山大·考尔德诞辰 113 周年

静态图片地址:http://www.google.com.hk/logos/2011/calder11.png

这是一个动态doodle,可用鼠标拖动,同时在搜索框下方看到同步变化的光影效果。其实去年Google就用同样的图片纪念过历山大·考尔德112周年,但一年之后的今天,他们将其进化到了更高级的动态形式。

亚历山大·考尔德(1898.7~1976.11)出生于美国费城,他的父亲以及祖父都是雕塑家。1919年,考尔德在新泽西州霍普肯史蒂文斯理工学院的机械工程系毕业,打下以后从事活动雕塑的 发明与设计的基础。1922年,他去纽约业余学习绘画。翌年,加入了美国“垃圾箱”画派领导的艺术学生联合会。真正从事雕塑,大约是在1926年去巴黎之 后。他在欧洲现代派雕塑的鼓舞下,开始用铁丝、木头等来制作玩具动物,把制成的动物组成一个微型“马戏班”,并公开展出,引起了人们的兴趣。接着,考尔德 又用金属线制作真人大小的模特儿。1930年,荷兰的蒙德里安画室给了他很大的启示,他开始思考艺术的抽象化问题。1931~1932年,他创作了许多由 机器牵动的雕塑品,受到杜桑的鼓励。至1937年,他为巴黎世界博览会西班牙馆设计了一件《水银喷泉》,以流注的水银冲击连在旋转杆上的金属板,成为他第 一件真正的“活动雕塑”作品。这一件纵横有259×290厘米大的活动雕塑《虾笼子与活动鱼尾》,是他在此基础上于1939年新设计的大型活动雕塑代表作之一。

考尔德是美国最受欢迎、在国际上享有崇高声誉的现代艺术家,是20世纪雕塑界重要的革新者之一。

UCenter中上传头像功能的剥离

UCenter中上传头像功能的剥离

本文的内容仅供技术交流学习之用,相关的代码并未考虑实际应用系统中所必需的用户身份验证等功能,同时由于 UCenter 发行许可的限制,请勿将本文附带的代码直接用于实际的产品或项目中。
Discuz! 和 UCHome 中的头像上传功能很好用,大概有不少人和我一样想弄清楚它是怎么实现的,甚至希望移植到自己的应用系统中。
这个功能其实是在 UCenter 中实现的(这是 Discuz! 和 UCHome 等其它相关产品都依赖的公共模块),通过一个 Flash 文件(camera.swf),跟服务端的 PHP 程序配合完成的。
UCenter/UCHome 本身是开源的,但那个 camera.swf 并没有提供源代码。我们可以通过对 PHP 程序进行分析研究,进而基本摸清这个功能操作的细节,并最终将其剥离出来,独立于 UCenter 而独立运行。本文内容依据的是 UCenter1.5.0/UCHome2.0 。
首先我们来看一下 UCenter/UCHome 中这个功能是怎么工作的。
基本步骤
0. 浏览器访问 UCHome 中的一个 web 页面,其中包含 camera.swf。为保证 camera.swf 能正常工作,在其相同的路径下需要有 locale.xml 文件。
装载 camera.swf 的 HTML 代码可以由下面的程序生成:
home/uc_client/client.php : uc_avatar()
生成的内容大致如下:
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="447" height="477" id="mycamera" align="middle">
<param name="allowScriptAccess" value="always" />
<param name="scale" value="exactfit" />
<param name="wmode" value="transparent" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<param name="movie" value="http://localhost/center/images/camera.swf?inajax=1&appid=1&input=6b49vKhr%2FC4VpMIMCAt07Kr2eQk8jjY%2F6vtvDonod47dU7JK%2BxVFJPIVY%2FJGMQoSpzHylapBa8FbsEWFGorPwZDJRM10wGjxvbHKTVmVgrng%2BpoSTTsk%2BE3U&agent=a523e70c80e13e4eaee37c7f4bde4f2c&ucapi=http%3A%2F%2Flocalhost%2Fcenter&avatartype=virtual" />
<param name="menu" value="false" />
<embed src="http://localhost/center/images/camera.swf?inajax=1&appid=1&input=6b49vKhr%2FC4VpMIMCAt07Kr2eQk8jjY%2F6vtvDonod47dU7JK%2BxVFJPIVY%2FJGMQoSpzHylapBa8FbsEWFGorPwZDJRM10wGjxvbHKTVmVgrng%2BpoSTTsk%2BE3U&agent=a523e70c80e13e4eaee37c7f4bde4f2c&ucapi=http%3A%2F%2Flocalhost%2Fcenter&avatartype=virtual"
quality="high"
bgcolor="#ffffff"
width="447"
height="477"
name="mycamera"
align="middle"
allowScriptAccess="always"
allowFullScreen="false"
scale="exactfit"
wmode="transparent"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
参数分解如下:
inajax 1
appid 1
input 6b49vKhr%2FC4VpMIMCAt07Kr2eQk8jjY%2F6vtvDonod47dU7JK%2BxVFJPIVY%2FJGMQoSpzHylapBa8FbsEWFGorPwZDJRM10wGjxvbHKTVmVgrng%2BpoSTTsk%2BE3U
agent a523e70c80e13e4eaee37c7f4bde4f2c
ucapi http://localhost/center
avatartype virtual
其中的关键参数为 ucapi,后面两步 POST 的 URL 为 <ucapi>/index.php
这里的 "/index.php" 似乎是 hardcode 在 camera.swf 里的,不过在最后的程序代码中会看到,如果我们指定的 ucapi 明确给定了一个 php 文件的话,可以绕开 index.php 这个文件名。换句话说,如果服务端不是采用 PHP,而是另外一种编程语言的话(比如 Java/.NET 等),也是可以实现的。
1. 用户在 camera.swf 中"选择图片"后,camera.swf 会立刻把选中的图片上传到服务器。
$_SERVER
REQUEST_URI /center/index.php?m=user&inajax=1&a=uploadavatar&appid=1&input=ca68o1L41a1HkbmhMJVGHu0oFjxYXwadnUT9HnFpnyz5AgiZcsVGecPP38w%2BwM7XtT79zC5WMWlH8T7LvluCSXS3YUsrcJDoD1ySILNO2xo63hmBAvXVX24f&agent=a523e70c80e13e4eaee37c7f4bde4f2c&avatartype=virtual
METHOD POST
$_GET
m user
inajax 1
a uploadavatar
appid 1
input ca68o1L41a1HkbmhMJVGHu0oFjxYXwadnUT9HnFpnyz5AgiZcsVGecPP38w+wM7XtT79zC5WMWlH8T7LvluCSXS3YUsrcJDoD1ySILNO2xo63hmBAvXVX24f
agent a523e70c80e13e4eaee37c7f4bde4f2c
avatartype virtual
$_POST
Filename something.jpg
Upload Submit Query
$_FILES
图片文件内容
处理程序为:
center/control/user.php : onuploadavatar()
程序返回的内容为保存该文件的临时位置,比如:
http://localhost/center/data/tmp/upload5.jpg
camera.swf 会通过上面这个网址来读取图片,显示供操作。还可以有以下返回值作为错误代码:
-1 : Invalid identity!
-2 : Invalid photograph!
-3 : No photograph be upload!
-4 : Can not write to the data/tmp folder!
-5 : Server can not upload!
2. 用户在 camera.swf 中"确定"后,camera.swf 会向服务器上传 3 个图片数据,作为大、中、小尺寸的头像图片。
$_SERVER
REQUEST_URI /center/index.php?m=user&inajax=1&a=rectavatar&appid=1&input=ca68o1L41a1HkbmhMJVGHu0oFjxYXwadnUT9HnFpnyz5AgiZcsVGecPP38w%2BwM7XtT79zC5WMWlH8T7LvluCSXS3YUsrcJDoD1ySILNO2xo63hmBAvXVX24f&agent=a523e70c80e13e4eaee37c7f4bde4f2c&avatartype=virtual&randomnumber=5478
METHOD POST
$_GET
m user
inajax 1
a rectavatar
appid 1
input ca68o1L41a1HkbmhMJVGHu0oFjxYXwadnUT9HnFpnyz5AgiZcsVGecPP38w+wM7XtT79zC5WMWlH8T7LvluCSXS3YUsrcJDoD1ySILNO2xo63hmBAvXVX24f
agent a523e70c80e13e4eaee37c7f4bde4f2c
avatartype virtual
randomnumber 5478
$_POST
avatar1 …<big>
avatar3 …<middle>
avatar2 …<small>
处理程序为:
center/control/user.php : onrectavatar()
程序的返回内容为:
成功时: <?xml version="1.0" ?><root><face success="1"/></root>
失败时: <root><message type="error" value="-1" /></root>
3. 上传完成后,如果 camera.swf 能找到名为 updateavatar() 的 Javascript function,就会调用它。
参数分析
在上面第 0 步生成的 HTML 中,指向 camera.swf 的 URL 携带了一些参数,其中最关键的是 ucapi,它决定了第 1 步和第 2 步的 HTTP Request 发往哪里。
其它几个都是 UCenter 应用系统所需要的参数。camera.swf 是专为 UCenter 设计的,所以它特别支持这几个参数值,也就是说,在访问 camera.swf 的 URL 里包含了什么值,在后续访问 ucapi 的时候就会原样传回来。
camera.swf 没有提供源代码,没办法改造,但并不妨碍我们使用它。比如,我们可以借用 input 这个参数,把自己应用程序所需要的自定义参数(比如 user id)统一编码装在这个值里。
剥离实现
搞清楚了功能操作的细节和参数含义,重新实现这个功能就很容易了。
所谓重新剥离实现,就是在直接借用 camera.swf/locale.xml 这两个文件的前提下,重新编写服务器端的处理程序,实现头像上传功能,脱离 UCenter 独立运行。
理论上任何服务端编程语言都可以,我这里只给出 PHP 的代码。
包含了三个程序文件:
avatar.php — 实现了上面"基本步骤"中提到的全部功能
camera.swf — 提取自 UCenter
locale.xml — 提取自 UCenter
将这三个文件部署到 web server 上,然后访问 http://localhost/avatar.php 即可。还可以在 URL 上指定一个 uid 作为"用户标识",比如 http://u.liyunde.org/avatar.php?uid=1

程序下载地址: http://maquan.download.csdn.net/

哪个器官在激动时会变大6~7倍

临床医学课上,男老师问:哪个器官在激动时会变大6—7倍?他点了个女生回答,该女生憋了半天红着脸说:我拒绝回答!老师无奈点一男生回答,男生答:瞳孔。老师说:正确!后对那女生说:我有三句话提醒你,一是你没有预习课的内容;二是你又在胡思乱想;三是你婚后会非常失望!

服务员冲厨房喊道:"出来个师傅,帮这位顾客把这块牛肉切一下!"

男子喊道:"服务员,过来一下!" 服务员:"您好,什么事?" 男子怒问:"我20块钱一碗的牛肉面,怎么才一块牛肉?" 服务员:"先生,那您希望有几块?" 男子想了想说:"怎么也得五六块牛肉吧。" 服务员冲厨房喊道:"出来个师傅,帮这位顾客把这块牛肉切一下!"

爱情观与四大名著的关系

【爱情观与四大名著的关系】1)爱情,就像三国,合久必分,分久必合;2)爱情,也像西游,九九八十一难,方才取得真爱;3)爱情,更像红楼,总有一群人对它高山仰止,耗费毕生研究它;4)爱情,最像的还是水浒,不管你有多轰轰烈烈,最终都得被生活招安。

标准的贱男淫!

半夜喝醉回来,趁老婆熟睡的时候,憋足了全身力气一脚将其踹到床下··接着极其愤怒地破口大骂:“去你妈的!老子是有老婆孩子的人!”然后倒头继续装睡。第二天早上,老婆忍着伤痛不仅没责备昨晚醉酒,还端来热气腾腾的牛奶,其中一半都是感动的眼泪·(到底是谁想出这么损的招?)

留意留意!!有没有这样的人?外表活泼内心孤僻的人会做的事

【外表活泼内心孤僻的人会做的事】1手机不离身;2对待不同的人有不同的性格;3从小懂得很多道理;4有时候很神经 有时候很镇静;5会因为别人一句话伤心 但不会被发现;6安慰很多人 但自己却没人安慰;7会怀念从前 讨厌现在;8有时候会笑的没心没肺 有时却很沉默。你是这样吗?

24个很酷的 CSS3 文本效果示例及教程

CSS3 是对 CSS 规范的一个很大的改善和增强,它使得 Web 开发人员可以很容易的在网站中加入时尚的效果。今天这篇文章收集了24个很棒的 CSS3 文本效果示例及教程分享给大家。

Text with Moving Backgrounds

Flashlight (Works in Safari only)

CSS3 Text Masking Effect

Tilt-Shift Effect on Text using CSS3

Free Overlapped CSS Menu Using CSS Sprites

Create a Cool Anaglyphic Text Effect with CSS

Shadows and CSS3

Create a Letterpress Effect with CSS Text-Shadow

Text Embossing Technique With CSS

CSS textured text

CSS Gradient Text Effect

Create Beautiful CSS3 Typography

The Neon Lights Text Effect

Create a Vibrant Digital Poster Design with CSS3

CSS 3 Transform Experiment

Glass Text Effect (refractive index) with CSS3

CSS3 Background-Clip & @Font-Face

CSS3 Trans-forms & @font-face Experiment

CSS3 Poo Fly

iPhone “slide to unlock” Text in WebKit/CSS3

Fun With CSS Text-Shadow

LETTERING.JS

Neon Text Effect With jQuery & CSS

CSS Poster: Three Laws of Robotics

(来源:梦想天空 国际来源:20+ Amazing CSS3 Text Effect Tutorials and Experiments

ifttt、GGG与网站图谱

尽管伯纳斯·李(Tim Berners-Lee)在发明WWW之初,心中就有一个GGG(Giant Global Graph)的宏大梦想,但是直到Google的网页图谱、尤其是Facebook的社交图谱、Twitter的兴趣图谱之后,人们才真正意识到图谱的网络效应魔力。

不过这仍然未及伯纳斯·李的预期,他理想中的GGG是一张数据的图谱、服务的图谱,而不仅仅是网页、人或兴趣。直到ifttt横空出世,欲以API打造横跨整个互联网的网站图谱,才终于接近了GGG这一终极目标。

ifttt之前的互联网

尽管伯纳斯·李发明了WWW,但他本人却不愿意使用WWW或是web这样的词汇,而是更愿意使用GGG或是graph。

WWW无疑是革命性的,但其最大的问题是,WWW这张大网中的节点是网页或者说文档,文档提供信息,WWW连接的所有文档将提供海量信息、和信息重用。但是在这个信息严重过量、互联网从信息的网向数据的网转型、从文档的网向服务的网转型的时代,WWW已不再重要,GGG才是王道。

比如,一位驴友为了安排旅游计划,需要费时费力地搜索机票、酒店、旅游景点、攻略等信息,但是这位驴友真正感兴趣的不是包含这些信息的网页/文档,而是这些信息、数据、服务本身。从一个用户的角度出发,其目的其实非常简单:找到最物美价廉的旅行计划并预定。

在以Google为翘楚的网页图谱时代,这些信息分散在各个网页里,而“人”必须手动做很多信息搜索、过滤、决策、执行的工作,才能最终基于这些信息完成任务。

ifttt之后的互联网ifttt的问世,最终实现了人们这一简单至极却又复杂无比的梦想。

如果说Google编织的是网页的网,那么ifttt编织的则是网站、应用或服务的网。ifttt能利用各网站或应用提供的API,将所有服务聚合起来,为用户提供自动的、个性化的服务。

ifttt示例

ifttt示例

ifttt里包括任务、触发器、反应器(动作)三个部分,结构为 if this then that ,或者说 if _ then _ 。用户所需的操作很简单,设定任务,再设定触发器即可;当条件满足时,任务将自动完成。

回到上面那个驴友的例子,如果有了ifttt或是ifttt山寨(前提是要有足够多的国内服务),他只需设定诸如“7月7日至7月9日北京至中国死海的最便宜旅行套餐,下单截至时间为7月6日12:00”,然后ifttt将自动为其完成任务。多么诱人的前景!

ifttt、GGG与网站图谱 ifttt的网站图谱,非常接近伯纳斯·李一直以来梦想的GGG,即互联网是数据和服务的Graph,能自动帮人完成任务。

但又不尽然,尽管功能非常相似,但ifttt与GGG的架构却有着很大不同。

ifttt的网站图谱,貌似天下大同但终归还是一家公司的产品和服务,如今互联网业界对Facebook一家独大的担忧已经很重了,我们没理由再需要一个更为强大和恐怖的终极版Facebook。

而伯纳斯·李心中的GGG指的是整个互联网,绝非某一家或几家网站。

他所想的GGG的架构,是分散的、开源的,就像互联网本身那样。但是,这却与以公司为主导的商业运作有着天生的矛盾,公司都想的是架构、数据、服务为自己所有,因为那是利润机器。

如此看来,ifttt的诞生,意味着互联网的GGG之路才刚刚开始。

文章来源:雷锋网

2011年6月28日搜索引擎收录变化数据(百度大更新)

今日大约92.60%的网站百度收录有变动,其中47.42%的网站收录数量增加,45.18%的网站收录数量下降;谷歌更新了73.40%的网站收录数量,其中39.62%的网站收录增加,33.78%的网站收录数量下降;今日谷歌PR更新比率达到 51.23% ,35.49% 的网站增加了PR,17.75%的网站PR被减少。 此数据我们每天都有一份全新的报表发布在站长俱乐部(BBS.CHINAZ.COM),帮助站长了解搜索引擎变化规律。 数据来源:从站长工具每天几十万的网站查询数据和MYTOOL.CHINAZ.COM里的监测数据抽样结果,以上数据全部真实有效,每天更新,欢迎各位登录体验。

31天打造更好的博客》节选

注明:本文节选自《31天打造更好的博客》内容的第十六天与第十七天,编译作者许岑。

第十六天的任务:

写一篇文章来解决你读者(或者潜在的读者)的问题

这项任务,是每一个成功的博主在他们每一天写博时所做的。为什么呢?如果你解决了他们的问题,你就会给他们带来一个很好的印象。因而人们就更愿意重访你的博客,并且他们也更愿意向他们的朋友推荐你的博客。

那么怎样找到问题呢?

对于某些博主们来说,找到他们读者的问题要容易得多——因为他们的读者众多,因而轻而易举的便能够找到读者的问题。我在这里教大家一个小窍门,来帮助那些并没有太多读者的博客新手们。

7种找到问题的方法

1、 解决你自己的问题

我比较喜欢的一种找到问题的方法就是记下自己的问题。以我的经验来说,当我遇到了某一个问题,别人很有可能也会遇到。所以,不要仅仅是解决了你的问题就不管了,相反的,为什么你不把它记录在博客上,这样他人也能得到帮助呢?

我的一个粉丝最近在Twitter问我应该如何开始写她的博客。她有一点点焦虑,并且不知如何下手去开始她的博客之旅。我的答案是:记下她遇到的问题然后还有解决方法。没有比这更好的方法去开始写博客——从第一天开始,你的读者会有这样的印象:你是一个爱解决问题的人。

2、 从你的网站统计中查看搜索来源

当你的博客已经上线一阵子后,你已经有很多方法可以定位读者的问题并借此加强与读者的关系。但是当读者不告诉你他们的需要和问题时,你可以看看他们是为什么、又是如何来到你的博客的。你可以查看你的网站统计,这在前面的课程中已经讲到。大多数时候,那些被搜索最多的词的话题应该就是人们的问题所在。

3、 分析站内搜索

另一个类似的方法来找到你读者的需求就是看看他们在你的博客上搜索了哪些词。这对你来说是非常重要的,因为借此你可以发现哪些东西是你的读者有问题而你又没有涉及到的。(注:原文中ProBlogger推荐了一个工具可以统计站内搜索的关键词并可以得到搜索量数据,该工具网址是http://www.lijit.com/,不过我没有测试是否支持中文。不知道强大的WordPress是否有插件可以担当此任?)

4、 直接向你的读者提问

另一个方法就是直接向你的读者们提问,看看他们有哪些需求,哪些问题,哪些困扰。这个方法的前提当然是你已经有了足够多的读者,并且他们也很乐意给你相应的回应。这个方法可以这样进行:

1)写一篇文章来向读者提问;

2)给最近的、留言比较多的读者写Email,问问他们是否有问题;

3)建一个相关的页面作为问答互动

4)对你的读者们做一个调查

5)在侧边栏添加一个投票栏目来看看哪些问题是比较普遍的。

上面的5种方法我都有试过,而且我相信每一个都值得你花时间去做。

5、 去其他的站点寻找问题

这个方法很适合于那些没有多少读者的博客新手们,他只需要你去找一个与你博客主题类似的论坛,或者一个博客或者社交网络,然后静下心来去从中发现人们提了哪些问题。

你应该集中你的全力把这项工作花在那些大型的站点,只有如此你才能得到足够多的问题。而一旦你花了时间研究后,你就会发现在这些站点上,其实有些同样的问题被问了一遍又一遍。

6、 通过社会化的媒体来收集问题

最近一段时间来,我越来越多的通过像Twitter这样的社会化媒体来获得文章的灵感。Twitter确实是一个获取人们实际需要和问题的绝佳地方!通常,我会这样做:

1、向大家提问——时不时的,我会在twitter上向大家提出一些问题,以此来作为下一篇文章的基础。

2、关键词跟踪——在twitter上,我会使用TweetDeck这个软件来设定一些我需要关注的关键字,然后来看看人们都在讨论什么,或者有哪些疑问。

7、 询问朋友和家人

最后,不要忘了你现实中的朋友、家人和同事。许多日常的交谈其实包含了人们面对的很多问题和挑战。不过,你在文章中要记得为这些谈话保密。

有些时候,家人的聚会也是对我写文章有帮助的:有一次,我的一个亲戚问我他拿相机的姿势是否正确。他问我这个问题时,其实是有些小尴尬的——因为这个问题似乎有点太基础了。当我回答他的时候,我意识到其他一些初学摄影的人其实也有可能面对这些困惑,因此——《如何正确的握住相机》便应运而生。

第十六天的小贴士:

一种解决高级一点问题的方法就是让这一领域的其他高人帮助你!举个例子,我的另一个摄影博客就常常遇到别人问我的问题,我自己无法回答——因为我并不是一个专业摄影师,即使我是专业摄影师,那也不可能我精通摄影的每一个问题。

所以,当这样的问题发生时,我就会去向这方面的专家求助。我会询问以下三个问题中的一个:

1) 你能为我的博客就那个问题写一篇客座文章吗?

2) 你介意就那一问题对你进行采访吗?

3) 你方便就那一问题回答以下吗?

我一般会从第一个开始询问他们,这取决于他们是否有足够的时间。如果他们抽不出空,或者不愿意,我就会另寻他人。

另一个方法是,把你问到的答案融合到一篇文章中,比如你询问了5个人,那么就整理一下,写成一篇文章。这种方法,可以使某个问题具有多角度性。

你博客的新来访者会在数秒之内决定他是否会再来,如果再来,会怎样使用你的博客。与你现实中的第一次见面一样,这种互联网上的第一印象也是极其重要的。

第十七天的任务

做一些调查,看看那些第一次来访你的博客的人们对你博客的第一印象。

你需要的

一个朋友,家人,同事,甚至是以前没怎么打过交道的博友。这项任务的关键就在于这些人要保证他们以前没怎么看过你的博客。

最好是能和他面对面的交流,但是如果情况不允许,也可以虚拟的在网络上进行交流。

过程

让你的朋友打开你的博客并且浏览个四五分钟,期间不要去和他闲聊。

仔细的观察他们是如何浏览你的博客:

1、 他们的浏览轨迹是如何的?

2、 哪些地方他们点击?

3、 哪些地方他们停下来阅读?

4、 哪些地方直接就跳过去了?

5、 博客的哪些地方看起来对他们最具有吸引?

当他们浏览完毕后,试着问问如下的问题:

1、 第一印象如何?

2、 当他们第一次打开你的博客,对你的博客第一想法是什么样?他们认为你的博客是干什么的?

3、 他们觉得你的博客便于阅读,导航,理解吗?

4、 他们对你的博客有哪些建议?

5、 他们浏览完你的博客,会存在哪些疑问?

6、 他们会用哪些词来形容你博客的设计?

7、 当10分钟过后,他们对你博客的记忆是在哪方面?

8、 站在用户的角度,他们有哪些建议?

PS. 最近一次我使用上面的方法,我邀请了四位朋友来进行。这四位朋友分别属于不同的层次,有完全不怎么上网的人,也有跟我差不多水平的专业博主。从这些不同的人士中,我得到了很有用的反馈。

今天的小贴士:

对于那些手动能力强的博主来说,你也可以加入一段Javascript代码看看人们在你博客上最多点击的是哪一块内容。这个小工具的网址是http://crazyegg.com/ 。(注,在中文中,这种服务称之为热力图,如果没有记错的话,百度统计好像是有的)

当然,这种热力图不会给你所有的信息,所以如果可以的话,我建议你还是按照上述的方法去实实在在“采访”几个人。

通过和他们的交流,你可以从博客布局、版式等设计的方面和内容方面来看看他们的评价与建议。

文章来源:http://www.chanue.com/

文章作者:许岑(转载请注明出处链接及作者)

Evan Williams:域名已死 有事烧纸

最近,我们在讨论一个产品命名的时候,有人问我,现在一个完美的域名是否已变得不再重要?作为一个被域名折磨多年的人来说,我不得不承认域名真的已经不再重要,并且将越来越无关轻重,理由至少有如下五条:

1)Google

你还记得上一次说出朋友们或者亲戚的电话是猴年马月吗?你还记得上一次准确写出邮件联系人的确切地址是多久之前吗?对我来说,不用汽车导航穿过整座城市已经是很久之前的事了。软件已经代替了大脑,替我们完成诸如此类的工作。域名和电话号码和Email地址类似,唯一的标识让电脑比人脑更有优势。(尽管对人类来说,域名是可读的IP地址,但是电脑依然可以更好的处理和记忆域名。)

如果你在你的电邮界面地址框中输入:张三,它会给你提供很多你之前联系过的“张三”的地址,你基本可以在这些地址中找到你想联系的那个“张三”。如果自动联想失败,你会找到该地址并将它复制到地址框中。在这个过程中,你根本不会在意这个电邮地址究竟是什么。

很多人这样用google。当我第一次看到人们在google中搜索“yahoo.com”以登陆雅虎网站时,我震惊了。就像这条博客留言一样,成千上万的用户通过在google中输入“facebook login”登陆Facebook,google才是大家上网的入口。我很希望这不是真的。但是,google的确就像所有网站的入口一样。不对,google只是这些入口其中之一。

2)自动完成地址框

对那些更高级一点的用户来说,浏览器地址框的自动完成功能替我们记住了各种网站地址–哪怕那些我们只登陆了一到两次的网站。事实上,google在Chrome浏览器的地址框做了完美的整合。有了Chrome,你啥都不用记。

3)移动浏览器和隐藏地址框

我们之所以在意域名,是因为我们打开什么页面都能看到相应的地址。当然,在移动设备上并非如此。因为页面有限,移动设备上的浏览器地址栏往往被隐藏了。当我们打开一个页面的时候,往往看不到它的地址。

出于简化设计的考虑,google很有可能将隐藏地址栏引入桌面浏览器(当我写这些的时候,我很想知道google是否有个秘密计划要将域名做掉并取而代之。)

4)应用程序

上一条理由中,我们谈论了用户手机上网的问题。但是大家现在不太关心域名的原因是:大家都开始用APP了。从我个人角度来说,我不认为未来是完全属于APP的。但是应用程序侵蚀了用户本来花在浏览器上的时间。现在基本每个APP都会对应一个网站,但是由于大家都是通过应用商店来安装这些APP,所以域名也就无关轻重了。

5)小众域名的兴起

拥有一个理想的.com域名越来越不重要,因为大家有了其他选择。传统上,大家认为只有.com的网站才算是正统的网站。据我了解,在从前,大家对类似.biz或.cc的域名没什么兴趣。当你见到这些域名的时候,也许还会对其正规与否产生怀疑。但是现在,你不会再这样了。

Del.icio.us可谓是域名变革的先驱,其域名选择也让极客们称赞(尽管如此,Yahoo还是指出Del.icio.us太难输入)。Bit.ly让.ly域名在诸多新兴网站中流行起来。About.me让.me域名成为其网站名称的一部分,与之相似的还有Last.fm和最近风头正渐的turntable.fm。

有缺陷的.com域名也变得可以接受。例如,Facebook曾使用过thefacebook.com域名。Dropbox曾用过getdropbox.com。很明显的,我们可以得出结论,网站成功与否和域名是否理想已经没啥必然联系了。

37 Signals是最早如此认为的公司之一。当时其有一款产品叫Basecamp,但是使用的域名是basecamphq.com。现在,这种设计优良,但却使用一个“烂”域名的产品越来越多。

因为这些事例,人们的想法改变了。

我不知道当新的顶级域名发布的时候会如何。我只知道我们将鉴证更多非.com域名的成功。这对于那些创业者们来说是好事。因为如果他们追求理想的.com域名,哪怕该域名没有被使用,哪怕忽略域名高昂的售价,光是联系域名持有者和讨价还价的繁琐过程也让人不堪忍受。

结论:品牌比域名重要很多

虽然一个好的.com域名依然价值不菲,但是它已经不像过去那么重要了。并且随着科技的进步,域名的作用将越来越小(特别是移动互联网相关的项目)。如果我需要选择一个域名,我当然会优先考虑一个合适的.com域名,但是这已经不是必需品。

另外一个角度来说,产品和品牌,依然是非常重要的(在互联网企业尤为如此)。太多的创业企业为了和域名匹配,不得已选了一个愚蠢的名称。令人欣慰的是,随着浏览器、应用程序等方面的发展,这样的悲剧将越来越少。

by Evan Williams

(lee 供雷锋网专稿,转载请注明!)