程序人生:做技术,切不可沉湎于技术

[1]好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,

逐渐对该行业深入了解,不要频繁跳槽,特别是不要为了一点工资而转移阵地,从长远看,这点钱根本不算什么,当你对一个行业有那么几年的体会,以后钱根本不是问题。频繁地动荡不是上策,

最后你对哪个行业都没有摸透,永远是新手!

[2]可以做技术,切不可沉湎于技术。千万不可一门心思钻研技术!给自己很大压力,如果你的心思全部放在这上面,那么注定你将成为孔乙己一类的人物!适可而止为之,因为技术只不过是你今后前途

的支柱之一,而且还不是最大的支柱,除非你只愿意到老还是个工程师!

[3]不要去做技术高手,只去做综合素质高手!在企业里混,我们时常瞧不起某人,说他“什么都不懂,凭啥拿那么多钱,凭啥升官!”这是普遍的典型的工程师的迂腐之言。8051很牛吗?人家能上去

必然有他的本事,而且是你没有的本事。你想想,老板搞经营那么多年,难道见识不如你这个新兵?人家或许善于管理,善于领会老板意图,善于部门协调等等。因此务必培养自己多方面的能力,包括

管理,亲和力,察言观色能力,攻关能力等,要成为综合素质的高手,则前途无量,否则只能躲在角落看示波器!技术以外的技能才是更重要的本事!!从古到今,美国日本,一律如此!

[4]多交社会三教九流的朋友!不要只和工程师交往,认为有共同语言,其实更重要的是和其他类人物交往,如果你希望有朝一日当老板或高层管理,那么你整日面对的就是这些人。了解他们的经历,

思维习惯,爱好,学习他们处理问题的模式,了解社会各个角落的现象和问题,这是以后发展的巨大的本钱,没有这些以后就会笨手笨脚,跌跌撞撞,遇到重重困难,交不少学费,成功的概率大大降低!

[5]知识涉猎不一定专,但一定要广!多看看其他方面的书,金融,财会,进出口,税务,法律等等,为以后做一些积累,以后的用处会更大!会少交许多学费!!

[6]抓住时机向技术管理或市场销售方面的转变!要想有前途就不能一直搞开发,适当时候要转变为管理或销售,前途会更大,以前搞技术也没有白搞,以后还用得着。搞管理可以培养自己的领导能力,搞销售可以培养自己的市场概念和思维,同时为自己以后发展积累庞大的人脉!应该说这才是前途的真正支柱!!

[7]逐渐克服自己的心里弱点和性格缺陷!多疑,敏感,天真(贬义,并不可爱),犹豫不决,胆怯,多虑,脸皮太薄,心不够黑,教条式思维。。。这些工程师普遍存在的性格弱点必须改变!很难吗?

只在床上想一想当然不可能,去帮朋友守一个月地摊,包准有效果,去实践,而不要只想!不克服这些缺点,一切不可能,甚至连项目经理都当不好–尽管你可能技术不错!

[8]工作的同时要为以后做准备!建立自己的工作环境!及早为自己配置一个工作环境,装备电脑,示波器(可以买个二手的),仿真器,编程器等,业余可以接点活,一方面接触市场,培养市场感觉,

同时也积累资金,更重要的是准备自己的产品,咱搞技术的没有钱,只有技术,技术的代表不是学历和证书,而是产品,拿出象样的产品,就可技术转让或与人合作搞企业!先把东西准备好,等待机会,

否则,有了机会也抓不住!

[9]要学会善于推销自己!不仅要能干,还要能说,能写,善于利用一切机会推销自己,树立自己的品牌形象,很必要!要创造条件让别人了解自己,不然老板怎么知道你能干?外面的投资人怎么相信你?

提早把自己推销出去,机会自然会来找你!搞个个人主页是个好注意!!特别是培养自己在行业的名气,有了名气,高薪机会自不在话下,更重要的是有合作的机会…

[10]该出手时便出手!永远不可能有100%把握!!!条件差不多就要大胆去干,去闯出自己的事业,不要犹豫,不要彷徨,干了不一定成功,但至少为下一次冲击积累了经验,不干永远没出息,而且要干

成必然要经历失败。不经历风雨,怎么见彩虹,没有人能随随便便成功!

j j j

如何成为一个好的程序员

1 学好基础,基础是关键,不要盲目的追崇新技术。

2 学技术要刨根问到底,要看清楚本质和原理,这样你才能根据原理和本质去千变万化,否则你只有永远跟在别人后面,做别人做过的功能。

3 要在工作和学习中总结,找出自己的不足,然后提高自己。

4 要学会沟通,和同事沟通,和上级沟通,和客户沟通等。

5 要学会随时给自己充电,等待机遇的到来,或者自己去创造机遇,一但机遇到来,就不要放过。

6 要学会给自己的近期蓝图做一个规划,是想做程序员呢,还是想做管理者,还是想先做程序员然后发展到管理者。

7 要学会团队协作,不要老把自己独立起来。

8 要分清楚主要矛盾和次要矛盾,做事情,想问题不要走极端,要全盘的思考。

9 要学会服从上级的命令,自己的建议是给上级参考的,但你不能要求上级要按你的想法去做。

10 工作要塌实,要有职业道德,要有责任心,在一家公司一天,就的做好自己该做的事情,那怕你心里想着自己下周就要跳槽了,但没走之前,也的把自己的工作做好。

11关于面试技巧之类的文章很多,只是要强调面试是很重要的,很多朋友可能忽略了这点,或者对这点的重视程度不够高。

12 如果你当了项目经理之类的职位,记的要注意培养你的下属,很多技术管理者只注重管理下属,而忽略了对下属的培养,这是不称职的上级。

13, 刚毕业或者毕业没多久的朋友,请不要把自己的姿态放的很高,别以为自己能做点东西就很牛了,其实要走的路还很长,有些时候技术能力并不能占主导地位的,况且技术真的就那么牛了吗?最后送上两个词:谦虚,塌实。

j j j

处理上百万条的数据库如何提高处理查询速度

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
5.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
6.下面的查询也将导致全表扫描:
select id from t where name like ‘%abc%’
若要提高效率,可以考虑全文检索。
7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where
可以改为强制查询使用索引:
select id from t with(index(索引名)) where
8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2
9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)=’abc’–name以abc开头的id
select id from t where datediff(day,createdate,’2005-11-30′)=0–‘2005-11-30’生成的id
应改为:
select id from t where name like ‘abc%’
select id from t where createdate>=’2005-11-30′ and createdate<‘2005-12-1’
10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
12.不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(…)
13.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
29.尽量避免大事务操作,提高系统并发能力。
30.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

j j j

tomcat6调优参数

service.xml配置
<Connector port=”8080″
redirectPort=”8443″
maxHttpHeaderSize=”8192″
useBodyEncodingForURI=”true”
minProcessors=”100″
maxProcessors=”5000″
maxThreads=”5000″
minSpareThreads=”1000″
maxSpareThreads=”4000″
enableLookups=”false”
acceptCount=”3500″
compression=”on”
compressionMinSize=”2048″
compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”
connectionTimeout=”20000″
disableUploadTimeout=”true”
debug=”0″
URIEncoding=”UTF-8″ />

j j j

mysql数据库 JDBC 对照

mysql数据库 JDBC 对照 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java.lang.String 12 CHAR N CHAR java.lang.String 1 BLOB L+N BLOB -4 TEXT 65535 VARCHAR java.lang.String -1 INTEGER 4 INTEGER UNSIGNED java.lang.Long 4 TINYINT 3 TINYINT UNSIGNED java.lang.Integer -6 SMALLINT 5 SMALLINT UNSIGNED java.lang.Integer 5 MEDIUMINT 8 MEDIUMINT UNSIGNED java.lang.Integer 4 BIT 1 BIT java.lang.Boolean -7 BIGINT 20 BIGINT UNSIGNED java.math.BigInteger -5 FLOAT 4+8 FLOAT java.lang.Float 7 DOUBLE 22 DOUBLE java.lang.Double 8 DECIMAL 11 DECIMAL java.math.BigDecimal 3 BOOLEAN 1 同TINYINT ID 11 PK (INTEGER UNSIGNED) java.lang.Long 4 DATE 10 DATE java.sql.Date 91 TIME 8 TIME java.sql.Time 92 DATETIME 19 DATETIME java.sql.Timestamp 93 TIMESTAMP 19 TIMESTAMP java.sql.Timestamp 93 YEAR 4 YEAR java.sql.Date 91

j j j

CentOS上安装Memcached[转]

1.安装Memcached前需要先安装Libevent:# curl -O http://www.monkey.org/~provos/libevent-1.4.9-stable.tar.gz
# tar zxf libevent-1.4.9-stable.tar.gz
# cd libevent-1.4.9-stable
# ./configure
# make
# make install

 

2.接着安装Memcached:
# curl -O http://www.danga.com/memcached/dist/memcached-1.2.7.tar.gz
# tar zxf memcached-1.2.7.tar.gz
# cd memcached-1.2.7
# ./configure
# make
# make install

 

3.接着在当前用户的.bash_profile中添加

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH


4.运行

# memcached -m 512 -u nobody -vv

测试时候发现会出现以下错误信息:

“/usr/local/memcached/bin/memcached: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory”

错误的原因是未在系统中注册Libevent. 解决方法如下:

# vi /etc/ld.so.conf.d/libevent-i386.conf

在VI中输入以下一行内容:

/usr/local/lib/

最后不要忘了
# ldconfig

 

5.运行

# memcached -m 512 -u nobody -vv

……….

<6 server listening
<7 server listening
<8 send buffer was 109568, now 268435456
<8 server listening (udp)
<9 send buffer was 109568, now 268435456
<9 server listening (udp)

Memcached运行正常。

原文:http://www.cnblogs.com/inrie/archive/2009/04/12/1434018.html

j j j

高效的MySQL分页

PERCONA PERFORMANCE CONFERENCE 2009上,来自雅虎的几位工程师带来了一篇”Efficient Pagination Using MySQL“的报告,有很多亮点,本文是在原文基础上的进一步延伸。

首先看一下分页的基本原理:

mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20\G
***************** 1. row **************
id: 1
select_type: SIMPLE
table: message
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4
ref: NULL
rows: 10020
Extra:
1 row in set (0.00 sec)

limit 10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行,问题就在这里,如果是limit 100000,100,需要扫描100100行,在一个高并发的应用里,每次查询需要扫描超过10W行,性能肯定大打折扣。文中还提到limit n性能是没问题的,因为只扫描n行。

文中提到一种”clue”的做法,给翻页提供一些”线索”,比如还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是9527,最小的是9500,如果我们只提供”上一页”、”下一页”这样的跳转(不提供到第N页的跳转),那么在处理”上一页”的时候SQL语句可以是:

SELECT * FROM message WHERE id > 9527 ORDER BY idASC LIMIT 20;

处理”下一页”的时候SQL语句可以是:

SELECT * FROM message WHERE id < 9500 ORDER BY idDESC LIMIT 20;

不管翻多少页,每次查询只扫描20行。

缺点是只能提供”上一页”、”下一页”的链接形式,但是我们的产品经理非常喜欢”<上一页 1 2 3 4 5 6 7 8 9 下一页>”这样的链接方式,怎么办呢?

如果LIMIT m,n不可避免的话,要优化效率,只有尽可能的让m小一下,我们扩展前面的”clue”做法,还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是9527,最小的是9500,比如要跳到第8页,我看的SQL语句可以这样写:

SELECT * FROM message WHERE id > 9527 ORDER BY idASC LIMIT 20,20;

跳转到第13页:

SELECT * FROM message WHERE id < 9500 ORDER BY idDESC LIMIT 40,20;

原理还是一样,记录住当前页id的最大值和最小值,计算跳转页面和当前页相对偏移,由于页面相近,这个偏移量不会很大,这样的话m值相对较小,大大减少扫描的行数。其实传统的limit m,n,相对的偏移一直是第一页,这样的话越翻到后面,效率越差,而上面给出的方法就没有这样的问题。

注意SQL语句里面的ASC和DESC,如果是ASC取出来的结果,显示的时候记得倒置一下。

已在60W数据总量的表中测试,效果非常明显。

原文链接:http://www.fuchaoqun.com/2009/04/efficient-pagination-using-mysql/

j j j

nginx上传限制

利用nginx做了play的前端服务器,应用一切正常,但是管理后台上传文件时,受到了限制,原来是nginx的一个参数惹的祸! client_max_body_size这个参数限制了上传文件的大小,默认是1M,此参数是在代理设置文件中配置的, 下面是我的proxy.conf 配置信息。
location / {
proxy_pass        http://fabo;
proxy_redirect          off;
proxy_set_header   Host             $host:80;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
client_max_body_size    1000m;
}

测试一下配置文件/usr/local/nginx/sbin/nginx -t
重启nginx:kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
这里我的设置是1000M的上限,通过修改client_max_body_size 设置的大小,重启nginx服务,解决了文件上传问题!

j j j

CentOS 5.5 中 Python 升级到 2.6.5

Python升级的过程(CentOS 5.5 中实验成功,其他发行版本Linux可作参考)。

1、下载

wget http://www.python.org/ftp/python/2.6.5/Python-2.6.5.tar.bz22、解压tar jxvf Python-2.6.5.tar.bz23、编译安装cd Python-2.6.5./configuremake && make installPython 默认安装目录在/usr/local/lib/python2.6查看一下刚才安装的版本 /usr/local/lib/python2.6 -V,看到了2.6.5吧4、更改系统默认版本之前查看版本使用 /usr/local/lib/python2.6 -V,现在来把系统默认的Python指向刚才安装的Python2.6。(如果有人问为什么不把2.4.3卸载呢?呃,貌似网上有讲yum是基于2.4.3,所以我也就没那样折腾)mv /usr/bin/python /usr/bin/python.bakln -s /usr/local/bin/python2.6 /usr/bin/python敲入 python -V 查看是否成功。5、修复不能正常工作的yum在完成了上面4步之后,如果有使用yum的话会发现出错,这是因为yum 依赖2.4.3而现在默认的 Python 版本是2.6.5。vim /usr/bin/yum将首行显示的 !#/usr/bin/python 修改为 !#/usr/bin/python2.4保存搞定。

Python 安装Mysqldb问题
yum install MySQL-python

j j j

nginx搭建支持flv mp4 seek 实现拖拽

wget http://sourceforge.net/projects/pcre/files/pcre/8.12/pcre-8.12.zip/download

wget http://h264.code-shop.com/download/nginx_mod_h264_streaming-2.2.7.tar.gz

wget http://nginx.org/download/nginx-1.0.0.tar.gz
wget http://sourceforge.net/projects/yamdi/files/yamdi/1.8/yamdi-1.8.tar.gz/download

tar zxvf  yamdi-1.8.tar.gz
cd yamdi-1.8
gcc yamdi.c -o yamdi -O2 -Wall

mv yamdi /usr/bin/
注意我们编译的 yamdi 它起着重要的作用,因为一个FLV视频要能够拖拽播放,这个FLV在其 metadata中有关键桢的信息,但大部分FLV 是没有的。所以,我们要甬道开源的yamdi来为视频添加关键帧信息
命令为
yamdi -i input.flv -o out.flv

yamdi的参数:
-i 指定FLV源文件.
-o 指定输出文件,如果文件名为-,则输出到标准输出设备上,如果不指定也是
-x 插入的metadata信息XML文件。如果输出文件省略了,则只生成metadata信息.
-c 一个写入creator标签的字符串.
-l 添加 onLastSecond 行为.
-h 显示帮助信息.

安装nginx

安装nginx之前必须先安装pcre

pcre编译安装需要gcc gcc-c++

yum install gcc gcc-c++ openssl-devel zlib-devel

unzip pcre-8.12.zip

cd pcre-8.12

./configure

make && make install

tar zxvf  nginx_mod_h264_streaming-2.2.7.tar.gz
tar zxvf nginx-1.0.0.tar.gz
cd nginx-1.0.0
./configure  –user=www –group=www –with-http_sub_module –with-http_flv_module  –add-module=../nginx_mod_h264_streaming-2.2.7 –with-http_dav_module –with-http_stub_status_module –with-http_addition_module
make时会有报错如下:
make[1]: *** [objs/addon/src/ngx_http_h264_streaming_module.o] Error 1
make[1]: Leaving directory `/home/mock/BUILD_ROOT/BUILD/nginx-0.8.38′
make: *** [build] Error 2
解决办法:Vim nginx_mod_h264_streaming-2.2.7/src/ngx_http_streaming_module.c  将如下几行注释
/* TODO: Win32 */
if (r->zero_in_uri)
{
return NGX_DECLINED;
}
make && make install
nginx配置文件
#nginx.conf
worker_processes 1;
events {
use epoll;
worker_connections  65535;

}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}

location ~ \.mp4$ {
mp4;
}
location ~ \.flv$ {
flv;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
命令测试:
curl -v http://xx.xx.com/resbase/2010/06/baihezhengdan.flv?start=10240000 -o /dev/null
找个支持seek(拖拽)的播放器JWplayer
http://www.longtailvideo.com/support/jw-player-setup-wizard

j j j