2014年5月31日星期六

微软私有云分享(R2)16PowerShell查看虚拟机信息

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
微软私有云分享(R2)16PowerShell查看虚拟机信息  阅读原文»

微软私有云分享(R2)16PowerShell查看虚拟机信息

微软私有云交流群【236804566】,技术分享成就梦想

欢迎关注新浪微博 @肥九叔

今天在群里面看到有同学问到,SCVMM能不能统一导出一份报表给客户看,当然这是可以的,不过基本非常依赖SQL,要写SQL语句。 当然,用PowerShell也可以实现差不多的功能,本人技术非常一般,下面脚本对我来说还是比较好用的。 首先PowerShell输出Hyper-V主机的条目信息是这样的

Get-VMNetworkAdapter-all

这个命令输出的结果有多悲剧我就不说了,东西太多。 所以我很机智的加了一些东西,"|"是管道的作用,把结果输出到后面的参数,后面的意思是只输出虚拟机名称和IP地址。

Get-VMNetworkAdapter-all|Select-ObjectVMname,IPAddresses|Format-Table

既然已经很机智了,再来一点吧

Get-VMNetworkAdapter-all|Select-ObjectVMname,IPAddresses|Format-Table>>\192.168.15.194d$33.csv

直接将内容输出到一个共享文件夹的.csv文件中。 ===========更高档的来了?====================== 用下面这个句子,可以一次输出三台主机的IP地址和虚拟机名称列表,名称为目标主机的d盘下的以主机名为名称的.csv,这时候注意下,输出结果是分散在不同主机上的。

Invoke-Command-ComputerNamehahv1,hahv2,hahv3-Command{Get-VMNetworkAdapter-all|Select-ObjectVMname,IPAddresses|Format-Table>d:$env:COMPUTERNAME.csv}

我们总结一下,写一个.ps1文件,也就是PowerShell的批处理脚本

Invoke-Command-ComputerNamehahv1,hahv2,hahv3-Command{Get-VMNetworkAdapter-all|Select-ObjectVMname,IPAddresses|Format-Table>d:$env:COMPUTERNAME.csv}#导出IP地址

#这下面三个copy是啥意思呢?拷贝不同主机上的文件到运行脚本的D盘

copy\hahv1d$hahv1.csvd:

copy\hahv2d$hahv2.csvd:

copy\hahv3d$hahv3.csvd:

#PowerShell中运行cmd命令不太方便,因为cmd命令有一些和PowerShell差不多,但是功能不一样,所以用ech写入一条命令,就是将本地的csv文件组合一下,附加到一个叫做cp.cmd的文件中

echo"copy *.csv hv.csv /y">d:/cp.cmd

d:

#运行这个拷贝,结束

.cp.cmd

还有很机智的小伙伴说,原来PowerShell里面可以运行cmd啊,是啊没错,不过你如果不是.xxx.cmd这种方式运行,程序就跑到cmd里面,回不到ps了,后续内容不执行,非常悲剧。

另外echo"copy *.csv hv.csv /y">d:/cp.cmd 这种方法其实是错的,正确的是下面的!!

echo"asdf3434sdsf3434df"Out-Filed:/11.txt-EncodingDefault-Append

你要问为什么这么写,是因为一行没什么事儿,多了的话,这乱码问题解决不了啊。 另外这种方式还有一个机智的地方,它是追加写入的,就是这命令你输入一次,他追加一行。 如果你想保证脚本干净,记得运行前来一个del cp.cmd 只有这样才会创建新的文件。

================下面内容是白送的=========================== 依然是报错一小波

Id10619,这个问题出错实在是太机智了。比如你VHD模板里面的管理员用户名是administrator,但是你在VM模板中想把管理员设置成admin,很遗憾,这不行。 如果你拿到的是别人做给你的VHD,你的好***很邪恶的修改了administrator的名称,变成了xyz,那么你正常部署必然会失败。

Id802,被其他人使用中,这个毫无办法,重启vmm服务器解决(其实是库服务器上的文件被其他人使用,但是重启VMM是有效的。)

Id2904找不到路径,这个问题是这样的,你想把虚拟机部署到目标主机的D:HYPERV目录下,但是,但是,你必须要提前创建这个目录才可以。

本文出自 "九叔-微软私有云" 博客,请务必保留此出处http://jiushu.blog.51cto.com/972756/1419862

ThinkPHP关联模型详解  阅读原文»

ThinkPHP关联模型详解

在ThinkPHP中,关联模型更类似一种mysql中的外键约束,但是外键约束更加安全,缺点却是在写sql语句的时候不方便,ThinkPHP很好得解决了这个问题.但是很多人不动关联模型的意思.现在就写个例子.让大家理解ThinkPHP关联模型的意思.

环境描述:公司有一个员工表think_user,一个档案表,think_archives,一个部门表,think_department,和一个银行卡表.think_cars.

一个员工只有一个档案表,所以关系就是HSA_ONE,

一个员工只属于一个部门,但是部门里有多个员工,所以是BELONGS_TO关系

一个员工有多个银行卡,但是一个银行卡只能属于一个员工.所以关系就是HAS_MANY.

先创建需要的表和测试数据

think_user表.

CREATETABLE`think_user`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`username`varchar(50)NOTNULL,
`password`varchar(50)NOTNULL,
`did`int(11)NOTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8|

think_department

CREATETABLE`think_department`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`name`varchar(50)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8|

think_archives

CREATETABLE`think_archives`(
`id`int(7)NOTNULLAUTO_INCREMENT,
`uid`int(11)NOTNULL,
`addr`varchar(200)DEFAULTNULL,
`email`varchar(30)DEFAULTNULL,
`tel`int(13)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8|

think_cars

CREATETABLE`think_cars`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`name`varchar(50)DEFAULTNULL,
`type`varchar(50)DEFAULTNULL,
`uid`int(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8

插入数据到部门表think_department

insertintothink_carsvalues
(null,'gongxiang','工商卡','1'),
(null,'jianshe','建行卡','2'),
(null,'jiaohang','交通银行卡',3);

think_user数据

insertintothink_archivesvalues
(null,1,'北京','123@163.com','13888888'),
(null,2,'上海','111@qq.com'阅读更多内容

PLSQL_性能优化效能跟踪工具DBMS_PROFILER分析(案例) - 东方瀚海

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
PLSQL_性能优化效能跟踪工具DBMS_PROFILER分析(案例) - 东方瀚海  阅读原文»

【摘要】2014-06-01 BaoXinjian In Capgemini一、摘要Oracle PLSQL性能诊断是经常会遇到问题,所以Oracle提供了比较多的程式诊断工具,其中包括了dbms_profiler包DBMS_PROFILER中会用到一些基本构建如下在调用程式前DBMS_PROFILER.S... 阅读全文

Jquery简单的placeholder效果 - 龙恩0707  阅读原文»

Jquery简单的placeholder效果

由于IE6-IE9不支持HTML5中的placeholder,所以自己依赖于Jquery简单的写了一个,供参考!

先看看效果吧!如下JSFiddle地址

查看效果链接

JS代码如下:

/*
* JS placeholder
* IE6-IE9不支持HTML5中的placeholder
*/

function Placeholder(options) {
this.config = {
defaultColor:
'#ccc',
curColor:
'#333',
targetElem:
'.placeholderCls'
};

this.init(options);
}

Placeholder.prototype
= {

constructor:Placeholder,

init:
function(options){
this.config = $.extend(this.config, options || {});
var self = this,
_config
= self.config;

$(_config.targetElem).each(
function(){
var supportPlaceholder = 'placeholder' in document.createElement('input');
if(!supportPlaceholder) {
var defaultValue = $(this).attr('placeholder');
$(
this).focus(function(){
var pattern = new RegExp("^" + defaultValue + "$|^$");
pattern.test($(
this).val()) && $(this).val('').css('color',_config.curColor);
}).blur(
function(){
if($(this).val() == defaultValue) {
$(
this).css('color',_config.defaultColor);
}
else if($(this).val().length == 0){
$(
this).val(defaultValue).css('color', _config.defaultColor);
}
}).trigger(
'blur');
}
});

}
};

HTML代码如下:

<form id="form1">
<h3>通过value方式模拟placeholder</h3>

<p>
<label for="username1">用户名:</label>
<input type="text" class="placeholderCls" placeholder="请输入用户名">
</p>
<p>
<label for="address1">地 址:</label>
<input type="text" class="placeholderCls" placeholder="请输入地址">
</p>
<p>
<label for="remarks1">备 注:</label>
<textarea placeholder="请输入备注" class="placeholderCls"></textarea>
</p>
</form>

代码初始化:

<script>
new Placeholder({});
</script>


本文链接:Jquery简单的placeholder效果,转载请注明。

阅读更多内容

2014年5月29日星期四

关于公司开发突然转语言的问题 - 任岩磊

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
关于公司开发突然转语言的问题 - 任岩磊  阅读原文»

刚才公司把我们全体技术人员召集在一起,开了一个会议。说我们的客户最近有反应NET技术档次太低,强烈要求我们转成其他语言。
我问经理,客户又不懂技术,他凭什么说NET档次低,经理说:客户不管哪个!只要看到aspx的后缀名,就觉得是低档次产品。我晕。
我不知道说啥了。就问经理,咱们转成什么,他说转成Java吧。我发现很多技术人员都不屑转成Java。
我觉得转语言是把双刃剑,要么转型成功,要么多年积累的产品代码和经验就会丧失。

转语言的好处

①:多接触其他语言 是自己的技术视野拓宽。

②:没有一成不变的开发语言,什么技术都会淘汰。为什么不主动学习新东西呢。

③:公司强制转语言。业务逻辑不用学习,但是语言会有一个周期

转语言的坏处

①:对于技术人员来说,在语言间切换绝对是个大问题。把一门语言玩的精通的才可能一通百通。公司大部分都是新手。他们刚开始接触一门语言马上有切换。学习成本太大。

②:语言间的联系性虽然说强。但是毕竟完全是两种语言。我们的学习周期要很长。

③:公司的语言竟然随着客户说变就变。这给开发者带来的极大坏处。

经理告诉我们,你们要么转语言,要么换工作。两条路选其一。我也在思考,纠结。小伙伴们。要是你们会怎么选择,给点建议。


本文链接:关于公司开发突然转语言的问题,转载请注明。

Unity3d使用经验总结 数据驱动篇 - Render Donkey  阅读原文»

我这里说的数据驱动,不是指某种框架,某种结构,或者某种编码方式。 我要说的,是一种开发方式。

大家都知道,U3D中,我们可以为某个对象编写一个脚本,然后将这个脚本挂在对象上,那这个对象就拥有了相应的能力。 但,由于脚本的威力是无穷的,它不仅可以操作这个对象本身,它同时还能改变整个世界。而U3D这种十分方便的开发模式,和你在FLASH CS中新建一个MovieClip,然后在它的时间轴上写代码如出一辙。 这种代码驱动的方式,在某些场合是非常有用的。

比如。 怪物AI,状态机,一些特殊的效果等(比如,摄相机振动)。

也就是说,如果我们想要让自己的代码很好地管理,那第一步,就是要限制代码与对象的关系。 世界中的任何单体对象,都不应该拥有改变世界(游戏逻辑)的能力。它唯一能做的,就是操作它自己,同时,如果遇上了自己能力以外的事情,必须要向管理器报告。

所以,为了实现数据驱动,我们的游戏大概有以下几种东西。

1、一个逻辑管理器,它决定了整个世界是如何运转,不同对象之间如何交互

2、事件管理器,它负责接收来自各个对象的报靠,比如(啊,有人踩到我了;咦,这是一个传送点耶;哎哟,你为什么点我。) 事件管理器起到事件队列缓存的作用,同时,游戏逻辑应该定时处理这些事件。 当然,这个事件管理器,也是逻辑管理器的一个小弟,如果逻辑管理器觉得不怕麻烦,也可以亲自操刀,负责事件收集。

3、若干对象相关的脚本,用于决定对象能力。 这些脚本不做别的,只做它们自己目标对象相关的事情。 比如,控制一个对象的动画切换,检查敌人是否进入攻击范围等等。 这些脚本,是做为脚本的一种能力挂上去的。当相应事件触发时,他们会将事件通知给事件管理器。 理论上,我们是可以完全避免这样做的, 就像早期的引擎中,对象只是资源,逻辑代码用来操作这些资源。 但是,既然U3D提供了如此便利的东西,我们为何不用呢。 因为有许多事件的检测,U3D已经为我们做好了,并且,也只有挂接在此对象上的脚本,才能够监听到这些事件。 比如OnTriggerEnter

当我们把代码限制在一定范围后,接下来的事情,就是限制场景树(Hierarchy)中对象的使用。

U3D很强大,你可以通过对象关系、组件,参数调节,快速地构建出一个对象。 这一步,是必须的。 但我们还是要限制一下, 我们不允许非Prefab的对象在场景树中出现,同时,Prefab除了Transform以外,不能被更改。(后面会说为什么,以及如何面对确实要更改的情况)。

接下来,我们来解决U3D中,一个操蛋的SVN冲突问题。 U3D的SCENE是基于二进制存储的,不管你怎么整,怎么避免,都会有冲突,并且冲突无法合并。 那,这事儿太简单了,我们不用它的SCENE文件就可以了。

需要做下面几件事

一、新增菜单 打开场景,保存场景

二、当我们保存场景的时候,遍历场景中的对象,将它们的transform,name,prefab,parentname存下来。输出到文本文件中,记住,这一定要是文本文件,不然,照样冲突。

三、如果只有一个文件,那冲突还是在所难免的,因此,我们需要把场景保存的时候,分割为多个文件。 如何分割呢, 我们需要提供一个配置文件,这个配置文件负责提供一个唯一的名字,以及对象ID段。 对象ID段的目的,这个对象ID,先前没有提过,但作为一个场景中的对象来说,如果没有ID,那将无法做到对它进行准确定位。 但,大家是工作在不同的机器上的,如果使这个ID唯一呢。 连接一个服务器? 那太坑爹了。 所以,我们可以把ID分段,项目组中,每个人拥有一个不相互冲突的ID段,和一个名字(可以是名字的拼音+后缀:如果有冲突的情况)。 当我们在编辑器中,把一个prefab拖入hierarchy的时候,修改这个对象的名字 ID_PrefabName_UserName 这样,这个对象在场景中就有了唯一的名字。 当我们保存的时候,我们根据USERNAME,将场景保存到不同的子文件划分中。

四、这样一来,我们的U3D场景就不需要保存了。 那我们如何做到点PLAY就即时运行查看效果呢。 这里有一个小小的技巧性方案。 在我们的编辑场景中,新建一个GameObject,在它上面挂上一个脚本,这个脚本什么事都不做,直接start的时候,就LoadLevel("game"). (这里,假设我们的游戏场景是game,game是一个新建好的场景,且加入到了当前项目的场景列表中的。 这个game其实也只有一个GameObject,它负责启动游戏。 加载我们先前输出的场景文件).

还有一个细节要处理,由于我们的game场景只有一个,那我们编辑许多个场景,要如何查看呢。 那我们可以使用一个静态变量来存储当前编辑的场景,这样game在加载的时候,就知道应该加载哪个场景的文件了。

五、为了使我们的开发更佳清析,在新建项目的时候,我们就新建两个Scene 一个叫Editor,一个叫Game。 大家都在Editor里面工作。 最后发布的时候,只发布Game.

六、SVN的提交, Editor和Game是一开始就新建好了的,直接在SVN上把它锁掉,禁止提交。 其余的文件,都是可以提交的。

这样,我们的U3D,就和自家引擎一样了。

在实施的过程中,我也遇上了一些问题。

一、保存场景的时候,取得所有的对象, 为了保证得到完整的场景树TOP结构,我有一个SceneRoot的空GameObject,所有的东西,都挂在这个下面。 当输出的时候,我直接从SceneRoot开始遍历,从而拿到了完整的parent,child关系。

二、监听对象改变的事件,我目前,只能在EditorWindow的OnHierarchyChange里面来做,但这样做有个不好的,就是这个EidtorWindow需要保持显示,如果不小心关了,就失效了(不知道哪位兄弟有更好的办法)

三、由于这套东西,没有使用U3D的场景保存功能,所以,CTRL+S是无效的。 不过,CTRL+S可以让你的东西保存到Editor.unity3d里面,虽然不可以提交,但不会导致你的东西丢失。

四、使用的过程中,也出现了一些大大小小的问题。

五、目前是强制让Prefab的其它属性不可修改,如果有变动的,就新建一个Prefab. 或许还有更好的办法.

如果有喜欢这个东西的朋友,可以一起来完善。


本文链接:Unity3d使用经验总结 数据驱动篇,转载请注明。

阅读更多内容

2014年5月28日星期三

[á]¤¨×ňí×××

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
[á]¤¨×�í×××  阅读原文»

[歪谈]员工(人才),留得住是因为本身就留得住;留不住的,你永远留不住

记得以前看过自媒体人罗振宇做过一挡节目,推荐了一本书叫做《不死的中国人》,一直没看过这本书,这几天闲着无聊就买来看了一看,不看不知道,看了果然颇有感触,因此今天我们来简单解读一下这部书的主题思想,同时来结合这本书来谈谈今天的话题"为何小公司招不到人"。

都是我个人的歪谈和歪理,错误之处在所难免。

一、谈书

《不死的中国人》作者是意大利人,这本书也是写给意大利人看的。书中描绘的现象如下,因为限于篇幅因此我用"罗列文风"表达,希望能缩短大家对本书的了解时间,如果大家对此有兴趣,可以去看看这本书,还是很有启示性的:

1、有一群移民或者到意大利打工的中国人,整天埋头干活,而且是极限式的干活,哪怕干到当场昏过去都不怕

2、意大利人一开始很喜欢这个人群。吃草产奶这是任何一个资本家都喜欢的,你不也是吗?

3、时间久了意大利人发现了端倪,并逐步开始排斥、讨厌甚至想把中国人赶出去。

为何呢?我们接着看:两代中国人的组合

4、中国人干活被概括成,超常的,近乎病态的,一个狭小的仓库,百来个人挤在一起制作皮鞋或衣物,厨房、卫生间、卧室都在这仓库里,幼小的孩子在堆积如山的货物间跑来跑去

5、第一代中国人:什么都愿意干,文化层次低。石匠、除草工、垃圾处理、沙发加工、服装、酒吧…他们利用自己的辛勤劳动积攒资本,再利用具有中国温州特色的民间信贷自己做老板,让当地人怀疑他们的资金来源的合法性。宁愿睡地板,也要当老板。

6、时间长了,他们发现这些第一代中国人有钱了(因为只赚钱不消费),由于文化层次太低(对于度假、文化根本不屑一顾),竟然在这些中国人当中也产生了赌博、斗殴、黑社会。

7、第二代中国人:第一代中国人狗一样的积累财富,于是他们的子女也来了。他们竟然聘请意大利当地人做保姆,就算受当地学校排挤,那也没关系,依然无法阻碍中国人的成绩超越众多当地人称为佼佼者

再接着看,中国人最根本的目的:赚钱

8、意大利人规定中国人每天工作10小时,因为在这之前有很多中国人因为过度劳动昏倒了

9、于是,第二天很多中国人辞职走人。

10、为毛?中国人曰:我们来就是赚钱的,没有钱赚(一天只能干10小时)那还有神马意思?

11、意大利人发现中国人赚了钱基本上除了最基本的温饱消费,剩余的钱基本完全就是寄回中国的亲人。

12、 有些中国人通过打拼积累了一定程度的钱,根本不会像意大利人那样"度假、甚至借钱度假消费"。而是会使用"浙商固有的理念",把钱滚钱,成为了"白手起家 的老板",可惜的是,这些中国人很少成为老板后在意大利买房产,原因很简单,这些老板赚了钱还是只干一件事:把钱寄回家

为什么意大利人觉得中国人不会死?接着看

13、中国人有叶落归根的中心思想。就算在中国本地,99%的中国人不愿意在死在外乡,大家记得赵本山的一部电影《叶落归根》吗?哪怕让朋友背也要"死回家去"

14、意大利人发现:大批的中国人移民到意大利,但是几乎只看到他们来,却看不到他们死。

15、这是为毛?其实也是叶落归根的思想,大部分赚了钱,然后会把钱寄回家,等到自己快死的时候就回中国老家等死。(死在国外?扯淡捏嘛)

16、有一部分"老板"在意大利定居了。结果意大利人发现,这些老板的工人大部分也是中国人,干着在意大利赚钱,消费却在中国的事。

17、而这位老板,在意大利买的房子没几平方。在国内却有别墅或联排别墅。这说明啥?人家还是要回去的

意大利人认为中国人的入侵"思想":

18、那时的意大利,有很多街道小店铺或作坊没啥生意,很多老店铺主要么关铺子,要么转让,因为他们的子女也不愿意接手(大家想想中国的祖产集成氛围吧)

19、不知道为何中国人觉得这些意大利人觉得不值钱的店铺值得接手。

20、很快,中国人用"不惜一切代价"的方式来向各种意大利店主要接手店铺权。

21、纵使有些意大利人一开始不愿意,不过慢慢他发现周围这些小店铺全部变成中国人的了

22、中国人来买店铺竟然用的是"鼓鼓囊囊"的现金。这就使每次店铺转让都要数很长时间的现金。

23、在意大利人看来,中国人从不会武力侵略,但是用的却是一个"商业侵略",因为很简单嘛~~一眼望去,整条街都是中国人的店铺,其他还说啥?

最后,我来总结一下这本书表达的对"中国人"的看法:

1、中国人只喜欢钱,钱以外的东西一律不关心,更别说文化融合

2、为了钱,啥事都干得出。也就是说,中国人只要看到利益,情愿累死街头,也要把钱赚到手

3、中国人仿佛赚钱只为了"他自己认可的家庭"。哪怕你(意大利人等外国人)对他再好,他也不会把你当亲人。关键时刻可能还会"卖了你"

4、如果没有钱赚,中国人也会罢工,他们的罢工绝对不是"每个月多要几天休息或者不能超过一天几小时",这和其他外国人罢工的原因是相反的

5、中国人很难被外国人洗脑。资本家哪怕天天告诉你"跟着他们能让你发家致富、幸福百年",可他们依然不关心。他们只关心的是到口袋里的钞票,"主义、文化、氛围"一律与他们无关。

6、千万别把你的关键性环节让中国人知道。否则,他们分分钟就能模仿出来,并以"狗一样的低价"几天内就把你干崩溃。哪怕你是他的救命恩人,这些根本不会勾勒在中国人的脑海里。

二、本文主题

好吧。我承认这本书我还没有看到最后,不过前面几章和我自己的理解已经让我够震撼的了,说话话我已经不想看下去了。不是说本书不好,而是我觉得写的太过于真实、太过于让人浮想联翩,我的大脑承受不了这么多的信息的爆炸式增长。

前几天有个软件公司的老板朋友和我聊天时诉苦:"招人太难了,不管用什么机制都留不住人。企业文化这些也没用"。

也正是这句话让我想到了这本书,前几天在网上也找了几篇关于"怎么留住人才的文章",如果论现实,我发现这些网上讲的有板有眼的理论在现实生活中根本无法行得通。

譬如:

1、升职,给予良好的竞升空间

2、巩固团队。打造良好的团队氛围

3、加薪、给期权

4、激励员工的创业意识

5、让员工接触客户,使之有一定的人脉资源积累。

6、。。。。。篇幅原因,不多列举。

可是事实呢?因为精神文明建设方面的原因,除非,你把这个员工绑在那,否则以上各种措施都是三个月效应:没有哪个员工会因为你这些激励措施感激涕零,甚至为你干到人老珠黄。

我身边有个案例,某朋友是一个HR总监,同时又是公司的股东。他告诉我一个案例,大概情况是这样的:

A是一个公司从外地高薪招聘过来的技术高手。由于其技术水平实在太高(怎么高发?其实也很难衡量),公司给他配备了单独办公室(良好的办公环境),高薪和分红(物质诱惑),然后还给他配备一组实干派的队友(企业文化"不干扰")。

结果,大约才两年。这位技术高手就提出要辞职,原因是公司的客户要过于苛刻(大家懂的),他受不了客户无良的需求造成他在公司做的技术产品大部分都是"废品"。

我 这朋友急了,但是他既然是HR总监,那肯定有驭人之术。于是,他坐下来和这个技术高人从上午一直交心交到下午。也算有点效果,在HR朋友差点"崩出?div style="border-bottom:1px solid #aaa;margin-bottom:25px">SSH°DropbearSSHé  阅读原文»

用户名:qw87112 文章数:15 评论数:0
访问量:745:280:190:2 注册日期:2011-11-02

SSH安全配置实践,如何手动编译Dropbear实现SSH协议。

在早期要从一台计算机通过网络登录另一条计算机获取终端,用的大多数是telnet协议,这种协议由于是明文传输的,在用户身份认证时,很容易被cracker抓取报文,从中获得帐户密码,然后你将为他所做的破坏负责。后来为了数据更安全的传,出现了SSHsecureshell ),由IETF网络小组所定制,SSH 为建立在应用层和传输层基础上的安全协议,是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。

opensshdropbear程序是SSH协议的实现。

下面来看看如何安全配置SSHD服务:

wKioL1OEjBjwGNoFAAHayYkCbQg286.jpg

控制ssh连接数,连接频度。

基于密钥认证,可以实现在建立连接时不需要输密码,比口令认证更方便,安全,缺点就是要保管好私钥文件。

# ssh-keygen -t rsa生成密钥;

wKioL1OElG6yfQMpAAF37SEKmOs507.jpg

# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.1.198

将生成的公钥内容追加到目标主机用户家目录下./ssh/authorized_keys文件中。

下次登录的时候,就可以直接完成密钥认证,无需输密码了。

wKiom1OElQHjjPRMAAGEYFw04So658.jpg

接下来看看如何用Dropbear实现SSH。

首先编译安装dropbear:

# tar -xvf dropbear-2013.58.tar.bz2

# cd dropbear-2013.58

#ls

#./configure --prefix=/usr/local/dropbear --sysconfdir=/etc/dropbear

# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"

#make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

安装完成!

wKiom1OEmeKysYkEAAL6dQXMcsQ705.jpg

为dropbear编写服务控制脚本:

以下是小菜写的脚本,可能不太完善,大家互相学习。

wKioL1OEvUyS7CaCAAZc0TLCxII030.jpg

现在可以用脚本控制dropbear了,启动下试试?

第一次启动,脚本会帮我们生成密钥。

# service dropbear start

wKiom1OEv9LS_zprAAFBh0AV3lA783.jpg

启动成功,我们看看是不是真的启动了。

看来是真的启动了,侦听在22222端口,侦听在这个端口,是我在脚本里指定的。

wKioL1OEwEbRaDceAAGybvx5jFY676.jpg

我们试试它能不能正常工作,用192.168.1.198连进来试试。

# ssh 192.168.1.200 -p 22222

成功登录,看到红色标记的部分没,192.168.1.200这是我们dropbear服务器的地址哦。

wKiom1OEwr7Tm50nAAJIZTVui_Q853.jpg

好了,大功告成了,去睡觉了。

以上内容纯小菜手打,亲测实验截图。

有问题欢迎与我交流QQ1183710107

本文出自 "坏人的博客" 博客,转载请与作者联系!

分享至 一键收藏,随时查看,分享好友!

阅读更多内容

2014年5月27日星期二

SQL Server 监控统计阻塞脚本信息 - 潇湘隐者

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
SQL Server 监控统计阻塞脚本信息 - 潇湘隐者  阅读原文»

数据库产生阻塞(Blocking)的本质原因 :SQL语句连续持有锁的时间过长 ,数目过多, 粒度过大。阻塞是事务隔离带来的副作用,它是不可避免的,而且是一个数据库系统常见的现象。 但是阻塞的时间和出现频率要控制在一定的范围内,阻塞持续的时间过长或阻塞出现过多(过于频繁),就会对数据库性能产生严重的影响。

很多时候,DBA需要知道数据库在出现性能问题时,有没有发生阻塞? 什么时候开始的?发生在那个数据库上? 阻塞发生在那些SQL语句之间? 阻塞的时间有多长? 阻塞发生的频率? 阻塞有关的连接是从那些客户端应用发送来的?.......

如果我们能够知道这些具体信息,我们就能迅速定位问题,分析阻塞产生的原因, 从而找出出现性能问题的根本原因,并根据具体原因给出相应的解决方案(索引调整、优化SQL语句等)。

查看阻塞的方法比较多, 我在这篇博客MS SQL 日常维护管理常用脚本(二)里面提到查看阻塞的一些方法:

方法1:查看那个引起阻塞,查看blk不为0的记录,如果存在阻塞进程,则是该阻塞进程的会话 ID。否则该列为零。

EXEC sp_who active

方法2:查看那个引起阻塞,查看字段BlkBy,这个能够得到比sp_who更多的信息。

EXEC sp_who2 active

方法3:sp_lock 系统存储过程,报告有关锁的信息,但是不方便定位问题

方法4:sp_who_lock存储过程

方法5:右键服务器-选择"活动和监视器",查看进程选项。注意"任务状态"字段。

方法6:右键服务名称-选择报表-标准报表-活动-所有正在阻塞的事务。

但是上面方法,例如像sp_who、 sp_who2,sp_who_lock等,都有或多或少的缺点:例如不能查看阻塞和被阻塞的SQL语句。不能从查看一段时间内阻塞发生的情况等;没有显示阻塞的时间....... 我们要实现下面功能:

1: 查看那个会话阻塞了那个会话

2:阻塞会话和被阻塞会话正在执行的SQL语句

3:被阻塞了多长时间

4:像客户端IP、Proagram_Name之类信息

5:阻塞发生的时间点

6:阻塞发生的频率

7:如果需要,应该通知相关开发人员,DBA不能啥事情都包揽是吧,那不还得累死,总得让开发人员员参与进来优化(有些问题就该他们解决),多了解一些系统运行的具体情况,有利于他们认识问题、解决问题。

8:需要的时候开启这项功能,不需要关闭这项功能

于是为了满足上述功能,有了下面SQL 语句

SELECT wt.blocking_session_id AS BlockingSessesionId ,sp.program_name AS ProgramName ,COALESCE(sp.LOGINAME, sp.nt_username) AS HostName ,ec1.client_net_address AS ClientIpAddress ,db.name AS DatabaseName ,wt.wait_type AS WaitType ,ec1.connect_time AS BlockingStartTime ,wt.WAIT_DURATION_MS/1000 AS WaitDuration ,ec1.session_id AS BlockedSessionId ,h1.TEXT AS BlockedSQLText ,h2.TEXT AS BlockingSQLText FROM sys.dm_tran_locks AS tl INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id LEFT OUTER JOIN master.dbo.sysprocesses sp ON SP.spid = wt.blocking_session_id CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1 CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2

我们做一个测试例子来验证一下

1:打开第一会话窗口1,执行下面语句

USE DBMonitor; GO BEGIN TRANSACTION SELECT * FROM dbo.TEST(TABLOCKX); --COMMIT TRANSACTION;

2:打开第二个会话窗口2,执行下面语句

USE DBMonitor; GO SELECT * FROM dbo.TEST

3:打开第三个会话窗口3,执行下面语句

编写高质量代码改善C#程序的157个建议[用抛异常替代返回错误、不要在不恰当的场合下引发异常、重新引发异常时使用inner Exception] - aehyok  阅读原文»

前言  

  自从.NET出现后,关于CLR异常机制的讨论就几乎从未停止过。迄今为止,CLR异常机制让人关注最多的一点就是“效率”问题。其实,这里存在认识上的误区,因为正常控制流程下的代码运行并不会出现问题,只有引发异常时才会带来效率问题。基于这一点,很多开发者已经达成共识:不应将异常机制用于正常控制流中。达成的另一个共识是:CLR异常机制带来的“效率”问题不足以“抵消”它带来的巨大收益。CLR异常机制至少有一下几个优点:

  1、正常控制流会倍立即中止,无效值或状态不会在系统中继续传播。

  2、提供了统一处理错误的方法。

  3、提供了在构造函数、操作符重载及属性中报告异常的便利机制。

  4、提供了异常堆栈,便于开发者定位异常发生的位置。

  另外,“异常”其名称本身就说明了它的发生是一个小概率事件。所以,因异常带来的效率问题会倍限制在一个很小的范围内。实际上,try catch所带来的效率问题几乎忽略的。在某些特定的场合,如Int32的Parse方法中, 确实存在这因为滥用而导致的效率问题。在这种情况下,我们就应该考虑提供一个TryParse方法,从设计的角度让用户选择让程序运行得更快。另一种规避因为异常而影响效率的方法是:Tester-doer模式,下文将详细阐述。

  本章将给出一些在C#中处理CLR异常方面的通用建议,一帮助大家构建和开发一个运行良好和可靠的应用系统。

  本文已同步到http://www.cnblogs.com/aehyok/p/3624579.html。本文主要来学习以下几点建议

  建议58、用抛出异常代替返回错误代码

  建议59、不要在不恰当的场合下引发异常

  建议60、重新引发异常时使用inner Exception

58、用抛出异常代替返回错误代码  

  在异常机制出现之前,应用程序普遍采用返回错误代码的方式来通知调用者发生了异常。本建议首先阐述为什么要用抛出异常的方式来代替返回错误代码的方式。

  对于一个成员方法来说,它要么执行成功,要么执行失败。成员方法成功的情况很容易理解。但是如果执行失败了却没有那么简单,因为我们需要将导致执行失败的原因通知调用者。抛出异常和返回错误代码都是用来通知调用者的手段。

  假设我们要实现这样一个简单的功能:应用程序需要完成一次保存新建用户的操作。这是一个分布式的操作,保存动作除了需要将用户保存在本地外,还需要通过WCF在远程服务器上保存数据。负责保存用户的成员方法如下:

public int SaveUser(User user)
{
if (!SaveToFile(user))
{
return 1;
}
if (!SaveToDataBase(user))
{
return 2;
}
return 0;
}

public bool SaveToFile(User user)
{
return true;
}

public bool SaveToDataBase(User user)
{
return true;
}

如果单纯的看SaveUser方法,似乎一切都还不错,在约定好了错误代码后,调用者只要接收到1或2,就知道到底是那里出现了问题。但仔细研究会发现,如果方法执行失败,似乎还可以挖掘出更多的原因。

假设在SaveToFile方法中,我们可能会遇到:

1、程序无数据存储文件写权限导致的失败。

2、硬盘空间不足导致的失败。

在SaveToDataBase方法中,我们可能会遇到:

1、服务不存在导致的失败。

2、网络连接不正常导致的失败。

当我们想要告诉调用者更多的细节的时候,就需要与调用者约定更多的错误代码。于是我们很快就会发现,错误代码飞速膨胀,直到看起来似乎无法维护。因为我们总在查找并确认错误代码。

  采用接下来的方法,可能会省略很大一部分的错误代码:

public bool SaveUser1(User user,ref string errorMessage)
{
if (!SaveToFile(user))
{
errorMessage
= "本地保存失败";
return false;
}
if (!SaveToDataBase(user))
{
errorMessage
= "远程保存失败";
return false;
}
return true;
}

  这看上去不错,即使存在更多的错误也可以将失败信息呈现给调用者或者上层用户。然后仅仅呈现失败信息就可以了吗?我们来看看这样一种情况:给失败通知增加稍微复杂一点的功能。

  如果本地保存失败,要完成“通知运行本段代码的客户机管理员”的功能。通常情况下,仅仅只需要显示类似的信息:“本地保存失败,请检查用户权限”。如果远程保存失败,应用程序需要“发送一封邮件给远程服务器的系统管理员”。总金额个增加的功能导致我们不能像处理“本地保存失败”那样来处理“远程保存失败”。

  一切仿佛又回到了起点,在没有异常处理机制之前,我们只能返回错误代码,但是现在有了另一种选择,即使用异常机制。如果使用异常机制,那么最终的代码看起来应该是下面这样的:

static void Main(string[] args)
{
try
{
SaveUser(
new User());
}
catch (IOException e)
{
///IO异常,通知当前用户
}
catch (UnauthorizedAccessException e)
{
////权限异常,通知客户端管理员
}
catch (CommunicationException e)
{
///网络异常,通知发送给网络管理员
}
}

public static void SaveUser(User user)
{
SaveToFile(user);

SaveToDataBase(user);
}

  使用CLR异常机制后,我们会发现代码变得更清晰、更易于理解了。至于效率问题,还可以重新审视“效率”的立足点:throw exception产生的那点效率损耗与等待网络连接异常相比,简直微不足道,而CLR异常机制带来的好处却是显而易见的。

  这里需要稍加强调的是,在catch(CommunicationException)这个代码块中,代码所完成的功能是“通知发送”而不是“发送”本身,因为我们要确保在catch和finally中所执行的代码是可以倍执行的。换句话说,尽量不要在catch和finally中再让代码“出错”,那么让异常堆栈信息变得复杂和难以理解。

  在本例的catch代码块中,不要真得编写发送邮件的代码,因为发送邮件这个行为可能会产生更多的异常,而“通知发送”这个行为稳定性更高(即不“出错”)。

  以上通过实际的案例阐述了抛出异常相比于返回错误代码的优越性,以及在某些情况下错误代码将无用武之地,如构造函数、操作符重载及属性。语法特性决定了其不能具备任何返回值,于是异常机制倍当作取代错误代码的首要选择。

59、不要在不恰当的场合下引发异常  

  最常见不易引发异常的情况是对在可控范围内的输入和输出引发异常。如下面的代码所示:

public void SaveUse

阅读更多内容

2014年5月26日星期一

Linux系统资源常用监控工具

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Linux系统资源常用监控工具  阅读原文»

每日博报 精彩不止一点关闭

用户名:Mr_陈 文章数:36 评论数:9
访问量:4719:1026:792:4 注册日期:2014-02-08

Linux系统资源常用监控工具

Linux系统维护的主要工作就是保证系统和应用的稳定。而如果想保证稳定就必须时刻了解系统的状态;cpu、内存、磁盘、网络和各种应用程序的运行于占用资源的状态等。同时掌握了系统资源的状态信息;也可以对系统进行优化,以发挥更好的性能。

对于这些信息的查看;需要一些工具能够及时的查看和分析;下面就对Linux系统资源监控常用的工具进行简单的介绍:

1、sar(System Activity Recorder)

sar可以显示CPU 使用率、内存页数据、网络 I/O 和传输统计、进程创建活动和磁盘设备的活动详情

Usage:sar[options][<interval>[<count>]]
Mainoptionsandreports:
-b I/Oandtransferratestatistics
-B Pagingstatistics
-d Blockdevicestatistics
-I{<int>|SUM|ALL|XALL}
Interruptsstatistics
-m Powermanagementstatistics
-n{<keyword>[,...]|ALL}
Networkstatistics
DEV Networkinterfaces
EDEV Networkinterfaces(errors)

测试:

#sar-b-r-u1为了方便;这里一次性显示三项
Linux2.6.32-431.el6.x86_64(node2.soul.com) 05/25/2014 _x86_64_ (1CPU)
09:07:24PMCPU%user%nice%system%iowait%steal%idle
09:07:25PMall0.000.002.020.000.0097.98
09:07:24PMtpsrtpswtpsbread/sbwrtn/s
09:07:25PM0.000.000.000.000.00
09:07:24PMkbmemfreekbmemused%memusedkbbufferskbcachedkbcommit%commit
09:07:25PM76482824752424.4511772102232114258836.75
#对于这其中每项的含义就不做一一解释;基本表示的很清楚;大都是词面意思。

sar还记录每天的cpu信息

#sar-f/var/log/sa/sa25sa25表示本月25号的信息
Linux2.6.32-431.el6.x86_64(node2.soul.com) 05/25/2014 _x86_64_ (1CPU)
12:00:01AMCPU%user%nice%system%iowait%steal%idle
12:10:01AMall0.020.000.100.080.0099.80
12:20:01AMall0.010.000.100.060.0099.83
03:20:01PMCPU%user%nice%system%iowait%steal%idle
03:30:01PMall7.380.000.530.310.0091.77
03:40:02PMall23.890.000.310.040.0075.76
03:50:01PMall21.840.002.370.320.0075.46
04:00:04PMall97.140.002.860.000.00基于openldap+Kerberos+google authenticator动态口令实现的运维跳板机  阅读原文»

用户名:双鱼座小龙 文章数:19 评论数:36
访问量:7250:472:378:3 注册日期:2011-11-23

出于安全考虑,大多数公司的办公环境和业务环境在网络层面基本上是隔离开的,在办公环境是无法直接连到业务生产环境的,只有做过特定白名单同性的情况下才会允许这么做。这样做了,开发人员需要访问生产环境服务器排查问题或者运维人员通过办公网络对生产环境进行维护就不太方便,但是网络一旦开通又会出现安全风险。

在这种情况下,就需要一种可以控制网络入口,能够统一授权,认证的系统,这样运维跳板机,也就是比较严格意义上的AAAA认证系统就出现了。

所谓的4A认证系统其实是指:

统一用户账号(Account)

统一认证(Authentication)

统一授权(Authorization)

统一安全审计(Audit)

我们公司使用的是openldap(管理用户信息,同时实现资源访问控制),Kerberos(网络鉴权),google authenticator(二次认证的动态口令),bash (修改源码,实现账户远程登录操作

日志记录)

wKioL1OCXNDQxpkOAAIq4HeAkrI350.jpg

系统环境: 64位 CentOS linux 6.3

openldap+bdb+phpldapadmin

openldap:

master端:yum 安装

openldap

openldap-clients

openldap-servers

nss_ldap

客户端:yum方式

openldap

nss_ldap

slapd.conf配置文件修改:

databasebdb
suffix"dc=dianping,dc=com"
rootdn"cn=ldapadmin,dc=dianping,dc=com"
#Cleartextpasswords,especiallyfortherootdn,should
#beavoid.Seeslappasswd(8)andslapd.conf(5)fordetails.
#Useofstrongauthenticationencouraged.
rootpw!@qwaszx
#ThedatabasedirectoryMUSTexistpriortorunningslapdAND
#shouldonlybeaccessiblebytheslapdandslaptools.
#Mode700recommended.
directory/usr/local/openldap/var/openldap-data
#Indicestomaintain
indexobjectClasseq
#indexuidNumbereq
serverid3ldap://server1
serverid5ldap://server2
cachesize50000
checkpoint10245
syncreplrid=005
provider=ldap://server2
binddn="cn=ldapadmin,dc=dianping,dc=com"
bindmethod=simple
credentials=hehehehhe,qunying.liu
searchbase="dc=dianping,dc=com"
type=refreshAndPersist
interval=00:00:00:10
retry="553005"
mirrormodetrue
overlaysyncprov
syncprov-checkpoint10010
syncprov-sessionlog100
databasemonitor

系统加入ldap认证:

vi/etc/nsswitch.conf
passwd:filesldap
shadow:filesldap
group:filesldap

打开ldap服务日志:

syslog中加入ldap日志文件

vi/etc/syslog.conf
#saveOpenLDAPlog
local4.*/var/log/ldap.log

客户端修改 /etc/ldap.conf

2014年5月25日星期日

ASP.NET MVC学习之模型绑定(2) - y-z-f

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
ASP.NET MVC学习之模型绑定(2) - y-z-f  阅读原文»

ASP.NET MVC学习之模型绑定继续

3.手工调用模型绑定

很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了很多过程中的控制,所以我们就需要使用手工的方式进行绑定。下面我们通过一个例子来说明,首先打开Views/Home/Index.cshtml页面,并输入如下代码:

1 @{
2 ViewBag.Title = "Index";
3 }
4
5 @if (TempData.ContainsKey("msg"))
6 {
7 <h1>
8 @TempData["msg"].ToString()
9 </h1>
10 }
11
12 @using (Html.BeginForm())
13 {
14 <input type="text" name="id" />
15 <input type="submit" value="submit" />
16 }

接着打开HomeController并写入如下代码(关于ActionName可以点击这进行参考):

1 namespace MvcStudy.Controllers
2 {
3 public class HomeController : Controller
4 {
5 private class TestA
6 {
7 public String id { get; set; }
8 }
9
10 public ActionResult Index()
11 {
12 return View();
13 }
14
15 [HttpPost]
16 [ActionName("Index")]
17 public ActionResult IndexPost()
18 {
19 TestA ta = new TestA();
20 UpdateModel(ta);
21 TempData["msg"] = ta.id;
22 return View();
23 }
24 }
25 }

这里我们通过UpdateModel进行手动绑定,最终的结果和采用形参的方式相同,读者可以进行测试可以发现输入的值都显示了,但是读者一定会奇怪,因为TestA中的id不仅仅存在于表单,同时还存在与RouteData中以及查询字符串中,我们可以用?id=123来测试这个页面可以发现并不会修改最终结果,而通过手动调用模型绑定的优点之一就是我们可以控制数据来源,比如我们修改HomeController代码如下所示:

1 [HttpPost]
2 [ActionName("Index")]
3 public ActionResult IndexPost()
4 {
5 TestA ta = new TestA();
6 UpdateModel(ta,new FormValueProvider(ControllerContext));
7 TempData["msg"] = ta.id;
8 return View();
9 }

这里我们可以发现我们给UpdateModel传递了第二个参数,FormValueProvider这表示数据源只能来自于表单中,同样我们还可以修改成RouteDataValueProvider或者QueryStringValueProvider,具体的效果读者你自行替换之后,输入http://localhost:1201/Home/Index/123?id=asdsad测试,可以看看最后显示的内容是不是来自于我们指定的来源。再使用形参的方式中我们有时会遇到http流中不存在我们需要的值,并且这个形参的类型不能为null,或者我们不希望它为null,这个时候就会出现异常或者赋值为null,而通过UpdateModel则可以通过try…catch…的形式捕获InvalidOperationException异常从而手动处理,如果读者不希望通过这种方式也可以像下面这种形式来处理:

1 一个合格的前端工程师必看的书籍 - EXE-DREAM  阅读原文»

以我的经验,大部分技术,熟读下列四类书籍即可。

  1. 入门,用浅显的语言和方式讲述正确的道理和方法,如head first系列
  2. 全面,巨细无遗地探讨每个细节,遇到疑难问题时往往可以在这里得到理论解答,如Definitive Guide/Programming xx系列
  3. 实践,结合实际中经常遇到的情景环境,来描述如何设计和解决问题,如cookbook系列
  4. 深入,讲解一些文化,思路,甚至于哲学上的东西,真正做到深入一种语言去编程,如unix编程艺术,程序员修炼之道等等

那么,目前为止我认为最好的书是:

css:

  1. 入门: Head First HTML and CSS, XHTML (中文版,第二版)这本2005年底的书依然是最易懂,清晰和正确的入门读物,去看看amazon排名就知道了
  2. 全面: CSS, The Definitive Guide (3th Edition) (《CSS权威指南(第3版)》)Meyer可能是css领域最权威和知名的作者,他在这本书里讲解了每个细节的实现和原理,更详细的东西恐怕只能从w3c那几乎不可读的文档中去寻找了
  3. 实践:CSS Mastery (2th Edition) (《精通CSS:高级Web标准解决方案(第2版)》)Andy budd恐怕是英国最出色的css作者,这本书用简单直接的方式论述了很多实践中组件的正确实现以及可替代方法,包括css3
  4. 深入:很遗憾,css在这方面还没有一本必读著作,也可能并不需要,因为到了这个程度,多是用户体验和视觉设计了,目前最接近的是 Transcending CSS (《超越CSS:Web设计艺术精髓(修订版) 》), 但不断的技术进化使得书中某些部分感觉有些落伍。


关于css3, 她是一个模块化的渐进式增强,且以2.1为基础,因此,请学好css2再学习css3,这方面我认为只需要一本实践书即可,告诉你css3能做到什么,毕竟,原理是共通的。

The Book of CSS3 推荐这本,一个技术人员写的组织清晰的css3模块描述和实践指南,还包括浏览器的实现情况,2011年5月出版,是目前为止最好的。

javascript:

  1. 入门:Eloquent Javascript 一位hacker写的编程入门,书中向hacker,open source, free software的欣赏和痴迷比比皆是, 比如官网下边那个向emacs致敬的console。作者很聪明,这本书的目标读者,beginners, 是不会因为这些小细节而向他叫好的。他想要的,只是把在其中浸淫多年的,真正意义上的编程精神,传达给初学者们而已。 少见地打败了对应的HeadFirst系列(Headfirst Javascript)
  2. 全面:Javascript, The Definitive Guide(6th edition) (《JavaScript权威指南(第6版)》)伴随我们web开发者成长的一本javascript圣经,一直以来都是无可争议的最好与最全面的js书籍,2011年出版了最新版。
  3. 实践:在目前的web开发环境中,我们都是在使用各种js框架,很少自己写框架来开发,因此这本书的位置,应该留给你所使用的框架。如果是jquery,我推荐 Jquery: Novice to Ninja (《JQUERY从菜鸟到忍者(第2版) 》)这本,框架方面的书,经常一本入门的就够了,因为更新实在太快,之后的研究学习只能全靠网络了。
  4. 深入:与css不同,js是一种真正的编程语言,所以对他的深入研究是一个长期的过程,css的深入更偏向技艺/工匠,而js更偏向设计/架构/艺术,我推荐以下几本从不同方面深入js的书,他们都是业界最顶级的js开发团队(yahoo)的成员和同事,因此思路是很统一的,著名的高性能网站建设指南1和2都出自这个团队。
  • Javascipt, The Good Parts (《JavaScript语言精粹(修订版) 》)由JSON的发明者撰写
  • Javascript Patterns (《JavaScript模式》)YSlow的合作开发者撰写
  • High Performance Javascript 最好的zakas的书,虽然我不太喜欢他

附上一些即将出版,我非常想看的书,有先睹为快的朋友可以分享一下心得:

    • Secrets of Javascript Ninja (好像没有中文版)Jquery作者John Resig最新著作
    • Node: Up and Running 认识一下流行的no-block js server
    • Javascript Web Applications (《基于MVC的JavaScript Web富应用开发》)这本号称是对当下js landscape的总结

转载自:财富江湖。更多好文章,程序员创业必看知识请点击:http://caifujianghu.com/article/qiongren-shi-ruhe-yuelai-yueqiong.html/ref=3k91


本文链接:一个合格的前端工程师必看的书籍,转载请注明。

阅读更多内容