2012年9月30日星期日

java中Vector

java中Vector

枚举就是Vector特有的取出方式,枚举和迭代一样。枚举名称以及方法的名称过长。所以,被迭代器替换。取出集合元素的方法有三种:迭代,遍历,for循环使用枚举:package com.day14.wd;import java.util.Enumeration;import java.util.Vector;public class VectorDemo {    public static void main(String[] args){        Vector  vec=new Vector();        vec.add("java01");        vec.add("java02");        vec.add("java03");    Enumeration enu=vec.elements();     while (enu.hasMoreElements()) {        Object object = (Object) enu.nextElement();         System.out.println(object);            }    }}

TAG:

SEOer的认知 :SEO不是网络营销唯一手段

SEOer的认知 :SEO不是网络营销唯一手段

  越来越火爆的seo培训班,越来越多的seoer,让草根站长、企业网站误认为网络营销就是seo,seo就等同于网络营销。这个观点是错误的。不可否认Seo是网络营销最重要的一个手段,但是并不是唯一的网络营销手段。还有更多的营销手段如论坛社区推广、贴吧发帖、流量互换推广、网址导航站推广、edm推广(电子邮件推广)、新媒体推广(微博博客sns 微信通过web2.0应用进行推广)媒介推广等。

  Seo(搜索引擎优化)营销还不如sem(搜索引擎营销)营销。因为只把seo作为网站营销的唯一手段,就等于把自己的命运交给了搜索引擎。一旦你进行违规操作,如无限制的内容采集,关键热词的伪seo创作,过度的seo优化,没事找事大改版,那么你的网站命运就悲催了,面对就是所谓的k站。辛苦换来的确是k站,网站的实质要求是转化率,seo获取再多的无相关性的流量并不能带来转化率反而会被搜索引擎误认为作弊。而sem则能达到低投资高收效的效果。

  Seo之外的网络营销手段则不会把命交给别人,而是通过多种推广手段,达到很好的营销效果。根据自己的能力以及喜好站长们选择适合自己的网络营销手段,只要自己感兴趣的一种手段做到极致,那会是怎样的效果呢?

  Seo之外的网络营销手段之一论坛社区推广。网站新手做的最多的就是论坛社区推广以及贴吧的推广。在论坛社区发相关网站的软文贴以及设置论坛签名。成立网站名称的贴吧,在贴吧利用热门事件,热门关键词吸引流量。

  Seo之外的网络营销手段之二媒介推广(软文推广)。写作功底比较强,喜好写作的站长们可以选择流量互换的推广手段。创作网站相关的软文,在百度新闻容易收录的知名媒体网站发布,换来更多的转载以及新闻的收录。对于媒体本身增加了原创内容,对于网站能够提升网站自身的品牌效益,能够轻松地获取流量。新闻媒体推广是媒介推广的一部分,利用知名的新闻媒体网站对网站自身加强品牌宣传。

  Seo之外的网络营销手段之三网址导航站推广,在著名的网址导航站花钱获得好的展示位置以及推荐,只要舍得花钱投放广告,则能获得不小的流量。或者在网址导航站新站登录里录入自己的网站,对于搜索引擎来说增加一个外链。

  Seo之外的网络营销手段之四流量互换,就是网站之间互相交换广告位,互相带来流量,不过需要网站流量大的才能带来效果,首页的效果比较好,内页的效果不怎么样。同时也可以和搜索引擎交换广告位,一般会出现在搜索引擎的左侧,以一定的文字再现出来。大的如百度左侧的那些都需要竞价的。

  Seo之外的网络营销手段之五新媒体营销,网站的用户来源除了搜索引擎和网址导航入口之外还有就是web2.0的应用。Web2.0的应用如微博、博客、sns 微信等,微博营销,博客营销,sns营销,微信营销这些相信大家都不会陌生。新媒体营销如火如荼的进行着,这个不需要花费多少成本,只需花费时间去经营即可。8.15日的京东国美苏宁价格战就是从微博上挑起的战火。各个商家都比较注重微博营销,新浪微博有企业版微博,专供企业使用。博客营销也是很重要的,有的商家目前仍是会养一些权重高的博客。未来的微信营销更是前程不可估量,移动互联网的发展已经不可阻挡了。

  综上所述,seo不等同于网络营销。seo只是网站推广的一种手段,网站推广只是网络营销的一种方法。网络营销只是网站推广与企业营销的一种途径!所以说seo不是网络营销唯一手段。本文来源于深圳网站建设http://www.0755hsl.com/,转载请保留作者链接,谢谢。


TAG:SEOer 认知 SEO 网络 营销 一手 越火 seo 站长 网站 网站推广 赚钱

Html5中新input标签与Asp.net MVC应用程序

Html5中新input标签与Asp.net MVC应用程序

Html5引入了一些新的input标签,它们包括number, range, email, url, color, date, datetime等。目前它们还不完全支持所有的浏览器。但做为一个Web Developer需要知道它们。Html5 提供了下面这些类型的<Input>标记:

Email (email)

URL (url)

Telephone No. (tel)

Number (number)

Range (range)

Color (color)

Date (date)

Month (month)

Week (week)

Time (time)

Date Time - UTC (datetime)

Date Time - Local (datetime-local)

Search (search)


下面我们来看一下在Asp.net MVC application中如何使用它们, 一开始是个静态的html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>
</head>
<body>
    <form id="form1">
 
    <p>Email :</p>
    <input type="email" name="email" />
 
    <p>URL :</p>
    <input type="url" name="url" />
 
    <p>Telephone No. :</p>
    <input type="tel" name="tel" />
 
    <p>Number :</p>
    <input type="number" name="number" min="1" max="10" step="2"/>
 
    <p>Range :</p>
    <input type="range" name="range" min="1" max="10" step="2" />
 
    <p>Date :</p>
    <input type="date" name="date" />
 
    <p>Month :</p>
    <input type="month" name="month" />
 
    <p>Week :</p>
    <input type="month" name="week" />
 
    <p>UTC Date Time :</p>
    <input type="datetime" name="utcdatetime" />
 
    <p>Local Date Time :</p>
    <input type="datetime-local" name="localdatetime" />
 
    <p>Time :</p>
    <input type="time" name="time" />
 
    <input type="Submit" value="Submit" />
    </form>
</body>
</html>

 

在Opera 12.02 打开后,你可以看到这个效果:

T_HTML5InputInASPNET_02

你也可以使用 Chrome,IE 9,FF 13.01并不支持。我们看到上面呈现出原生的UI,这是我们想要的。在Asp.net MVC application中,可以这样来实现它们:

<%= Html.TextBox("range","2",new {type="range",min="1",max="10"}) %>

上面的代码等同于下面的html:

<input id="range" max="10" min="1" name="range" type="range" value="2">


如果你使用StrongType,那可以这样实现:
<%= Html.TextBoxFor(m => m.MyRange, new {type="range",min="1",max="10"}) %>    

其它一些您可以自行探索,HTML5 推出了一些新的输入元素的输入类型,例如数字、范围、email、url、颜色、日期、日期时间等更多。 这些新的Input类型非常棒,因为它们允许您验证用户输入,而无需使用任何客户端脚本。 目前并非所有浏览器都支持这些输入型的,但下一个版本的所有主要浏览器将支持他们。 你可以开始在ASP.net 应用程序中使用它们,并且很少或没有额外的工作。

希望对您Web开发有帮助。更多参考:

  • W3C input overview by Michael Smith
  • Sandbox of all input types by Estelle Weyl
  • Examples of the input types by Estelle Weyl
  • JavaScript checking by type by Mike Taylor


作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog。


TAG:

【代码组织】♣(function(window, undefined) {})(window);

【代码组织】♣(function(window, undefined) {})(window);

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="utf-8" />    <title></title></head><body>    <script>        // jquery        (function(window, undefined) {            var document = window.document;        })(window);// 不考虑其他略微差异的形式了        // undefined        // javascript中的undefined并不是作为关键字出现的。因此可以允许用户对其赋值        // firefox,全局的undefined始终为undefined        // chrome,undefined始终为所赋的值        /*(function() {            var str;            console.log('1 ' + str);            var undefined = 'value';            console.log('2 ' + undefined);            window.undefined = 'value';            console.log('3 ' + window.undefined);        } ());*/        var undefined = 'value';        (function() {            console.log('1 ' + undefined);        } ());        // 没有实参,相当于传递给形参undefined的就是实参undefined        (function(undefined) {            console.log('2 ' + undefined);        } ());        // window        // 找了2次window        (function() {            window.alert(1);            window.alert(2);        } ());        // 只找了1次window        (function() {            window.alert(3);        } (window));    </script></body></html>

JS 关于(function( window, undefined ) {})(window)写法的理解
http://itping.iteye.com/blog/1679783
关于 jQuery 1.4.4 中 function( window, undefined ) 写法的原因讨论
http://www.fising.cn/2011/01/%E5%85%B3%E4%BA%8E-jquery-1-4-4-%E4%B8%AD-function-window-undefined-%E5%86%99%E6%B3%95%E7%9A%84%E5%8E%9F%E5%9B%A0%E8%AE%A8%E8%AE%BA.shtml


TAG:

2012年9月29日星期六

从SEO论坛现状分析如何获得更有营养的SEO信息

从SEO论坛现状分析如何获得更有营养的SEO信息

  作为SEO从业者我想很多人都跟笔者一样喜欢到论坛上去寻找一些有价值的SEO信息。但不知你是否跟笔者一样发现现今几大SEO论坛都存在着一个很大的问题,那就是虽然每天有好几万的帖子,但是实际上真正的交流贴却为数不多,大多数帖子是一些转载的,纯粹为了链接的帖子,而回复的也很多都是为了签名的那一个链接。

  对于现今SEO论坛的这一种普遍的现象,笔者不禁反思到SEO变化度极大的行业,对于从业者来说需要实时的掌握到最新的SEO信息,而很多论坛平台都沦为外链的工厂。那么我们还可以从什么渠道获得最新的有营养的SEO信息呢?下面笔者就简单的分享笔者每天获得最新SEO信息的几个主要的渠道。

  渠道一:微博

  微博在国内也发展了几年,技术也日趋成熟。拥有一个微博并不算是什么新奇的事情,尤其是做互联网这一行业的人,很多都已经是微博控了。笔者也一样,每天打开电脑都习惯性的看一下微博,那么微博如何帮助我们获得最新有营养的SEO信息呢?

  1:你可以关注一些在SEO行业中有名气的任务,例如夫唯、卢松松、ZAC等等。通过这些人的微博更新,往往你可以从这些名人身上获得有用的SEO信息。

  2:关注一些权威机构。作为SEO,我们面向的机构就是搜索引擎,对此我们可以关注一些与搜索引擎相关的机构微博。例如百度、谷歌、搜搜、搜狗等机构的微博。因为这些机构都有借助微博发布最新消息的习惯,我们就可以借助微博获得最新的搜索引擎信息。

  3:进入微博群。就如同QQ群那样,我们也可以寻找一些与SEO相关的微博群。进入这一些群进行交流讨论,获得更多的SEO信息。

  渠道二:优秀的SEO博客

  SEO博客也是获得有营养的SEO信息的渠道之一。博客的内容质量远远的高于论坛。笔者相信很少有站长会主动在论坛上写出优质的文章,很多都是通过自己的博客发表的。当然我们也不得不正视一个问题,那就是现阶段SEO博客太泛滥了,多到数不来。不过没关系,对于SEO博客我们可以主要关注一些有名气的博客。比如卢松松的卢松松博客,ZAC的博客、月光博客等。这一些博客一般每天都会有更新优质的内容。我们可以直接订阅博客,只要博客一更新我们就可以获得这些优质的信息。

  渠道三:QQ群

  作为SEOer,不可避免的我们需要与其他同行进行交流和讨论。我们可以找一些高质量的QQ群加进去,参与并观察群上人员交谈,往往可以在交谈中获得很多知识。例如百度更新,收录大量下降,看看其他的同行是不是也遇到这种问题。或者我们也可以借助QQ群与其他站长进行合作,互相分享一下外链资源,互相回答一下百度知道等等。通过QQ群学习的有点就在于可以实时的进行知识的沟通,与微博相比QQ群的互动及时性更高,有问题在群里喊一下,一般可以得到不错的建议,当然前提还是你要加到一些高质量的QQ群。

  渠道四,社区平台

  前文中我们谈过现今很多SEO论坛都有内容质量低的问题,但是并非所有的论坛都是如此,有的seo论坛还是经营得不错的,比如BSG论坛,光年论坛、百度针对站长推出的百度站长平台,平台中很多信息都是直接来自官方,更加的权威及时。还有就是类似站长网,Chinaz这样的站长平台也是不错的选择。

  这四个渠道就是笔者获得最新SEO信息的主要渠道。当然从这些渠道的获得知识都是来自他人,想要真正掌握还是需要自己去实践与测试,只有这样才能真正拥有这一些知识。以上是来自omegle陌生人聊天交流网站http://www.qingchat.net/ 对于获得SEO信息的几点看大,希望对大家有所帮助


TAG:SEO 论坛 现状分 析如 何获得 营养 信息 作为 SEO 站长 网站 网站推广 赚钱

移动互联网到底需不需要搜索引擎?

移动互联网到底需不需要搜索引擎?

  从严格意义上来说,搜索引擎是指根据一定的策略、运用特定的计算机程序从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务,并将用户检索的最大相关信息展示给用户的系统。简单说来就是满足用户信息索取的工具,这似乎已经成为互联网用户不可或缺的服务,但是对移动互联网用户来说,似乎并不需要它。

  互联网模式的搜索引擎已经从当初的简单文字内容搜索,衍生到了包括新闻、普通网页、MP3、地图等在内的多功能检索工具。人们通过搜索引擎满足自己获取信息的要求。人们的生活已经离不开搜索,这对于移动互联网的用户也是一样的道理,只是方式发生了改变。

  从现有情况看来,搜索引擎从来都不是移动终端的热门应用或常用工具。当我们需要看新闻时,我们有网易或新浪新闻客户端;当我们需要查看地图时,我们有了高德或谷歌地图应用;当我们想要听个性化的音乐时,我们通过联网的音乐APP即时搜索试听。移动互联网已经成为了APP的天堂,而这些搜索信息入口的被取代,也让搜索引擎被各种APP应用所取代。

  在诸如UC这样的浏览器应用大行其道的同时,搜索引擎的主页甚至都很难出现在用户眼前。当我们进入浏览器时普遍都会显示它自己的首页,这里有众多普及受欢迎的网址大全,在显眼位置会有自己设置的网站登录图标,只需轻轻点击就能进入网站。而用户在使用浏览器上网多半是想通过熟悉的网站看新闻或娱乐,而浏览器的收藏夹和导航让人们不用搜索引擎就可以方便的访问页面。可以说浏览器的导航作用,让搜索引擎被使用的概率越来越低。

  有人会说,用户可以从搜索引擎上查找自己需要的应用,因此搜索引擎还有很大的用武之地。其实不然,就目前情况而言,用户更多是通过PC下载移动终端应用,再通过相关软件对移动终端转移或直接安装。而这些应用也是通过PC端的应用商店平台下载的,根本不需要我们通过移动互联网搜索来实现APP的检索。

  面对这样的现实,大家肯定会疑问:移动互联网究竟要不要搜索引擎?在这里我们虽然没有一个明确而坚定的答案,但是李彦宏的百度确定以百度云作为移动互联网的发展重点,而不是专注于自己已经在互联网取得巨大成功的搜索引擎,从这里我们也能够看出一些端倪。如果互联网巨头都不重点发展移动互联网搜索引擎,那么很可能在移动互联网里搜索引擎确实处境简单。

  当然,搜索引擎是发展成熟的产品,既然有它,移动互联网的用户就不会放弃它,只是使用量远低于互联网而已。九方网认为,以现阶段而言用户热衷搜索的习惯并没有变,变的只是搜索形式,APP取代了大部分过去由搜索引擎承担的工作。就发展现状而言搜索引擎在移动互联网没有多大市场,也许未来会有机会吧。

  来源:九方网http://www.j1f3.com/


TAG:移动互联网 搜索引擎 站长 网站 网站推广 赚钱

四大手段获取有价值SEO信息

四大手段获取有价值SEO信息

  随着SEO行业的火热,越来越多的人跻身到网站优化推广的大队伍,但是关于SEO方面的知识,在网上真正有价值的文章却少的可怜,下面笔者就简单的分享笔者每天获得最新SEO信息的几个主要的手段。

  手段一:SEO高手的博客

  SEO博客也是获得有营养的SEO信息的渠道之一。博客的内容质量远远的高于论坛。笔者相信很少有站长会主动在论坛上写出优质的文章,很多都是通过自己的博客发表的。当然我们也不得不正视一个问题,那就是现阶段SEO博客太泛滥了,多到数不来。不过没关系,对于SEO博客我们可以主要关注一些有名气的博客。比如卢松松的卢松松博客,ZAC的博客、月光博客等。这一些博客一般每天都会有更新优质的内容。我们可以直接订阅博客,只要博客一更新我们就可以获得这些优质的信息。

  手段二:微博

  微博在国内也发展了几年,技术也日趋成熟。拥有一个微博并不算是什么新奇的事情,尤其是做互联网这一行业的人,很多都已经是微博控了。笔者也一样,每天打开电脑都习惯性的看一下微博,那么微博如何帮助我们获得最新有营养的SEO信息呢?

  1:你可以关注一些在SEO行业中有名气的任务,例如夫唯、卢松松、ZAC等等。通过这些人的微博更新,往往你可以从这些名人身上获得有用的SEO信息。

  2:关注一些权威机构。作为SEO,我们面向的机构就是搜索引擎,对此我们可以关注一些与搜索引擎相关的机构微博。例如百度、谷歌、搜搜、搜狗等机构的微博。因为这些机构都有借助微博发布最新消息的习惯,我们就可以借助微博获得最新的搜索引擎信息。

  3:进入微博群。就如同QQ群那样,我们也可以寻找一些与SEO相关的微博群。进入这一些群进行交流讨论,获得更多的SEO信息。

  手段三:QQ群

  作为SEOer,不可避免的我们需要与其他同行进行交流和讨论。我们可以找一些高质量的QQ群加进去,参与并观察群上人员交谈,往往可以在交谈中获得很多知识。例如百度更新,收录大量下降,看看其他的同行是不是也遇到这种问题。或者我们也可以借助QQ群与其他站长进行合作,互相分享一下外链资源,互相回答一下百度知道等等。通过QQ群学习的有点就在于可以实时的进行知识的沟通,与微博相比QQ群的互动及时性更高,有问题在群里喊一下,一般可以得到不错的建议,当然前提还是你要加到一些高质量的QQ群。

  手段四,社区平台

  前文中我们谈过现今很多SEO论坛都有内容质量低的问题,但是并非所有的论坛都是如此,有的seo论坛还是经营得不错的,比如BSG论坛,光年论坛、百度针对站长推出的百度站长平台,平台中很多信息都是直接来自官方,更加的权威及时。还有就是类似站长网,Chinaz这样的站长平台也是不错的选择。

  这四个渠道就是笔者获得最新SEO信息的主要渠道。当然从这些渠道的获得知识都是来自他人,想要真正掌握还是需要自己去实践与测试,只有这样才能真正拥有这一些知识。

  以上是来自曲阳雕刻http://www.lsdk.com.cn/ 对于获得SEO信息的几点看大,希望对大家有所帮助。


TAG:四大手 段获取 价值 SEO 信息 随着 SEO 行业 火热 站长 网站 网站推广 赚钱

两款国外SEO优化工具推荐

两款国外SEO优化工具推荐

  SEO博客在站长常用免费SEO工具一文基本上都是推荐国内SEO工具,本文福建SEO将为大家带来的是:两款国外SEO优化工具推荐。

  1、重定向检查器,Redirect Checker,也可以称为页面跳转方式检查工具。Chinaz站长工具里面的HTTP状态查询也可以实现部分功能。

  Redirect Checker:http://www.internetofficer.com/seo-tool/redirect-check/更加强大。

  Which redirection ?在文本框粘贴需要检查的网址,点击Check Redirects即可看到结果。这里的英文比较简单,一般SEO优化人员都看得懂。

  Redirect Checker两大用处:

  A、常规的HTTP状态码查询,如200-服务器成功返回网页、404-请求的网页不存在、503-服务不可用;

  B、辨别网站或者网页使用的跳转类型,如js跳转和meta refresh跳转;

  SEO博客简单总结就是:可以让我们不通过查源码就识别出网站的一些状况。

  2、网页相似度检查工具,Similar Page Checker,也可以称为相似页面检测器。

  网址:http://www.webconfs.com/similar-page-checker.php。Enter First URL文本框粘贴URL,Enter Second URL文本框粘贴另外一个URL,点submit就可以了。

  Similar Page Checker是如何工作的?搜索引擎是在我们之前就发现网站内容是复制或者相似的,这个工具可以让我们确定两个页面相似程度的百分比,避免我们被惩罚后还不知道,而我们需要做的就是尽可能降低页面相似度。搜索引擎对于重复内容过滤是有一套筛选机制的,如果你的英文不错,可以看看http://www.webconfs.com/duplicate-content-filter-article-1.php,这篇文章将帮助您理解你为什么可能会被过滤,以及如何避免它。

  Similar Page Checker的好处:SEO从业人员可以通过对两个页面进行相似度分析,然后调整页面模版,减少共同模块,增加页面更新机制,如相关内容、随机内容、热点内容等,整体页面页面更加丰富,当然根本上还是要提高文章内容的原创度了。

  福建SEO博客在后续的文章将为大家带来的是SEO优化如何降低页面相似度,敬请期待!

  声明: 本文由福建SEO原创编译,转载请保留链接: http://www.fqseo.org/1232.html


TAG:国外SEO优化工具 站长 网站 网站推广 赚钱

SEO工作在中秋、国庆黄金周如何安排

SEO工作在中秋、国庆黄金周如何安排

  seo工作是持续性的,如果中途长时间停下来了就会影响网站排名。即将来来临的比较长的假期,中秋、国庆黄金周,如何在这些假日里合理安排seo工作,保证网站排名稳定,苏州SEO有如下建议。

  1、确保网站服务器和域名在长假期间保持稳定运行

  有些SEO朋友很粗心,连服务器和域名到期了都不知道的,然后刚好碰上放假就更抛之脑后了,等到假期回来之后,才猛然发现网站已经一个多星期不能访问了,在看排名,全没了,这就悲剧了!排除到期之外,最好使用服务器监控短信通知,超级监控有这个功能,建议使用。

  2、假期网站内容日常更新照常

  内容更新平时一般是人工每天进行内容编辑和发布的,而到了放假,也不能要求我们的编辑继续来搞了,还得要放假的,那么这个问题如何解决呢?这个大家可以使用自动发布的功能来解决的,如果你的网站没有可以让技术开发一个小工具就行了,有的网站是有自动发布功能的,放假前让编辑准备假期的文章就好了,然后每天定时自动发布。

  3、外链可以在假期前后发布

  外链这个问题其实比较难搞,貌似没有什么自动发布外链的,群发软件除外,所以这里建议可以在放假前后多发点外链,假期中能发则发,不能也就只有耽误几天了,对于大站,稳定的站,几天不做外链是影响不大的。

  4、安排值班人员

  如果公司许可的,可以安排值班人员留意网站情况的,如果没有估计就要seo主管来辛苦了,毕竟自己是主管了,如果网站出事,老板还是找你的。

  最好这些准备工作,网站应该是可以安全度过长假的,希望大家的网站在假期以后依然有较好的排名上升。


TAG:假日SEO 站长 网站 网站推广 赚钱

企业站点优化需要注意的四大误区

企业站点优化需要注意的四大误区

  在此我把企业站点管理员通通列入站长行列,毕竟他们也是要做网站优化,也同样拥有网站源文件的管理权限。企业站长是一群比较特殊的群体,因为我们都知道排名变动很正常,优化需要一颗淡定的心,但这个群体确是最难保持淡定心态的,企业站的站长没有耐心往往是由于来自老板的压力,老板考虑到成本和利润的因素往往就失去了耐心。企业站长为了排名往往把重心放在更新和外链上,忽视一些常见的误区极大了限制了站点排名,在这里个人谈谈企业站一些常见的误区:

  误区一:把企业介绍、企业新闻和关于我们放到最主要位置

  企业的产品得到更好的营销效果才是企业站点最终的归宿,而把企业重复的介绍文字罗列、添加行业新闻这些都是提高网页噪音的反作用优化。解决这个问题需要我们弄清一件事,就是客户进入我们的企业站点他想要了解什么?是想知道我们这个企业的规模、老板简历等等这些东西吗?不是,客户最直接的想法就是了解我们的产品,而我们的目的也是销售我们的产品,所以,我们应该把关于产品的内容放到最主要的位置。

  1、解答客户最急需的问题:产品的选购、功能和属性,所以有必要对于产品加上评价和FAQ(常见问题解答)

  2、其次才是解决信用度的问题:这里可以加一点企业简介的内容

  误区二:频繁更新行业新闻和企业新闻

  很多站长觉得高收录就是高权重,高排名,其实看看搜索我们就会知道并不是这样,其实做企业站没有必要追求高收录、多收录,我们要保证搜索引擎对于我们企业站点的收录都是有价值的页面,所以更新企业新闻的方式是错误的。另外,对于一些小规模的企业企业站点,完全没有必要加上行业新闻的栏目。比如我是做家教培训网站的,如果为了更新企业站点内容而强行加入很多的行业新闻,比如机学校资讯,国内教育等这些都是错误的。

  误区三:错误的使用锚文字

  锚文字是关键词了解目标网页主题和关键词的直接方式。最典型的是使用常见的垃圾锚文字:更多、more、点击这里等,另外一种情况就是为了追求一种整齐的效果而牵强的一律使用3或4个字的锚文字。

  误区四:选择不恰当的关键词

  一种情况是主页做了某个关键词却没有对这个关键词进行展开,另一种情况是主页只有一个核心词,一切内容都是围绕这个词展开。这样的后果就是导致企业站点的相关性和匹配减弱。另外,选择长尾关键词做流量也应该选择跟网站主题相关的长尾词。

  当然,以上仅仅是本人对企业站点的一点小见解,期待着和大家深入探讨。

  来源:http://www.dgqjj.com/bbs/read-htm-tid-1345.html


TAG:网站优化 站长 网站 网站推广 赚钱

至死不逾选择白帽SEO的理由

至死不逾选择白帽SEO的理由

  世间本没有白帽SEO这一说,因为SEO这条路走得人多了,就形成了两派,分别是白帽SEO与黑帽SEO,哪一派才是武林至尊且先不管,点水今天只说我要选择白帽SEO的理由:

  一,什么是白帽SEO?

  白帽SEO是指通过使用符合搜索引擎规律以及不伤害用户体验的方法来优化网站,从而实现在搜索引擎中获得理想的自然排名,流量和树立品牌形象的目的。

  二,白帽SEO的方法

  我们先了解搜索引擎的变化:

  1,文本分析阶段。通过页面关键词来判断网页的相关性而决定排名。

  2,链接分析阶段。通过推荐网站的数量与质量来决定其排名。

  3,行为分析阶段。将用户行为加入到网站的排名因素中来。

  在文本分析阶段,在Title,kword和descrption标签中以及内容中加入一定密度的关键词,就很容易能够获得不错的排名,而在链接分析为主的阶段,只要通过建立大量的外链,便可以轻易取得不错的排名。而在目前阶段,搜索引擎的算法显然已经复杂很多,不再单单将文本与链接做为决定排名的主要的因素,更多的用户行为将被列入排名因素之中。

  我们再来了解搜索引擎的目的:

  1,搜索引擎希望能够更简单的抓取和更容易的处理互联网上的网页。海量增长的数据总是在考验他们的技术。

  2,搜索引擎需要能够最快最简单的让用户搜索到自己需要的内容。这是搜索引擎能够生存的核心。

  3,搜索引擎需要更多新鲜与原创的内容,而不想天天抓取重复的内容来消耗他们的精力。

  4,搜索引擎需要保持健康的生态循环,不希望会被SEO能够恶意的破坏其自然排名次序。

  5,而最重要的一点是:搜索引擎也需要盈利,他不会大度到允许SEO人员与其利益产生冲突。百度是很好的例子。

  白帽SEO应该遵循的原则:

  1,给搜索引擎同时也是给用户提供高质量的原创性内容。内容才是网站的灵魂,内容策略也是SEO工作的最大的难点。

  2,自然的链接增长。搜索引擎能够很清楚的清楚一个网站的链接增长规律是否合理。

  3,优质的用户体验。不要说用户体验与排名不关,只能说明你落伍了,好的用户体验不仅仅可以给你带来更多的回访,更会让你的网站在搜索引擎中的表现形成一个良性循环。

  三,白帽SEO的好处

  1,你投入的时间和精力永远不会是无用功。不会立杆见影,但质变需要量变。

  2,白帽SEO能够建立一个能够长远发展的公司,而黑帽永远只能是打酱油的。

  3,白帽方法你是可以公开的,不用担心被人抄袭而超越你。而黑帽方法你得藏着。一个是练内功,一个是学外功。你懂的。

  4,优质原创的内容总是受用户欢迎,制造垃圾信息总是会让人反感。

  5,白帽是帮你建立一个品牌的网站,用户需求稳定,你不用担心搜索引擎排名不稳定。

  6,白帽的方法做的是一份事业,人不能没有长远的眼光!

  文章来源点水SEO博客,原文地址:http://www.semrace.com/jishu/whiteseo.html

  四,知识解答

  问:是不是只要是采用白帽SEO方法就一定会有很好的排名呢?

  答:在搜索引擎中决定排名的因素很多,比如文章中提到的搜索引擎的利益,特别是百度,所以不一定你使用了正确的方法就一定会很快有合理的排名,搜索引擎的算法也不是天衣无缝,但是以结果为导向,白帽SEO是最佳的选择。


TAG:白帽SEO 站长 网站 网站推广 赚钱

移动互联网需不需要搜索引擎

移动互联网需不需要搜索引擎

  从严格意义上来说,搜索引擎是指根据一定的策略、运用特定的计算机程序从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务,并将用户检索的最大相关信息展示给用户的系统。简单说来就是满足用户信息索取的工具,这似乎已经成为互联网用户不可或缺的服务,但是对移动互联网用户来说,似乎并不需要它。

  互联网模式的搜索引擎已经从当初的简单文字内容搜索,衍生到了包括新闻、普通网页、MP3、地图等在内的多功能检索工具。人们通过搜索引擎满足自己获取信息的要求。人们的生活已经离不开搜索,这对于移动互联网的用户也是一样的道理,只是方式发生了改变。

  从现有情况看来,搜索引擎从来都不是移动终端的热门应用或常用工具。当我们需要看新闻时,我们有网易或新浪新闻客户端;当我们需要查看地图时,我们有了高德或谷歌地图应用;当我们想要听个性化的音乐时,我们通过联网的音乐APP即时搜索试听。移动互联网已经成为了APP的天堂,而这些搜索信息入口的被取代,也让搜索引擎被各种APP应用所取代。

  在诸如UC这样的浏览器应用大行其道的同时,搜索引擎的主页甚至都很难出现在用户眼前。当我们进入浏览器时普遍都会显示它自己的首页,这里有众多普及受欢迎的网址大全,在显眼位置会有自己设置的网站登录图标,只需轻轻点击就能进入网站。而用户在使用浏览器上网多半是想通过熟悉的网站看新闻或娱乐,而浏览器的收藏夹和导航让人们不用搜索引擎就可以方便的访问页面。可以说浏览器的导航作用,让搜索引擎被使用的概率越来越低。

  有人会说,用户可以从搜索引擎上查找自己需要的应用,因此搜索引擎还有很大的用武之地。其实不然,就目前情况而言,用户更多是通过PC下载移动终端应用,再通过相关软件对移动终端转移或直接安装。而这些应用也是通过PC端的应用商店平台下载的,根本不需要我们通过移动互联网搜索来实现APP的检索。

  面对这样的现实,大家肯定会疑问:移动互联网究竟要不要搜索引擎?在这里我们虽然没有一个明确而坚定的答案,但是李彦宏的百度确定以百度云作为移动互联网的发展重点,而不是专注于自己已经在互联网取得巨大成功的搜索引擎,从这里我们也能够看出一些端倪。如果互联网巨头都不重点发展移动互联网搜索引擎,那么很可能在移动互联网里搜索引擎确实处境简单。

  当然,搜索引擎是发展成熟的产品,既然有它,移动互联网的用户就不会放弃它,只是使用量远低于互联网而已。九方网认为,以现阶段而言用户热衷搜索的习惯并没有变,变的只是搜索形式,APP取代了大部分过去由搜索引擎承担的工作。就发展现状而言搜索引擎在移动互联网没有多大市场,也许未来会有机会吧。

  来源:九方网http://www.j1f3.com/


TAG:移动互联网 搜索引擎 站长 网站 网站推广 赚钱

深入分析虚拟链接的秘密

深入分析虚拟链接的秘密

  虚拟链接貌似一个非常神秘的东西,其实不然,有些新手们还是存在一定的误解和疑虑,。今天给大家分享一点虚拟链接的秘密,同时教给大家怎么做虚拟链接。

  1、虚拟链接是什么?

  虚拟链接是查询网站时遗留的查询外链或者叫做缓存。举例来讲:我们在站长工具查询网站www.shiyanji5.com的alexa排名,在左侧会出现这个查询的查询记录。如果www.shiyanji5.com这个域名出现在左侧的时候,这个页面正好被百度收录,那么这个网站就增加了一条反链,这个反链就是所谓的虚拟链接。

  2、虚拟链接有没有用?

  虚拟链接能够被百度收录,能增加你网站的domain数量,那你说这种链接有没有用?肯定有用呀。那这个虚拟链接有多大的作用呢?权重比较低,作用也比较小。当然,在这里我要问大家一个问题:论坛里或软文里的一个明链作用大不大呢。所以说,不管你做哪种链接,单个或少数肯定作用不大,但是大批量的呢?

  3、虚拟链接怎么做?

  目前市场上有很多刷外链的工具和网站,这些都可以利用。百度搜索自动外链,外链群发,大家会找到很多。利用这些工具盒网站,可以批量做这个虚拟链接。

  4、虚拟链接刷多长时间有效?

  百度的更新周期在20天左右,也就是说,刷虚拟链接你可能看不到效果,但是一直刷的话,肯定会看到效果。

  5、刷虚拟链接会不会被百度认为作弊,会导致k站?

  目前不会,将来也应该不会。但是百度将来可能禁止收录这种虚拟链接。且听我细细道来。百度绝对不会允许K站的因素放在站外,特别是一些非常容易做到的一些操作。因为K站的因素在站外的话,那我们岂不是可以去进行K站的操作,那百度的风险不就非常大。所以刷虚拟链接不会导致K站。

  6、刷虚拟链接对网站有没有负作用?

  肯定的讲,会有一定的负作用。但这个负作用是建立在虚拟连接数急速下降的基础上,但是影响不会很大。下面详细说明。

  大家清楚,任何一种链接都有生命周期,虚拟链接的生命周期更短一些。如果你刷了n多虚拟链接,然后你不刷了,而且其他方面的链接也没有做。那么等这些虚拟链接生命周期结束后,你的网站总的反链会降低很多。这时,会对网站的权重有一定的影响。

  7、如何利用好虚拟链接?

  刷虚拟链接只是你操作的一种,你还需要增加其他方面的反链建设工作。如果一个新站,再没有任何权重的情况下,你去交换友链是比较难的。你可以利用虚拟链接这种比较简单的操作去提高网站权重,再有了一定的权重之后,重点去做友链等一些起初你不容易操作的一些事情。只要你掌握虚拟链接在总的链接建设中的比例,那么即使你不再做虚拟链接,虚拟链接下降,你网站的权重也不会受到影响。

  本文编写不容易,给大家带来知识的同时,欢迎转载,让更多的站长了解该知识。转载时,请不要对本文做任何修改,不要把它当成你的原创,谢谢您的合作。如有任何疑问,可以加群:SEO技术交流群259111006进行交流。


TAG:虚拟链接 反链建设 站长 网站 网站推广 赚钱

还原大备份mysql文件失败的解决方法

还原大备份mysql文件失败的解决方法

今天在维护公司CRM的时候,恢复一个大的mysql数据库,恢复失败.

用下面方法解决(管理mysql用的是navicat).,设置以下几个参数的值后就正常了,以下语句也可以在mysql的控制台上执行 .

show variables like '%timeout%';

show variables like '%packet%';

set global max_allowed_packet=99328000;

set global wait_timeout=2880000;

set global interactive_timeout=2880000;

-- wait_timeout=2880000
-- interactive_timeout=2880000
-- max_allowed_packet=100M

PS:如果是在服务器上,要记得恢复后这几个参数要调回去,不然性能会下降的,具体这几个参数功能,大家自己找找吧.


TAG:

SQL 2008官方下载地址

SQL 2008官方下载地址

SQL 2008下载地址

 


SQL2008(10.00.1600)下载地址:
中文版(3.28GB):http://sqlserver.dlservice.microsoft.com/dl/download/B/8/0/B808AF59-7619-4A71-A447-F597DE74AC44/SQLFULL_CHS.iso
英文版(3.03GB):http://sqlserver.dlservice.microsoft.com/dl/download/9/C/0/9C036510-3218-4258-8B03-67DC1D6A497C/SQLFULL_ENU.iso
SQL 2008 R2(10.50.1600)32位中文版下载地址:http://care.dlservice.microsoft.com/dl/download/1/E/6/1E626796-588A-495C-917B-321093FB98EB/2052/SQLFULL_x86_CHS.exe?lcid=2052&ptype=pcare
SQLServer2008SP2补丁下载地址(注意:这个补丁是打在SQL2008上的):
中文版(292M):http://download.microsoft.com/download/8/B/6/8B693FAC-34E8-418F-9423-464931FEEDE4/SQLServer2008SP2-KB2285068-x86-CHS.exe
英文版(284M):
SQLServer2008R2SP1补丁(10.50.2500)下载地址(注意:这个补丁是打在SQL 2008R2上的):
中文版(205M):http://download.microsoft.com/download/0/9/9/099E0C83-072B-42A5-83A0-9BB3D2E6E2A3/SQLServer2008R2SP1-KB2528583-x86-CHS.exe
英文版(201M):http://download.microsoft.com/download/7/7/6/776727E8-57EE-4AB5-BC69-6CCDF04A2A70/SQLServer2008R2SP1-KB2528583-x86-ENU.exe
SQLManagementStudio_x86(2008)下载地址:
中文版(174M):http://download.microsoft.com/download/0/9/9/099E0C83-072B-42A5-83A0-9BB3D2E6E2A3/SQLManagementStudio_x86_CHS.exe
英文版(153M):http://download.microsoft.com/download/7/7/6/776727E8-57EE-4AB5-BC69-6CCDF04A2A70/SQLManagementStudio_x86_ENU.exe
SQLManagementStudio_x64(2008)英文版下载地址:http://download.microsoft.com/download/7/7/6/776727E8-57EE-4AB5-BC69-6CCDF04A2A70/SQLManagementStudio_x64_ENU.exe


TAG:

站长如何做好SEO:分工协作 效率百倍

站长如何做好SEO:分工协作 效率百倍

  自从了解了seo,经过近一年的时间去实践与操作,做的确是同一件事情。在客户网站的基本优化好后,就是不断给客户的网站添加原创文章,增加外部链接,然后排名就很自然的上来了。

  虽然做的事情主要只有两件,但却非常浪费时间。原创文章当初开始写的时候非常的费力而且写不出来文章,不知道怎么动笔,就算后来写顺了写一篇文章也要花不少时间,何况每天要给客户写3篇原创文章。就拿我那十几个客户来说吧,每天文章就几十篇,一天的时间就过去了。

  再说外链,我们的标准是每个网站每天做至少3-5个外链。不断的注册,不断的发帖,最可恨的是有的网站注册后不能发帖,可以发帖的不能留链接,留了链接过一天被删除了。这样去做外链浪费的时间太多了,自己根本就做不过来。

  迷茫了,难道seo就是要把大量的时间浪费在这里吗,难道我们一天只能维护这一点客户吗。后来认识了星月seo(qq:2294480961),给我解决了大问题,在此感谢。一开始我找他们代做外链,每天3个,价格很便宜。于是我就让他们做一个月,看看效果再说。他们把每天做的外链我都可以随时查看到,非常方便.我看了下,全部是独立网站,网站都带pr,而且锚文本关键词也做了链接,比我自己做的都好,关键是他们做的不删除。于是外链就找他们代工了,这样就解决了我的一个大问题,节省了我的很多时间。

  看他们做的东西还不错,我就问他们原创文章怎么写的,他们说原创文章客户最好自己写,实在写不了的交给他们,价格有点高。我一听多高啊,原来就几块钱,呵呵。于是我也找他们代工了。

  现在,我做的主要任务就是接单,谈生意,和朋友研究下优化思路 百度算法,接到单子基本的网站操作好后就外包给他们,真是爽呆了,我也不用请人做,划算。

  做seo,要学会分工协作,提高效率。什么都自己做,当单子多了就根本做不完,要善于使用周边资源,让自己的工作更加有效率,钱也赚更多,呵呵


TAG:站长 如何 做好 SEO 工协 效率 百倍 seo 一年 站长 网站 网站推广 赚钱

地方人才网站如何谋得自我发展的RMB

地方人才网站如何谋得自我发展的RMB

  关于网站盈利,我不知道在大家脑子里会浮现怎样的情景,是点击广告,还是主营业务,但不管怎样,一个网站要想承担起更多的发展任务,那么它自身的盈利能力就一定不能仅仅局限于这些方面,尤其是现在经营的岳阳人才网站,并没有看得见摸得着的产品,如果要想让它实现盈利,就一定要在赚钱能力上多下功夫。

  根据网站性质进行盈利:

  A 因为自己网站性质的特殊性,以至于来我网站寻求帮助的大部分都是些大四毕业生、研究生毕业生或是社会散员,他们除了需要就业指导外,更需要的是真真正正的工作岗位,所以利用这个需求点我就和当地一些人才招聘网站或是有实力的企业进行合作,通过给他们输送人才流量然后赚取佣金,当然还会选择拉一些赞助商,通过给他们推销服务,比如租房信息,门面租赁信息等,切实打造满足人才流向以及工作需求方面的全方位导航网站。

  B 克服自身瓶颈,进行捆绑销售。就像前面说到的那样,仅靠流量显然不能成为咱们盈利的主要手段,但是作为一个交流站本身没有实际意义上的商品,所以网站的盈利不能靠销售量,这算是我们的一个短板,但这并不意味着我们没有盈利的能力,因为我们除了提供就业岗位,还可以提供岗位旁边的房屋租赁以及一些二手物品的出售,而这些都可以成为我们服务的范围,就像我的网站现在和长沙本地的门面网站进行合作,如果你想做生意,那么完全可以通过我的合作伙伴找到适合自己的门面,而这就是我们倡导的工作+创业+资源盈利模式,满足寻求工作人群的一切需求。

  根据网站主流人群进行盈利

  C 赞助大学社团,进行品牌建设。之前笔者提到自己的网站主要和学生打交道(当然也有社会散员),但是每年的毕业生是我的网站必须要抓住的资源。那么怎样做才能博得他们的好感呢?没错,那就是学生会,只要我们投入少许金额的钱就能获得他们外联部的认可以及合作机会,在每次举办活动的时候就能打上我们的横幅,效果肯定比在网上做广告实在,还有学生终究是学生,没有太多小心眼,都是实打实的干活,所以作这方面的推广实在,还有来了流量肯定就要挂广告,但是整个首页我只挂了一个广告,那就是关于淘宝开店培训的,因为我做过调查,大学生通常对网赚比较感兴趣,而拉上一个关于开店的培训广告自然是吸引力十足,点击率相当可观。

  D 既然是学生,那么培训市场对他们绝对有吸引力。比如就业指导,比如计算机二级考试指导等,人才网站绝对不能局限于自己的主营业务,要根据面向人群进行一个服务范围的重新定位,而且长沙周边有很多大学,这是一个地区优势,所以我们会仿照北京四中网校的模式给学生授课,或是在周末在大学校园周边进行设计科目的培训,大学生学习是怎么样的情况大家也都知道,所以开展一个培训课程,尤其是在毕业之际,生源是很多的。如果人才网站自身做不到,那么完全可以和别人合作,以介绍学员划分收入提成。

  根据网站发展方向进行盈利:

  E 人才网站竞争的激烈程度相信很多站长都心里有数,如何增加用户粘度成为我们每一个站长的头等大事,而未来仅仅依靠介绍工作显然不能满足长远发展的需求,毕竟好工作也需要人才来实现,否则变数太大,影响品牌的信誉,所以在未来发展上,我们依靠自身已有的会员优势,开始涉足创业方面的盈利,比如现在在做的门面以及写字楼的租赁,而这些资源就是未来我们奠定交流网站的基础。

  F 不想当将军的士兵不是好士兵,所以未来我们的目的是将网站建设成58同城那样的模式,树立起一个资源寻找平台,所以依据这个发展方向,我们会在现有的网站中拓展出一个子目录,可以让大家上传自我资料以及相当案例,让商家去挑选职工,从而实现应聘对象的角色转化,提高就业成功效率。而网站可以从中抽取一定的介绍佣金。

  关于盈利方面,我想大家都会有自己更多的想法,并不一定是我自己说的这些,只要是合法的,有创意的,那么就可以成为咱们网站生存下去的基础。以上来自我的网站长沙门面网 http://cs.51hsp.cn/ ,欢迎转载,谢谢。


TAG:方人 网站 如何 谋得 自我发 RMB 关于 网站 盈利 站长 网站 网站推广 赚钱

使用Html5开发Windows 8应用

使用Html5开发Windows 8应用

如果你是一位有经验丰富的Web开发人员,你会爱上Visual Studio 2012提供的HTML5/JavaScript/CSS3的选项。

我们知道,10月26日Windows 8将正式发布,这表示开发人员得做出决定是使用HTML5/JavaScript/CSS还是XAML/C#或者Visual Basic或者C++来构建Metro样式的应用程序。

很多Web开发人员会选择HTML5/JavaScript/CSS,因为对它已经很有经验了。作出使用什么来开发的决定,下一步就是理解Windows Runtime(WinRT)和它的新API是如何与Windows 8交互的。

这篇文章将带着你使用HTML5/JavaScript/CSS3构建一个Metro应用程序。

开发环境

1.Windows8。
2.Visual Studio 2012
3.建议下载Metro app samples,下载地址:http://code.msdn.microsoft.com/windowsapps/Windows-8-Modern-Style-App-Samples。


1.环境搭建好后,启动Visual Studio 2012,选择其他语言->JavaScript->Windows Metro style,选择“空白应用程序”,名称设置为“VSMagJS”,单击“确定”。如下图所示:

1

从上图可以看到,JavaScript下的Windows Metro style提供了5个模板,选中模板,在右侧会有相应的介绍。

组件

2.创建项目成功后,打开“解决方案资源管理器”,会看到项目的结构如下图所示:

2

引用:包含此应用程序功能所需要的WinRT API。默认只添加了一个:Windows Library for JavaScript 1.0 RC,包括ui-dark.css和ui-light.css两个文件,同样是WinRT需要的基本API文件。在这个例子中,还包括英语语言的全局字符串文件。
CSS:default.css文件很简单,它只包含CSS3媒体查询,以决定设备方向。

Images:这个文件夹包括4张图片用于表示应用程序的图标。它还包含启动画面(splashscreen),在应用程序开始时显示。
JS:包括一个文件——default.js——当应用程序启动时运行。它包含样板代码以帮助你快速入门。
Default.html:标准的HTML页。

Package.appxmanifest:描述应用程序的部署包,允许更改容量、声明等等。
VSMagJS_TemporaryKey.pfx:个人信息交换文件,换句话就是应用程序的数字证书。

修改开始页

打开default.html,会看到如下图所示的内容:

3

上图中,<!DOCTYPE html>是使用了HTML5文档类型,往下是使用了其他标准的HTML标签,如meta,title等。往下可以看到WinJS引用,再往下就是针对具体应用程序的引用,default.css确定设备的方向。

下面来修改default.html页,代码如下:

   1:  <body>
   2:      <h1>Hello VSM Reader</h1>
   3:      <p>What's your favorite magazine? </p>
   4:      <input id="magazineInput" type="text" />
   5:      <button id="questionButton">OK </button>
   6:      <div id="questionOutput"></div>
   7:  </body>

单击调试工具拦中的“本地计算机”按钮会出现如下图所示:

4

到目前为止,当在文本框中输入内容或单击按钮什么都不会发生。

给开始页添加逻辑

打开default.js,会看到如下图所示代码:

5

注意“strict”关键字对代码提供额外的错误检查。

现在添加一些代码使default.html具有交互的功能。找到下面的代码:

args.setPromise(WinJS.UI.processAll()); 

在它的下面,添加下面三行代码:

// Get the Element ID of our OK Button and attach an event handler to it.
var OKButton = document.getElementById("questionButton");
OKButton.addEventListener("click", OKbuttonClickHandler, false);

下面添加一个名为OKbuttonClickHandler的函数,当OK按钮点击后执行。

在app.oncheckpoint下面添加这个函数:

   1:  function OKbuttonClickHandler(eventInfo) {
   2:    var answer = document.getElementById("magazineInput").value;
   3:    if (answer == 'Visual Studio Magazine') {
   4:      var finalanswer = "Good Answer!";
   5:    }
   6:    else {
   7:      var finalanswer = "Try Again! - Hint type Visual Studio Magazine";
   8:    }
   9:    document.getElementById("questionOutput").innerText = finalanswer;
  10:  }

再次运行程序,运行结果如下图所示:

6

快速轻松的设置应用程序样式

默认情况下,default.html引用下面的代码,使用dark样式:

 <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />

Metro UI也提供了一个light主题,在default.html中引用如下代码,应用程序就会应用light样式:

<link href="//Microsoft.WinJS.1.0.RC/css/ui-light.css" rel="stylesheet" />

再次运行程序,如下图所示:

7

了解更多

是时候进一步探讨package.appxmanifest了。如前面所述,package.appxmanifest描述了应用程序的部署包。可以通过双击该文件打开它,如下图所示:

8

每个页面都提供了访问应用程序可能需要或可能不需要的特定功能。当点击Tab时,下面会出现相应Tab页的介绍。例如,应用程序UI,它的下面对它的解释是:使用此页可以设置用于标识和描述应用程序的属性。

打包应用程序

打包应用程序,执行下面的步骤:

点击“项目”——>应用商店——>创建应用程序包,如下图所示:

9

弹出对话框:

13

是否上传到Windows商店,选择“否”,点击“下一步”:

14

单击“创建”:

15

打开上面的目录,找到Add-AppDevPackage.ps1,右击选择“使用PowerShell运行”:

16

结束语

以上内容大部分翻译自Windows 8 Apps With HTML 5这篇文章!


TAG:

MYSQL插入处理重复键值的几种方法

MYSQL插入处理重复键值的几种方法

当unique列在一个UNIQUE键上插入包含重复值的记录时,默认insert的时候会报1062错误,MYSQL有三种不同的处理方法,下面我们分别介绍。
先建立2个测试表,在id列上创建unique约束。
mysql> create table test1(id int,name varchar(5),type int,primary key(id));
Query OK, 0 rows affected (0.01 sec)
mysql> create table test2(id int,name varchar(5),type int,primary key(id));
Query OK, 0 rows affected (0.01 sec)
mysql> select * from test1;
+-----+------+------+
| id  | name | type |
+-----+------+------+
| 101 | aaa  |    1 |
| 102 | bbb  |    2 |
| 103 | ccc  |    3 |
+-----+------+------+
3 rows in set (0.00 sec)
mysql> select * from test2;
+-----+------+------+
| id  | name | type |
+-----+------+------+
| 201 | aaa  |    1 |
| 202 | bbb  |    2 |
| 203 | ccc  |    3 |
| 101 | xxx  |    5 |
+-----+------+------+
4 rows in set (0.00 sec)
1、REPLACE INTO
发现重复的先删除再插入,如果记录有多个字段,在插入的时候如果有的字段没有赋值,那么新插入的记录这些字段为空。
mysql> replace into test1(id,name)(select id,name from test2);
Query OK, 5 rows affected (0.04 sec)
Records: 4  Duplicates: 1  Warnings: 0
mysql> select * from test1;
+-----+------+------+
| id  | name | type |
+-----+------+------+
| 101 | xxx  | NULL |
| 102 | bbb  |    2 |
| 103 | ccc  |    3 |
| 201 | aaa  | NULL |
| 202 | bbb  | NULL |
| 203 | ccc  | NULL |
+-----+------+------+
6 rows in set (0.00 sec)
需要注意的是,当你replace的时候,如果被插入的表如果没有指定列,会用NULL表示,而不是这个表原来的内容。如果插入的内容列和被插入的表列一样,则不会出现NULL。例如
mysql> replace into test1(id,name,type)(select id,name,type from test2);
Query OK, 8 rows affected (0.04 sec)
Records: 4  Duplicates: 4  Warnings: 0
mysql> select * from test1;
+-----+------+------+
| id  | name | type |
+-----+------+------+
| 101 | xxx  |    5 |
| 102 | bbb  |    2 |
| 103 | ccc  |    3 |
| 201 | aaa  |    1 |
| 202 | bbb  |    2 |
| 203 | ccc  |    3 |
+-----+------+------+
6 rows in set (0.00 sec)
如果INSERT的时候,需要保留被插入表的列,只更新指定列,那么就可以使用第二种方法。
2、INSERT INTO ON DUPLICATE KEY UPDATE
发现重复的是更新操作。在原有记录基础上,更新指定字段内容,其它字段内容保留。例如我只想插入test2表的id,name字段,但是要保留test1表的type字段:
mysql> insert into test1(id,name,type)(select id,name,type from test2) on DUPLICATE KEY UPDATE test1.name=test2.name;
Query OK, 5 rows affected (0.04 sec)
Records: 4  Duplicates: 1  Warnings: 0
mysql> select * from test1;
+-----+------+------+
| id  | name | type |
+-----+------+------+
| 101 | xxx  |    1 |
| 102 | bbb  |    2 |
| 103 | ccc  |    3 |
| 203 | ccc  |    3 |
| 202 | bbb  |    2 |
| 201 | aaa  |    1 |
+-----+------+------+
6 rows in set (0.00 sec)
如果INSERT的时候,只想插入原表没有的数据,那么可以使用第三种方法。
3、IGNORE INTO
判断是否存在,存在不插入,否则插入。很容易理解,当插入的时候,违反唯一性约束,MySQL不会尝试去执行这条语句。例如:
mysql> insert ignore into test1(id,name,type)(select id,name,type from test2);
Query OK, 3 rows affected (0.01 sec)
Records: 4  Duplicates: 1  Warnings: 0
mysql> select * from test1;
+-----+------+------+
| id  | name | type |
+-----+------+------+
| 101 | aaa  |    1 |
| 102 | bbb  |    2 |
| 103 | ccc  |    3 |
| 203 | ccc  |    3 |
| 202 | bbb  |    2 |
| 201 | aaa  |    1 |
+-----+------+------+
6 rows in set (0.00 sec)


TAG:

2012年9月28日星期五

如何进行合理的网站改版 助力网站名次稳定上升

如何进行合理的网站改版 助力网站名次稳定上升

  很多站长朋友听到网站改版这个名次就感觉头疼,想改又担心网站被搜索引擎降权。其实对网站进行合理的改版不仅不会影响到网站的名次,恰恰还会让网站被搜索引擎重新认可,对网站给予新的权重,下面结合我自己的网站改版经验来谈谈如何进行合理的网站改版,助力网站名次不断上升。一个网站在改版前必须要满足几大要素,如果这几大要素不能够满足,那么就千万不要对网站进行改版。1是网站是否快照停滞不前,时间超过15天,2是网站是否文章收录不断下降,3是网站的名次长时间的不变化。如果你的网站出现了这三种情况之一,那么就可以对网站进行改版,否则不要轻举妄动。下面具体的谈谈网站如何合理改版。

  一、理清改版思路,确定改版方向

  站长你是想在什么地方对网站进行改版,这一点非常重要,是修改网站的标题还是网站的页面或者网站的内链,这些都需要理清思路。如果你的网站是快照有问题,那么修改网站的标题是最好的解决方法,如果你的网站是收录出现问题,那么对网站的内链进行改版是解决的好办法,如果你的网站是名次有问题,那么对网站进行综合修改是有必要的,根据网站的不同情况对网站进行不同的改版是站长必须确定的思维路线,否则一着不慎满盘皆输。

  二、找准改版方法,不要盲目改版

  标题:改变一个网站的现有状态不是一件容易的事情,假如你要修改一个网站的标题,那么就要遵循三大原则,1是标题修改字数亦减不亦增;2是标题修改亦少不亦多;3是标题修改不能脱离以前的标题中心,如果你做不到这一点,那么就不要去随便的动你的网站标题,否则悔之晚矣。

  内链:对网站内链进行修改是一件难事,相对标题而言,内链牵涉到了整个网站的收录情况,可以说修改失败就是一个网站的死期来临,因此对内链进行修改也必须遵循几大原则,如果你做不到,那么就不要去动你的网站内链,1是内链不能够随便跳级修改,比如以前是A/B/C,不能直接修改为A/C;2是内链的修改不能够修改已收录链接;3是内链的修改不能够删除链接太多,一般以5分支一为标准。

  页面:网站的页面与用户体验息息相关,很多网站因为页面的原因而未获得用户的重视,因此修改网站的页面也是一件必要的事情,但是页面改得好不好与代码有直接关系,从根本上来说修改页面就是修改网站代码,在修改页面的时候也必须遵循三个原则,1是必须遵循代码精简原则,删除复杂代码;2是代码统一性原则,不要弄几个不同类的代码出现;3是代码必须与网站的主题高度统一,很多站长在修改自己的网站页面时都会将网站的代码改得乱七八糟,这是大忌。

  三、改版之前,必须做的准备工作

  网站改版并不是几分钟、几十分钟就能够搞定的事情,因此在网站改版之前做好一系列的准备非常有必要。1是要做好网站的搜索引擎屏蔽抓取准备,这个时候最好将搜索引擎蜘蛛屏蔽了,不要让搜索引擎将你的错误行为也抓取到;2是准备好改版之后的10篇文章,这一点非常重要,如果想让自己的网站被搜索引擎重视,那么改版之后就立即更新大量的高质量原创文章,这样有助于网站不断发展。;3是找好引导蜘蛛的外链,这是保证网站改版之后第一时间被搜索引擎蜘蛛抓取的根本条件。

  网站改版并不是人人都能够成功的,如果站长在改版中不注重细节,那么改版的失败率又会增加,本篇文章对网站改版进行了全面的分析,我相信也是目前一些网站站长改版急需用到的资料,希望大家珍惜。文章来源店铺装修http://www.afpr.org ,A5首发,转载请保留地址!


TAG:如何 进行 网站 改版 助力 网站名 次稳 多站 长朋 友听 站长 网站 网站推广 赚钱

WinRT/Metro: 从StorageFile中显示图像

WinRT/Metro: 从StorageFile中显示图像

做一个小程序,进入程序后,选择一个文件夹,然后从StorageFolder中读取StorageFile,筛选图片文件,最后将图片显示在GridView中。

 

界面上很简单,一个准备弹出FolderPicker的按钮,还有一个GridView,GridView的Template直接绑定ItemsSource的图像:

<GridView Name="grid">

    <GridView.ItemTemplate>

        <DataTemplate>

            <Image Source="{Binding}" Stretch="Fill" Width="400" Height="200"/>

        </DataTemplate>

    </GridView.ItemTemplate>

</GridView>

 

执行逻辑就在按钮点击的事件代码中。首先注意需要要入如下额外的命名空间:

using Windows.Storage.Pickers;

using Windows.UI.Xaml.Media.Imaging;

using System.Threading.Tasks;

 

接着需要两个辅助方法,一个将StorageFile转换成ImageSource,另一个用来字符串比较(在判断图像扩展名时用到):

//将StorageFile转换成ImageSource

static async Task<ImageSource> ImageFromFile(StorageFile file)

{

    var bitmapImage = new BitmapImage();

    var stream = await file.OpenReadAsync();

    {

        bitmapImage.SetSource(stream);

        return bitmapImage;

    }

}

 

//用于判断扩展名

static bool CheckExtension(string str, params string[] exts)

{

    foreach (var ext in exts)

        if (str.Equals(ext, StringComparison.CurrentCultureIgnoreCase))

            return true;

    return false;

}

 

最后按钮Click执行代码:

private async void Button_Click_1(object sender, RoutedEventArgs e)

{

    //创建FolderPicker

    var folderpicker = new FolderPicker();

    folderpicker.FileTypeFilter.Add("*");

 

    //用户选择的文件夹

    var targetDir = await folderpicker.PickSingleFolderAsync();

 

    //筛选图像文件

    var imgFiles = (await targetDir.GetFilesAsync()).Where(f => CheckExtension(f.FileType, ".jpg", ".jpeg", ".png", ".gif", ".bmp"));

 

    //将StorageFile转换成ImageSource

    var imgs = imgFiles.Select(f => ImageFromFile(f).Result);

 

    //设置ItemsSource

    grid.ItemsSource = imgs;

}


TAG:

7种在页面优化技术 深SEO关键字和链接关系

7种在页面优化技术 深SEO关键字和链接关系

  很多站长都知道基本的搜索引擎的页面优化技术,但深SEO(搜索引擎优化)很少想过。大家都知道,你需要包含你的关键词在你的文章的标题,meta描述,标签,和在你的文章本身。但更精细的细节呢?

  建立联系与深层链接是一样重要的,因为从你的网页链接和任何指向您的网站的链接将有助于提高你的搜索引擎排名。如果你是认真对待你的SEO和链接建设策略,你必须确保一些来自深层链接的链接。

  1、管理者尝试欺骗搜索引擎,通过编写少量的内容,基本上页的其余部分留与不相关的内容。做的工作,并欺骗搜索引擎,但显然这已经不再是一个可行的方法在搜索引擎中的排名。这是因为谷歌已经开发了不同的方法来衡量实际页面提供已经承诺的事。开始的标题,描述和所有常见的位,但随后被详细到关键字的关系,如果确实属于在页面上。

  2、当开发一个网页,它通常是围绕主关键字。但内容只包含一个重复的关键字是不正确的方法来优化您的网页。这就是为什么你需要使用相关的关键字,确实有一个关系的主关键字。在下面的视频。兰德提到写了一篇关于猫的例子。他提到,字猫,喵喵,小猫,等相关的单词cat。但如果老虎是在那篇文章中的话,那么这个话题可能有不同的含义。毕竟是老虎是一只猫,但换句话说,如果在文章中,我们将假定一个不同的主题。因此,在你的文章中所包含的话是非常重要的,因为他们告诉人类和搜索引擎的文章是关??于什么的。当你提到不属于的话,它不仅是搜索引擎感到困惑。

  3、百度提到参考相关的潜在内容和网站管理员已经测试这一理论,证明它是正确的,你可以得到奖励。连接到宝贵的资源是没有害处的,它不仅有利于我们的主要目标,给他们想要的东西的人。请有关链接从东莞网站建设问题看到更多的细节。

  4、如果您visitiors很高兴与您的网页,停留更长的时间。超过其他人,他们也将选择内容。百度当然,你会高兴的速度非常快位访客提供相关的结果,但搜索引擎知道这一点。例如,如果人们看到你的网页,离开,回去继续他们的信息搜索,你的页面并没有让他们感到高兴。如果他们离开,并停止他们的搜索,然后他们迅速离开了,但你仍然让他们开心。

  5、是唯一的。你整个网站的内容,不要重复。新的网站管理员经常会看到的页面排名,并尝试建立类似的网页,居然说同样的事情。这将只能看到您正试图操纵搜索引擎的排名下降。

  6、我个人很喜欢写长的内容。长度取决于我确实需要回答什么,但我喜欢访问者走正确的答案,而不只是一半的答案。要做到这一点,最好的办法调查类似的网页,并提供超过他们提供什么。

  7、深SEO优化技术 - 问题的火花理念。一个伟大的方式去思考更深层次的搜索引擎优化技术是思考的人正在寻找如何为您的内容。把自己放在人类的鞋子,实际上是搜索的内容,看你怎么可以请他们。为了得到我的页面优化对的,我喜欢问自己一些问题,这将导致我认为有关的关键字,我应该如何使用它们。

  原创:出自http://www.cn578.com/a/News/Optimization/1354.html


TAG:页面优化 SEO关键字 链接关系 站长 网站 网站推广 赚钱

java 双向循环链表

java 双向循环链表

博客园第一篇正式文章,献上自己的原创代码,欢迎园友交流指教!

java 之 双向循环链表 新鲜出炉

  1 package com.xlst.util;  2   3 import java.util.HashMap;  4 import java.util.Map;  5 import java.util.UUID;  6   7 /**  8  * 双向循环链表  9  * 完成时间:2012.9.28 10  * 版本1.0 11  * @author xlst 12  * 13  */ 14 public class BothwayLoopLinked { 15     /** 16      * 存放链表长度的 map 17      *  18      * 如果简单使用 static int 型的 size 基本类型变量,则只能维护一个双向循环链表。 19      * 同时存在两个及以上双向循环链表时,数据会错乱 20      */ 21     private static final Map<String, Integer> sizeMap = new HashMap<String, Integer>(); 22     /** 23      * 双向链表的 id 24      * 一个双向一个唯一的 id 25      * 根据这个id可以从 sizeMap 中取出当前链表的长度 26      */ 27     private String linkedId = null; 28      29     /** 30      * 节点中的数据 31      */ 32     private Object data = null; 33      34     /** 35      * 前一个节点(初始化时是自身) 36      */ 37     private BothwayLoopLinked prev = this; 38     /** 39      * 后一个节点(初始化时是自身) 40      */ 41     private BothwayLoopLinked next = this; 42      43     public BothwayLoopLinked(){} 44      45     /** 46      * 在节点之后插入新节点 47      * @param newLinked 新插入的节点 48      */ 49     public void insertAfter(BothwayLoopLinked newLinked){ 50         //    原来的前节点与后节点 51         BothwayLoopLinked oldBefore = this; 52         BothwayLoopLinked oldAfter = this.next; 53          54         //    设置 newLinked 与原前节点的关系 55         oldBefore.next = newLinked; 56         newLinked.prev = oldBefore; 57          58         //    设置 newLinked 与原后节点的关系 59         oldAfter.prev = newLinked; 60         newLinked.next = oldAfter; 61          62         //    链表长度加一 63         changeSize(+1); 64         //    绑定新节点的 linkedId 65         newLinked.linkedId = this.linkedId; 66     } 67      68     /** 69      * 在节点之前插入新节点 70      * @param newLinked 新插入的节点 71      */ 72     public void insertBefore(BothwayLoopLinked newLinked){ 73         //    原来的前节点与后节点 74         BothwayLoopLinked oldBefore = this.prev; 75         BothwayLoopLinked oldAfter = this; 76          77         //    设置 newLinked 与原前节点的关系 78         oldBefore.next = newLinked; 79         newLinked.prev = oldBefore; 80          81         //    设置 newLinked 与原后节点的关系 82         oldAfter.prev = newLinked; 83         newLinked.next = oldAfter; 84          85         //    链表长度加一 86         changeSize(+1); 87         //    绑定新节点的 linkedId 88         newLinked.linkedId = this.linkedId; 89     } 90      91     /** 92      * 从链表结构中删除自身 93      * @return 被删除的节点 94      */ 95     public BothwayLoopLinked remove(){ 96         return remove(this); 97     } 98     /** 99      * 从链表结构中删除指定节点100      * @param linked 要删除的节点101      * @return 被删除的节点102      */103     public BothwayLoopLinked remove(BothwayLoopLinked linked){104         linked.prev.next = linked.next;105         linked.next.prev = linked.prev;106         107         linked.prev = linked;108         linked.next = linked;109         110         //    链表长度减一111         changeSize(-1);112         //    取消该节点的 linkedId113         this.linkedId = null;114         115         //    返回被删除的节点116         return linked;117     }118     119     /**120      * 改变链表长度(默认长度加1),私有方法121      */122     private void changeSize(){123         changeSize(1);124     }125     /**126      * 改变链表长度(根据参数),私有方法127      * @param value 改变的长度值(可以为负数)128      */129     private void changeSize(int value){130         if(this.linkedId == null){131             this.linkedId = UUID.randomUUID().toString();132             133             sizeMap.put(linkedId, 1 + value);    //    sizeMap.put(linkedId, 2);134         }else{135             Integer size = sizeMap.get(this.linkedId);136             //    Integer 是引用类型,更新值之后不必再 put 回 sizeMap 里137             size += value;138         }139     }140 141     public Object getData() {142         return data;143     }144 145     public void setData(Object data) {146         this.data = data;147     }148 149     /**150      * 获取链表的长度151      * 如果是新生的节点 或 从链表中删除的节点,则作为独立链表,长度是 1152      * @return 链表的长度153      */154     public int getSize() {155         return (linkedId == null) ? 1 : sizeMap.get(this.linkedId);156     }157 158     public BothwayLoopLinked getPrev() {159         return prev;160     }161 162     public BothwayLoopLinked getNext() {163         return next;164     }165 }

TAG:

作为搜索供应链的源头你产出了垃圾还是精品

作为搜索供应链的源头你产出了垃圾还是精品

  平时生活中听的最多的都是什么生产供应链、电商供应链,同样作为庞大的中文搜索领域也有自己的工业链,搜索引擎处于中间平台,供应链的末梢就是搜索用户,供应链的源头(网站)就是中国200的站长服务的网站。供应链源头到底产出的是垃圾还是精品直接影响整个供应链的健康性、成长性和能够产生多大的效益性。

  搜索供应链的源头(网站)产生是垃圾还是精品不是以站长的主管意识为前提的,他需要供应链的中间平台的把控,也可以说是搜索引擎的过滤,以及搜索引擎不断变化的算法而产生的对网站的质量判断度。还有就是搜索用户主管思维的短暂识别。哪么我们就从搜索供应链的源头的中间平台和搜索供应链的末梢来看看如何看待搜索供应链的源头(网站)产出的到底是垃圾还是精品。

  1、搜索供应链中间平台的把控

  不管是谷歌、百度、还是最近风生水起的搜索新贵360搜索,他的目的都是把控自己搜索领域数据库中搜索供应链的源头(网站)的质量好坏,而且这种盘对标准不是唯一和永久性的。昨天的质量好会随着时间的推移不断的变化,好的也会编程坏的标准。

  百度6月算法大更新可以说是一次网站质量判断标准的大换血,曾经的网站的收录越多、网站外链的数量众多、网站内容的数量、网站快照最新已不再是判断网站好的大部分因素。相反前三者可以说成了百度打击网站排名的最大的举证。百度接二连三的发布公告阐述所谓的网站好的标准,只有告诉中国200W的站长,搜索领域的网站好坏认知标准变天了,站长们应该与时俱进,紧跟百度的脚步。

  作为供应链的中间把控平台,搜索引擎有选择供应链源头的供应商(网站)的权利,这个就和京东、当当、苏宁等等电商平台一样择优录取。站长门给网站做优化就是要把自己网站的最好、最真实的一面展示了搜索引擎。网站和搜索引擎的关系从商业角度来说是一种伙伴关系,没有所谓搜索引擎一定要依附与某些网站才能生存。2012中国互联网大会最热门的词我想就是小马哥的微信告诉增长和周宏伟的用户体验,2者都是说互连网产品需要用户的高度认可,这个和我们做网站优化的初衷是重合的。网站优化不管我们采取什么正规的手法目的只有一个达到搜索供应链中间平台的认可。

  2、搜索供应链末梢短暂认知度

  为什么这个牛人小鱼要用短暂认知度呢?搜索用户借助搜索引擎的平台登陆一个网页,一般判断一个网页的好坏只有短短30秒,30秒网页的整体感、局部细节、与用户搜索内容的匹配度决定了30秒周是否还有一个接一个的30秒在这个网站上,这应该就是网站优化所谓的关键字研究的精准部署和页面内容的权威性、唯一性、用户帮助性。

  相信很多人都看过小马哥的产品设计7要素,网站的优化也是打造产品的一种过程,原创作为网站产品的一种最真实的表现形式,可以说网站优化的重点,其实牛人小鱼一直认为所谓搜索引擎喜欢原创,蜘蛛能够智能判别原创纯粹就是在忽悠大家,一个网站的内容只要真正贴近网站企业品牌、企业产品的精准性、真实性、甚至带有一点点的诱饵性的文章用户高认知度的好文章。易中天说过写文章主要看三点:感觉、文字、结构。这个三点做好这个篇文章不得了就是牛逼烘烘的好文章。网站如果能源源不断的产出符合自己网站核心内容的好文章、精彩文章何愁网站没有用的高驻留性、高流量、高转化呢?

  最后牛人小鱼要说的是网站优化作为搜索供应链的源的改造,需要每个SEOER做好自身定位,只做精品不做垃圾的制造者。网站优化的成功足以,何愁网站不兴,老板不笑,奖金多多。

  本文由牛人小鱼 http://blog.sina.com.cn/1976xiaoyu 发布,欢迎转载,转载请注明出处


TAG:搜索供应链 站长 网站 网站推广 赚钱

桥接模式结构型模式(2)

桥接模式结构型模式(2)

前言

 回顾上一篇对适配器模式的介绍,其主要用于对现有对象的接口的适配封装,使其符合复用环境的接口要求,同时相对于类适配器来说,在java语言层面更适合使用对象组合的方式来实现适配器模式(主要是因为java或者.net语言不支持多继承机制),降低系统的耦合度,增加代码的灵活性和可维护性。其实,Favor Composition Over Inheritance原则在多个结构型模式中都有很明显的体现,接下来我们将要讲述的桥接模式便是一例。从复杂度来说,桥接模式算是23种设计模式中较为难懂和抽象的一种模式,认识和理解其本质,对我们设计人员来说将是一个很好的提高途径,因为它涉及了很多的面向对象设计中的原则,比如“开闭原则”及“组合/聚合复用原则”等,掌握了这些核心的设计原则,势必会对我们形成正确的设计思路和培养良好的设计风格有所帮助。

动机

在日常的系统开发中,某些对象类型的业务逻辑的复杂性,其内部具有两个或者多个维度的变化。如何应对这种多维度的变化?如何通过面向对象的方式来封装隔离多个维度的变化,同时又不增加额外的类设计的复杂程度呢?桥接模式给我们提供了一个良好的解决之道,接下来就让我们来深入地学习理解这个神奇的设计模式吧!

意图

将抽象部分与它的实现相分离,使它们都可以独立地变化

《设计模式》一书将桥接模式的意图概括地太过于精炼和抽象,对我们初学者来说,并不太好理解。在这里,我们就多来认识一下相关概念。所谓桥接,通俗地说是就将将不同的东西搭一个桥,将两者连通起来,这样彼此就可以相互通讯和使用呢。而在桥接模式中,我们是通过将抽象部分与实现部分间进行“搭桥“,这样两者就可以相互通信,发送信息呢。不过,在桥接模式中,桥接是单向的,也就是说只有抽象部分会使用具体的实现部分对象,也就是调用其中相应的实现方法,反之不成立,实现部分是不会也不应该调用抽象部分中的相应方法的,所以这个桥接只是一个单向桥接。

之所以需要桥接,是为了让彼此独立变化的抽象部分和实现部分之间进行联通, 这样虽然从程序结构上分开呢,但是通过这个”桥“,抽象部分就可以顺畅地调用到实现部分的功能呢。实现桥接,在实现上很简单,不是让抽象部分拥有实现部分的接口对象,然后抽象部分需要的时候可以通过这个接口对象来调用具体相应的功能呢。

最后,根据桥接模式的意图,是为了实现抽象与实现可以独立变化,都可以相互扩充。两者是相当松散的关系,它们之间是完全独立和分开的,唯一关联就是抽象部分会保留一个对实现部分的对外接口对象在需要的时候方便调用其相应的功能罢呢。

需要注意的是,我们这里说的抽象部分与实现部分是两个变化维度的抽象接口,也就是说它们之间不是我们平常所说的抽象与实现的关系,它们都可以单独地去变化(拥有不同的实现),通过对象组合的方式来连接抽象部分和实现部分,这一点值得大家理解清楚哦。

结构图

image

  1. 抽象化(Abstraction)角色:抽象类的接口,并保存一个对实现化对象的引用。
  2. 修正抽象化(Refined Abstraction)角色:扩充了Abstraction定义的接口,加强或者修正了父类对抽象化的定义。
  3. 实现化(Implementor)角色:定义实现类的接口,该接口不一定要与Abstraction的接口一致,事实上这两个接口可以完全不同。一般来说,Implementor接口仅定义提供了底层的基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作,理解这点很关键哦!总结一点就是,抽象化与实现化角色之间并不存在继承与实现的关系,两者之间只是存在一种委托的关系而已。
  4. 具体实现化(ConcreteImplementor)角色:实现了所有实现化角色所定义的接口。

代码示例

 1:  public abstract class Implementor{
 2:      public abstract void OperationImp();
 3:  }
 4:   
 5:  public class ConcreteImplementorA extends Implementor{
 6:      public void OperationImp(){
 7:          //省略实现...
 8:      }
 9:  }
10:   
11:  public class ConcreteImplementorB extends Implementor{
12:      public void OperationImp(){
13:          //省略实现...
14:      }
15:  }
16:  public abstract class Abstraction{
17:      protected Implementor implementor;
18:      public abstract void Operation();
19:  }
20:   
21:  public class RefinedAbstraction extends Abstraction{
22:      public RefinedAbstraction(Implementor implementor){
23:          this.implementor=implementor;
24:      }
25:   
26:      public void Operation(){
27:          //...
28:          implementor.OperationImp();//调用实现化角色实现的操作
29:          //...
30:      }
31:  }
32:   
33:  public class Client{
 
34:      public static void main(String[] args){
35:          Abstraction abstraction=new RefinedAbstraction(new ConcreteImplementorA());
36:          abstraction.Operation();
37:      }
38:  }

从上述示例代码中,我们应该可以进一步理解上文中对抽象化与实现化两者间的关系。其实,两者就是组合/聚合的关系,抽象化需要保存对实现化角色的引用,因为抽象化的接口实现过程中需要调用实现化提供的相应底层操作接口。相对于示例代码来说,类Abstraction就是抽象化角色,而类Implementor就是实现化角色,两者定义的接口规范并不相同,也没必要相同,因为两者所定义的接口在实现层面上就不同,从逻辑上来说,抽象化角色定义的接口应该是更高层次的接口,而实现化角色定义的接口应该是较低层次的接口。其实,我们也可以这样理解,实现化就是我们开头所说的变化维度,现在我们通过对象组合的方式来隔离当前维度的变化,使代码更具灵活性和可扩展性。

现实场景

考虑这样一个场景——信息发送。首先信息本身就有不同的种类,比如有普通信息和加急信息(即需要特殊处理的信息,比如需要对方回执或者说在原信息内容的开头加上特定信息),但是对它们都有一个共同的接口,就是发送信息的操作,这是一个变化的维度;另外,在现实的世界中,发送信息的手段有多种,比如通过短信(SMS)或者邮件(Email)的方式,这也一个变化的维度。现在,我们有两个不同的变化维度,一个是信息种类,一个是信息发送手段,如果我们通过传统的继承方式,那么设计出来的UML图大概会是下面的样子:

image

虽然从上图来说,现在好像结构并不是很复杂,而且也很合理。但是大家有没想过,如果此时再添加一种信息种类的类,通过继承的方式来扩展的话,这个时候我们需要添加三个类,一个是新类型的信息类,另外两个是针对这种信息类型的两种不同发送手段即短信和邮件的方式。如果需求至此为止的话,这样的结构设计还是可以勉强应付的,但是不幸的是,需求是不断变化的,或许在将来的某个时间里,我们又需要添加一种全新的信息发送手段,比如说现在用的很火的微信方式,那么这个时候需要添加的新类的数目就会很多呢。大家应该可以想像出此时的类结构图会是什么样子,我是不想再画出那样”复杂“的类结构图来展示给大家看呢,也没必要,继承关系太多,难于维护,最致命的一点是这样的继承方式扩展性太差。其实这里不光是类数目的激增问题,更要命的是,这样的设计已经全然违反了面向对象设计的类的单一职责原则上呢,也就是一个类应该只有一个引进它变化的原因,而这里,我们发现Message类却存在两个变化点,一个是信息种类,一个是信息发送手段。这样的设计无疑是脆弱的,不合理的,接下我们通过桥接模式来重新设计以上场景,对比一下,两者的区别之处:

image

上图是使用桥接模式针对信息发送场景设计的类结构图,我们不再通过继承的方式来耦合多维度的变化,而是通过对象组合的方式来降低它们之间的耦合度,让信息种类与信息发送手段两个维度可以自由扩展,而将它们连接在一起的方法便是通过”桥“的方式,使信息种类可以通过信息发送手段对象来调用到相应的发送方法。通过桥接的方式,类的结构图变得十分地简洁、清晰,而且拥有良好的可扩展性:和上文描述的一样,不管此时增加新的信息种类还是增加新的信息发送手段,我们都无需对原有类进行修改,只需增加必须的新类即可,甚至都无需考虑新添加的类与原来类间的关系,我们只需要继承对应的父类即可,它们已经帮我们打理好了两个变化维度之间的连通方式。下面给出上述场景示意性的代码片段吧,与我们上文的示例代码结构上几乎完全一致!

 1:  public abstract class MessageImplementor{
 2:      public abstract void Send();
 3:  }
 4:   
 5:  public class MessageSMS extends MessageImplementor{
 6:      public void Send(){
 7:          //短信发送信息的具体实现...
 8:      }
 9:  }
10:   
11:  public class MessageEmail extends MessageImplementor{
12:      public void Send(){
13:          //邮件发送信息的具体实现...
14:      }
15:  }
16:  public abstract class Message{
17:      protected MessageImplementor implementor;
18:      public abstract void SendMessage();
19:  }
20:   
21:  public class CommonMessage extends Message{
22:      public CommonMessage(MessageImplementor implementor){
23:          this.implementor=implementor;
24:      }
25:   
26:      public void SendMessage(){
27:          //...
28:          implementor.Send();//调用具体的短信发送实现操作
29:          //...
30:      }
31:  }
32:   
33:  public class UrgencyMessage extends Message{
34:      public UrgencyMessage(MessageImplementor implementor){
35:          this.implementor=implementor;
36:      }
37:   
38:      public void SendMessage(){
39:          //...
40:          implementor.Send();//调用具体的短信发送实现操作
41:          //...
42:      }
43:  }
44:   
45:  public class Client{
46:      public static void main(String[] args){
47:          Message message=new CommonMessage(new MessageSMS());
48:          message.SendMessage();
49:      }
50:  }

通过示例代码,我们可以清楚地看到,将信息种类和信息发送手段联系起来的方式就是通过对象组合的方式来完成,在信息种类的父类中保存一个对信息发送手段接口的引用,以便在需要时调用其相应的实现。好呢,通过这个简单的场景相信大家也对桥接模式的应用有了较深刻的理解呢,对其举例就在此打住吧,大家可以充分联想各种适用于桥接模式的应用场景,深入思考,相信会对桥接模式的本质有一个更全面准确的理解。

实现要点

  1. 桥接模式使用”对象组合“的方式来解耦抽象与实现之间绑定关系,使得各自可以沿着各自的维度来扩展和变化。
  2. 抽象部分与实现部分沿着各自维度的变化指的就是实现它们对应的子类,也就是不同的实现,这样将两者结合的效果就可以得到多种种类(比如信息种类)的不同实现(信息发送手段)。
  3. 桥接模式之所以不使用多继承方式,是因为继承方案容易违背类的单一职责原则,复用性和可扩展性都不及对象组合方式。
  4. 桥接模式是为应对两个维度的各自变化扩展问题,如果这两个变化的维度(或者某个维度)的变化程度并不十分剧烈,使用多继承的方式也未尝不可。

运用效果

  1. 分离抽象和实现部分:桥接模式分离了抽象部分和实现部分,让抽象部分和实现部分独立开来,分别定义接口,有助于对系统进行分层,产生更好的结构化的系统。
  2. 良好的扩展性:桥接模式把抽象部分和实现部分分离开来,而且分别定义了接口,这样两者就可以分别独立扩展,并互不影响,极大地提高系统的扩展性。
  3. 可动态地切换实现:由于桥接模式把抽象部分和实现部分分离开来,这样在实现的过程中,我们就可以实现动态的选择和使用具体的实现部分呢。因为实现部分不是固定的绑定在一个抽象接口上,可以实现运行期间动态地切换不同实现部分。
  4. 大大减小了子类的数目:针对两个维度的变化情况,如果采用继承的方式,需要的两个维度上的可变化数量(即具体子类数目)的乘积数目;而采用桥接模式,需要的只是两个维度上的可变数量(即具体子类数目)的和个数。极大地减小子类的数目。

适用性

  1. 不希望在抽象和实现部分之间有一个固定的绑定关系时,也就是可以在运行时刻可以动态地切换实现部分的不同具体实现情况。
  2. 类的抽象和它的实现都应该可以通过生成子类的方法加以扩充。 也就说可以对不同的抽象接口与实现部分进行组合,并分别对它们时行扩充。
  3. 设计要求实现化角色的任何改变都不应当影响客户端,也就是实现化角色的改变对客户端是透明的。
  4. 组件有多于一个抽象化角色和实现化角色,系统需要它们之间动态解耦时。

相关模式

  1. 桥接模式与策略模式:两者之间的类结构图比较相似,可以将策略模式的Context当作是使用实现化接口的对象(即抽象化角色),这样Strategy就是某一个具体的实现化部分呢。从这点来说,使用桥接模式可以模拟实现策略模式的功能,但是是有一点需要注意的是,策略模式的Context不能扩展,而桥接模式的抽象化角色却可以自由扩展。再者就是两者的目的不一样,策略模式是封装一系列算法,使得这些算法可以相互替换; 而桥接模式的目的是分离抽象部分和实现部分,使得它们可以独立地变化。
  2. 桥接模式与状态模式:应该说两者的结构上来说,与状态模式与策略模式是一样的,两者的关系也基本上类似于桥接模式与策略模式的关系。不同的还是各自的目的,状态模式是封装不同状态下对应的行为,在内部状态改变的时候改变对象的行为。
  3. 桥接模式与抽象工厂模式:其实凡是需要创建对象的地方就需要创建型模式,而使用最多的创建型模式就是工厂方法模式和抽象工厂模式。在桥接模式的实现过程中,抽象化部分需要引用一个实现部分的具体实现对象,而这个实现对象的创建工作可以交由工厂方法或者抽象工厂模式来完成,甚至如果所需的实现化角色的种类不多,完全可以使用简单工厂方法来胜任。
  4. 桥接模式与适配器模式:适配器模式主要用于解决原本由于接口不兼容而不能一起工作的那些类,使得它们可以一起工作,而桥接模式重点在于分离抽象部分和实现部分,使它们彼此可以沿着各自的维度自由扩展、变化。在使用时间上,适配器模式一般用于系统设计实现之后,而桥接模式一般用于系统设计实现之时。

总结

桥接模式的本质是:分离抽象和实现。只有将两者分离,它们才能独立地变化,也只有两者可以相对独立地变化时,系统才会有更好的可扩展性和可维护性。桥接模式很好地遵循了开闭原则,也较好地体现了Favor Composition Over Inheritance(优先使用对象组合/聚合原则)。大家是否也已经体会到呢?原因上文已经介绍地很明白呢。客观地说,桥接模式比较难理解,虽然意图只是简单的一句话,但是里面包含的东西却很深刻,需要我们大家反复领悟思考,才会做到真正的融会贯通。对桥接模式的介绍就到此为止吧,接下来,我们将继续介绍下一种结构型设计模式——组合模式,敬请期待!

 

参考资料

  1. 程杰著《大话设计模式》一书
  2. 陈臣等著《研磨设计模式》一书
  3. GOF著《设计模式》一书
  4. Terrylee .Net设计模式系列文章
  5. 吕震宇老师 设计模式系列文章

TAG:

二三线城市招聘网站前景无限 选择系统是首要保障

二三线城市招聘网站前景无限 选择系统是首要保障

  依据艾瑞征询推出的《2011-2012年中国网络招聘职业展开陈述》统计分析,2009年中国网络招聘商场规模达16亿人民币,比较2010年的12.0亿人民币年增加11.2%。

  艾瑞征询以为,2009年中国网络招聘商场规模增加,主要有两个方面的缘由:一是金融危机影响削弱,中国微观经济形势向好股动网络招聘商场回暖;二是中国商场抢先的网络招聘企业改进产物效劳质量,展开多元化经营。艾瑞征询以为,中国网络招聘商场长时间展开趋势达观,缘由在于:一、中国具有宏大的求职部队和招聘企业,对求职和招聘效劳的商场需求宏大;二、网络招聘颠末十几年的展开,日益取得求职者和雇主的认可和承受。

  笔者以为,相对省级城市的网络招聘商场而言,二三线城市招聘网站更具有展开空间和远景,由于省级城市的人才招聘商场曾经趋于饱满,许多当地的二三级城市网络人才招聘竞赛相对较小,所以中小城市展开机会更多。

  依据查询,当前90%的当地招聘网站顺序都不是本人开发,是从网上下载的免费顺序,由于本人开发顺序本钱较高,何况运用起来并不完满的话还不如找一个现成的顺序来用,当前网上运用的顺序无论是安全性仍是安稳性都有存在着很大的危险,依据360、金山安全卫士歹意网页监控数据显现,仅2月23日一天,就有197家人才招聘网站被挂马,近6000个网页被黑客植入歹意代码,招聘网站除了做好网站安全防备外,选择安全功能高的网站顺序尤为重要。

  工作易人才招聘体系V2.5版别(官方下载地址:http://www.workyi.com)的推出补偿来了这一缺憾,该体系根据Win32平台,选用微软.Net(Aspx)+MSSQL 2000/05/08运转环境,大大提高了平台的安全和安稳性。在装置运用方面,具有装置简略,后台办理灵敏,全能收集体系等许多优势,而且该体系彻底开源,利于企业或小我二次开发,为用户打造高效、安全的企业级平台体系。

  当地性招聘网站只要为企业找到实实在在对企业展开有用的人才,使用招聘会场等线下手法为企业想尽办法选择人才,一起让求职者取得更多的就业机会,让网站用户看到的作用来说话,信任将来的路一定会越走越远。


TAG:三线 城市 招聘 网站 前景 无限 选择 系统 保障 艾瑞 站长 网站 网站推广 赚钱

总结让访客为你创造内容的六大理由

总结让访客为你创造内容的六大理由

  随着搜索引擎的不断升级,对于原创内容的识别度也在不断的提升。而原创内容对于草根站长来说也是最大的挑战,对于草根站长来说他们并没有足够的资源来创造更多的原创内容。在伪原创逐渐衰败的今天,如何为站点创造出更多的原创内容一直是站长所苦恼的问题之一。而随着web3.0时代的到来,让访客产生内容才是一个省力实效的方式。那么如何让访客为你的站点产生内容,今天笔者就简单的总结六个让访客为你创造内容的理由。

  理由一:获得外链

  这一点我们可以从几个大型的站长网看到。我们可以看到几个大型的站长网上投稿文章的人都会在自己的文章后面留一个链接。一来可以为我们的文章做一个版权的声明。二来可以为我们的站点获得一条不错的高权重外链。同时站长网的文章一般都会得到广泛的转载,能够很好的提升站点的外链。这无疑是站长网一个不错的运营模式,一方面我们可以通过文章分享交流自己的心得体验,获得不错的外链。另一方面作为站长网页可以获得访客为其创造的原创内容。可以说是一个双赢的局面。

  理由二:为了答疑解惑

  这一点我们可以从问答网上看到。比如百度知道、新浪爱问、搜搜问答等。这一些平台都是借助为用户答疑解惑而让用户创造内容的。对于我们的站点来说只要我们的站点上有相关专业的专业人士的话,访客就会主动到你的站点上进行问题的咨询。而访客在咨询的同时就会为我们的站点产生大量的原创内容。同时回答的过程中也是一种原创内容的创造途经。对此我们可以看到很多论坛都设有特别的问答互助板块,比如seowhy,这就是一个借助答疑解惑让用户创造内容的模式。

  理由三:为了个人线上品牌

  这一点我们可以从各大站长网的站长专栏上看到。例如我们可以看到在站长圈很多人都会在一些大型的站点上建立自己的专栏,比如donews专栏等等。然后通过这些专栏发表自己的文章,借助这些高人气的、专业的专栏平台来构建自己的线上品牌。只要你的文章有理有据,有能够引起共鸣的观点,呢么你的文章就会得到认同,慢慢的就会建立起自己的个人线上品牌。而通过这一些专栏也可以为我们的站点带来高质量的原创内容。

  理由四:为了营销

  软文投放可以说是目前最有效的线上营销手段之一。很多大型的企业都会有自己的文案,一篇好的软文所能带来的营销价值是巨大的。但是这一种软文需要发布到大型的专业的网站,有的发布平台甚至是需要收费的。

  理由五:为了礼品

  这点我们可以从很多电商平台看到。例如很多电商平台会经常推出产品试用的活动。借助商品的使用既可以推广自己的商品,同时通过这一手段也可以估计访客积极发言,发表自己的使用心得等等。我们也可以看到很多论坛为了鼓励用户发言也会推出有奖征文等活动。这一些活动都可以很好的促进用户为我们的站点创造内容的。

  理由六:个人兴趣爱好

  这个最明显的代表就是一些明星八卦论坛、电视剧电影论坛等等。因为这一些论坛都是一些志趣相投的人聚集的地方,很容易就可以引起访客自主的发表自己的看法。尤其是在一些有争议的话题上,往往能够创造出大量的原创内容。

  淡然促使用户为你创造内容的理由不仅仅是这六个方面。在很多方面上都是有迹可循的。希望本文能够帮助站长们更好的挖掘出让用户创造内容的方法。文章来自系统下载之家http://www.tt273.com/ 原创,转载请保留出处。


TAG:总结 访客 你创 造内 六大 随着 搜索 引擎 不断升 于原 站长 网站 网站推广 赚钱

动软.NET系统框架发布免费版本

动软.NET系统框架发布免费版本

动软.NET系统框架是一套基于可扩展组件式的软件系统项目,非常适合企业管理系统和互联网后台系统开发,代码基于面向对象的思想和多层架构设计,框架中提供了完善的权限角色管理功能,系统菜单管理,通用的功能模块,以及可扩展的系统机制,简洁的UI界面风格。

动软.NET系统框架拥有完善各种通用功能和各种模块,以便更好的服务于企业的开发需求,就像组装电脑的方式,组装开发出各种常用项目应用系统。企业无形中节省了大量的时间和人力成本,也让企业开发一个项目和系统变得如此轻松!

动软框架旨在实现,让企业以搭积木的方式实现各种通用功能,通过组装,开发出各种常用项目应用系统。为企业节省了大量的时间和重复开发的人力成本,让企业开发一个项目和系统变得如此轻松!

功能特点:

1. 全新的界面架构,JQuery UI+Ajax+ MVC3。

2. 完善的用户管理体系,控制用户的每个行为。

3. 权限角色管理

4. 灵活的系统配置,适应各种业务需求变化。

5. 网站运营管理

6. 完整的CMS内容发布系统,支持文章,照片,视频。

7. 强大的商品管理,支持自定义SKU规格和属性。

8. 可扩展的多层系统架构,保证未来的扩展和增容。

9. 各种增值功能组件:地图,短信,支付,邮件等等。


结合动软代码生成器,更是如吗虎添翼,个性化业务功能开发一键生成,瞬间完成项目不是梦!该免费版本暂不包括全部源码。

免费下载


TAG:

做SEO要学会步步为营 获得三大支撑是成功关键

做SEO要学会步步为营 获得三大支撑是成功关键

  从百度搜索引擎优化指南得知:SEO要想进入正常运行的轨迹,那么就需要为自己的行为买单,也就是说SEO要想合理、合规的运行,做白帽SEO,那么你就必须上车买票,而黑帽SEO行为也就是上车不买票,这种行为会经驾驶员同意吗?肯定不能,驾驶员发现你没有买票的时候肯定会请你下车,而百度也是如此,做黑帽优化并不要紧,但是你要记住黑帽优化有可能会被百度请下他的车。

  当我们一群付了钱的白帽优化者上车之后,这个时候也并不轻松,为什么:假如一辆客车的座位有20个,那么还能站着的人至少有50个,这就是说我们一群白帽SEO在上车之后也并不是人人都有座位,我们还需要竞争,这个时候的竞争就牵涉到多方面的因素了:1是自身素质、2是外力影响、3是驾驶员要求,如果你将这三点都做好了,那么我相信你就能够抢到一个优质的座位,你就是一名高质量的SEO。

  提高自身素质,才能在抢座位中技高一筹

  自身素质的提高才能够帮助自己在抢座位过程中占据优势地位,大家要知道假如你有1.8M,体重80KG,别人看到你都害怕,你还担心别人跟你抢座位,不可能的事情。因此我们在优化自己的网站过程中,就要不断的积累网站质量,坚持为网站更新高质量的内容,不断的为网站增加强有力的用户体验,提高用户感受,最后达到网站内部和谐,内部不断发展的状态。只有通过这种做法才能够在抢座位中技高一筹。

  利用外力影响,在抢座位中频繁去抢

  我们可以想象一下,在抢座位的时候假如旁边的人能够帮我们一把,我们是不是能够更加快捷方便的抢到一个好座位呢?因此我们在网站的建设过程中就要不断的借助外力去优化自己的网站,而外力最好的影响力构成方式就是我们的朋友,在抢座位的时候只有朋友才会帮助我们,因此友情链接就成为了影响我们抢座位的一大外力因素,不断的广交朋友、交真心朋友已经成为了我们网站优化的一条路线,而那些靠群发机、购买外链等等不是朋友的行为,总有一天会被出卖。

  让驾驶员认可,在抢座位中肯定能胜利

  驾驶员就是一个车主,他让你下车那么不管你怎么狡辩,你最后都只有下车一条出路,在车上的座位也是一样,他拥有绝对的控制权,因此我们如果能够在抢座位的时候被驾驶员认可,说不定驾驶员会将副驾驶的位置让给你做,那么你就是当之无愧的王者。因此我们在做网站优化的时候还不能够忘记了去拍一拍百度的马屁,争取尽可能的得到百度的认可与支持,百度旗下的产品我们能够利用的就要用,这就是我们拍马屁的好时候,我想任何事物都有影响的一刻,我还在我的网站上加入了一个百度的友情链接,我想这肯定能够得到百度的认可。

  为了让自己能够顺利的上车,那么就请掏腰包买票,为了让自己能够顺利的抢到座位,那么就请提高自身素质、不断借助外力、取得驾驶员的认可,我相信通过这样的方式肯定能够取得一个高质量的座位,也就是我们能够得到副驾驶座位,那么或许我们就得到了百度第一名。本文来源于深圳网站建设http://www.0755hsl.com,转载保留作者链接,谢谢。


TAG:SEO 学会步 获得 三大支 成功 关键 百度 搜索 引擎 站长 网站 网站推广 赚钱

网站seo数据分析的妙用

网站seo数据分析的妙用

  通过有效的数据分析,了解用户行为,来改进客户服务增加网站的粘性,更好的满足用户和访问者的需求。通过网站统计工具如百度统计,我要啦(51la统计),CNZZ数据专家,雅虎统计工具,谷歌统计软件,站长统计代码等。

  通过分析网站访问量的增长趋势图,来了解网站的近况。通过用户访问最高的时段、访问最多的网页、停留时间来做相应的网络推广。通过用户使用的搜索引擎,主要关键词、来路、入口、浏览深度、所用语言、时区、所用浏览器种类来把握用户的行为习惯,通过时段访问量统计分析、日段访问量统计分析以及周月访问量统计分析等判断网站行为方向。

  做好网站必要了解用户来源,用户喜好,用户行为,通过数据统计的分析来把握网站布局与导航,做好网站内容,吸引用户。

  通过数据统计对用户来源掌握的一清二楚。用户是怎样来到我们的网站,是通过其他网网站的链接,搜索引擎以及哪个搜索引擎。通过什么样的关键词,通过搜索什么来到我们的网站。用户经常使用那些关键词能找到我们的网站,了解我们的关键词是否合理有效,以此对关键词进行调整,那些关键词该去掉,那些关键词该强化,那些关键词改修改,对于提高关键词的精准度有很好的帮助。

  通过数据统计对用户行为更清楚明白。那些页面和内容能吸引用户,那些页面是用户经常访问,那些页面停留时间最长的,浏览的深度如何,那些入口使用户经常使用的。通过总结把此类页面的内容突出,把此类页面的优点用到成其他页面,来对网站达到更深入一步的优化。在推广的时候重点突出进行宣传和推广。

  通过数据分析对用户的习惯进行把握。用户是使用什么样的浏览器,使用什么样的搜索引擎,什么时间段访问,什么时段是高峰期,对用户的习惯行为进行总结,来针对浏览器,搜索引擎,进行网站的优化。通过日段访问统计,周月访问统计,网站访问量的增长趋势图来把握最近网站用户访问情况,进行网站内容的优化。

  无论是网站本身的优化还是搜索引擎的优化,数据分析都在优化的时候起到一定的助力作用,网站seo,少不了数据分析的应用。好好把握数据分析,根据数据统计来调整网站本身建设以及网站推广策略。因此网站seo 数据分析绝对不可少,利用好数据分析。本文来源于深圳网站建设http://www.0755hsl.com/,转载请保留作者链接,谢谢。


TAG:网站 seo 妙用 通过 解用户 改进 客户 服务 增加 站长 网站 网站推广 赚钱

mysql order by操作性能问题

mysql order by操作性能问题

在我的笔记本上,运行如下 sql代码(总共数据行约7万行,无索引)

select * from(
SELECT nodeinfo.nodeID nodeid,nodeinfo.niid niid ,nodeinfo.type type ,nodeinfo.testType testtype,sensordatapacket.storedtime storedtime,sensordatapacket.value value,
sensordatapacket.unit unit,sensordatapacket.dataType datatype,nodeconfig.nodeAddress nodename
FROM
nodeinfo
Left Join sensordatapacket ON nodeinfo.nodeID = sensordatapacket.nodeID
Left Join nodeconfig ON nodeconfig.nodeID = nodeinfo.nodeID
where  testtype='待测'  and type='土壤温度'  order by storedtime desc)  a
group by a.nodeid order by a.storedtime  desc

 

红字标注部分,使用order by storedtime desc时候 共用时9.284s

  使用order by storedtime asc时候,共用时17.04s

不使用order by操作的时候共用时2.022s。

 

目的时候对每个nodeid,检索出storedtime最近的一条数据。

若不使用order by 操作,检索出数据,storedtime时间为中间的一个某个时间。符合E.F.Codd博士在“a relation modal of data for large shared data banks”中提出的

数据库关系模型 的理论。数据库的物理存储并不一定是按照主键顺序存储,数据表中的数据本质上是在一个集合中。


TAG:

做网站优化并不是模仿与抄袭 制胜之道在于分析(上)

做网站优化并不是模仿与抄袭 制胜之道在于分析(上)

  中国的古老教育模式往往都是老师在讲台上讲课,学生在台下记笔记,说句实话这就是典型的模仿与抄袭,学生将老师脑袋中的知识汲取过来,又能够有多少创新呢?而在SEO这条道路上,一味的模仿与抄袭已经成为了网站优化的大忌,现在很多网站就是因为模仿抄袭而被搜索引擎降权,面对这种情况,我们总结出一个道理:网站优化的制胜之道还是分析。

  分析这个词语一直出现在站长的思维中,但是如何分析,怎么分析才算是好的分析成为了很多站长去分析的绊脚石,今天笔者要教会的就是不分站长学会去如何分析自己的网站发展方向,让站长兄弟能够在网站优化这条道路上获得好的收益,下面具体的谈一谈。

  分析网站的基础数据,特别是着重分析跳出率

  为什么站长第一点要分析跳出率呢?因为跳出率与网站的转化率息息相关,可以说跳出率的高与低直接与网站的收益成直接关系,一个网站的跳出率过高这表示用户对网站不友好,也可以说明这个网站的用户体验度不够高,这就是我们要分析的重中之重,假如你的网站也是这种情况,那么我们还必须从下面几个方法入手:

  1、分析用户来自于哪些搜索引擎,如果是百度搜索引擎,那么就进行第二步的分析,分析用户搜索的哪些关键词或者长尾词。

  2、找到用户搜索的关键词与长尾词之后,站长自己在百度搜索引擎上输入关键词,然后找到自己的网站点击进入。

  3、进入后直接将自己想象成搜索关键词的用户,然后分析自己的网站有符合用户需求的内容吗?

  4、如果连你都发现自己的网站内容构建太差,没有符合用户需求的内容,那么我这就是你网站跳出率过高的根本原因,而大数网站都是如此,网站有关键词,但是无内容,这让用户情何以堪,只有挥挥手走人,跳出率过高的问题也油然而起。

  分析网站的基础数据,还是看用户跳出率

  上面讲述了一个网站没有良好的用户内容网站的跳出率肯定会过高,而这一点内容将讲述网站即使有了符合用户需求的内容,跳出率还是会过高的问题,而这与网站的基础数据还是息息相关。大家都知道目前的电影网站、小说网站、文学等等类别的网站,大多数网站的谋生都是靠弹窗广告,而弹窗广告对用户的体验会造成极大的影响。

  实例1、用户A正在游览网页B,正看到关键时刻,一个游戏弹窗广告将用户A拉倒了游戏画面,用户A气晕了,直接关闭网站,并且发誓下次再也不来这个网站。

  实例2、用户B正在电影网站看电影,正看到两人决战的时刻,一个弹窗广告将用户B从激情中拉了出来,用户B立即关闭网站,再也不想进入这种网站了。

  这就是活生生的例子啊,笔者是一个喜欢阅读小说的人,我发现现在大多数小说网站的弹窗广告是层出不穷,对于我来说,只要我看到网站的弹窗广告,我第一时间就是换一家网站,真的很伤心。面对这种情况,如果你的网站跳出率过高,那么就必须要进行修改,这不仅仅是对网站名次有影响,更为重要的是对网站的用户吸引、老用户访问率有很大的影响,如果你不进行改正,那么就是对自己网站的一种失败行为。

  如果你还停留在模仿与抄袭别人的基础之上,我相信你看到这篇文章以后肯定有所感受,如果你还在模仿其他网站的弹窗广告,你还在靠流氓方法吸引流量,那么你就错误了,醒悟吧,互联网发展的未来就是用户为王,其余都是浮云,本文来自于汽车用品网http://www.che168.org 站长原创写作,这些都是我自己的实践心得,感觉非常有用特来分享。


TAG:做网站 优化 模仿 抄袭 制胜 之道 中国 古老 教育 模式 站长 网站 网站推广 赚钱

Javascript 扩展Date对象,实现字符串与Date按指定格式字符串互转

Javascript 扩展Date对象,实现字符串与Date按指定格式字符串互转

Date.format = function(d, mask){    var zeroize = function (value, length) {        if (!length) length = 2;        value = String(value);        for (var i = 0, zeros = ''; i < (length - value.length); i++) {            zeros += '0';        }        return zeros + value;    };    return mask.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])\1?|[lLZ])\b/g, function($0) {        switch($0) {            case 'd':   return d.getDate();            case 'dd':  return zeroize(d.getDate());            case 'ddd': return ['Sun','Mon','Tue','Wed','Thr','Fri','Sat'][d.getDay()];            case 'dddd':return ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][d.getDay()];            case 'M':   return d.getMonth() + 1;            case 'MM':  return zeroize(d.getMonth() + 1);            case 'MMM': return ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'][d.getMonth()];            case 'MMMM':return ['January','February','March','April','May','June','July','August','September','October','November','December'][d.getMonth()];            case 'yy':  return String(d.getFullYear()).substr(2);            case 'yyyy':return d.getFullYear();            case 'h':   return d.getHours() % 12 || 12;            case 'hh':  return zeroize(d.getHours() % 12 || 12);            case 'H':   return d.getHours();            case 'HH':  return zeroize(d.getHours());            case 'm':   return d.getMinutes();            case 'mm':  return zeroize(d.getMinutes());            case 's':   return d.getSeconds();            case 'ss':  return zeroize(d.getSeconds());            case 'l':   return zeroize(d.getMilliseconds(), 3);            case 'L':   var m = d.getMilliseconds();                    if (m > 99) m = Math.round(m / 10);                    return zeroize(m);            case 'tt':  return d.getHours() < 12 ? 'am' : 'pm';            case 'TT':  return d.getHours() < 12 ? 'AM' : 'PM';            case 'Z':   return d.toUTCString().match(/[A-Z]+$/);            // Return quoted strings with the surrounding quotes removed            default:    return $0.substr(1, $0.length - 2);        }    });};Date.prototype.format = function(mask) {    return Date.format(this, mask);};Date.parseFormat = function(str, format){    var pattern = format.replace(/(yyyy)/g, "([0-9]{4})")    .replace(/(yy)|(MM)|(dd)|(hh)|(mm)|(ss)/g, "([0-9]{2})")    .replace(/[Mdhms]/g, "([0-9]{1,2})");    var getIndex = function(expr1, expr2) {        var index = format.indexOf(expr1);        if (index == -1) index = format.indexOf(expr2);        return index;    }    var returnDate;    if (new RegExp(pattern).test(str)) {        var yPos = getIndex("yyyy", "yy");        var mPos = getIndex("MM", "M");        var dPos = getIndex("dd", "d");        var hPos = getIndex("hh", "h");        var miPos = getIndex("mm", "m");        var sPos = getIndex("ss", "s");        var data = {y: 0,m: 0,d: 0,h: 0,mi: 0,s: 0};        var pos = [yPos + ",y", mPos + ",m", dPos + ",d", hPos + ",h", miPos + ",mi", sPos + ",s"].sort(function(a, b) {            a = parseInt(a.split(',')[0]);            b = parseInt(b.split(',')[0]);            return a > b;        });        var tmpIndex = 0;        var newPos = [];        for (var i = 0, l = pos.length; i < l; i++) {            if (parseInt(pos[i].split(',')[0]) != -1) {                newPos[tmpIndex] = pos[i];                tmpIndex++;            }        }        var m = str.match(pattern);        for (var i = 1, l = m.length; i < l; i++) {            if (i == 0) break;            var flag = newPos[i - 1].split(',')[1];            data[flag] = m[i];        };        data.y = data.y || today.getFullYear();        data.d = data.d || today.getDate();        if (data.y.toString().length == 2) data.y = parseInt('20' + data.y);        data.m -= 1;        returnDate = new Date(data.y, data.m, data.d, data.h, data.mi, data.s);    }    return returnDate;};var time1 = new Date("2012/01/01 00:00:00 UTC+800");var str1 = time1.format("yyyy年MM月dd日 H时mm分ss秒 TT")console.log("Date["+time1+"]");console.log("格式化结果为:" + str1);var str2 = "2012年1月23日";var time2 = Date.parseFormat(str2, "yyyy年M月dd日");console.log("时间字符串:"+str2);console.log("格式化结果: Date["+time2+"]");

TAG:

jQuery 时间获取扩展

jQuery 时间获取扩展

本段代码实现了同步和异步获取服务器时间的放式,真正做到不会侵入服务器代码。主要原理是读取响应头部的Date值,即为服务器返回响应的时间(由服务器端生成),故可以以字符串格式取出,并可以转换为Date对象,以便后续操作。

对于获取服务器时间提供了同步和异步两种放式调用,可根据实际需要选择

jQuery.extend({    //获取系统时间    getSystemTime: function(){        return new Date();    },    //异步获取服务器时间    getServerTime_async: function(success){        $.ajax({            data: {_:Math.random()},            complete: function(xhr){                var str = xhr.getResponseHeader("Date");                var now = null;                if(str != null)                    now = new Date(str);                if($.isFunction(success))                    success(now);            }        });    },    //同步获取服务器时间    getServerTime: function(){        var xhr = $.ajax({            async: false,            data: {_:Math.random()}        });        var str = xhr.getResponseHeader("Date");        if(str == null)            return null;        return new Date(str);    }});//DEMO:console.log("$.getSystemTime()      Result: " + $.getSystemTime());console.log("$.getServerTime()      Result: " + $.getServerTime());$.getServerTime_async(function(t){    console.log("$.getServerTime_async()Result: " + t);});

TAG:

2012年9月27日星期四

C#中将MDI窗口嵌入普通窗口

C#中将MDI窗口嵌入普通窗口

有一种需求叫做变态,这有个例子:客户的系统使用了一个框架库,就是依据配置动态添加控件到一个主窗口的那种,即将被嵌入的程序却是一个MDI主窗口,同事电话寻求帮助.咋办?变态!于是想到以前在VC6时代,将自己的窗口嵌入MSDN帮助的经历,使用API试试,于是花了几分钟写了个测试,用手机拍照发彩信过去,同事努力一把,算是解决的.有意思的是,提供框架的一方,之前也在努力协助此次嵌入工作而无果,看见我们的代码也大为感慨.是不是有点无理,别忘了,没有C#时,我们什么都是这样干的.


TAG:

WinRT参考资料

WinRT参考资料

WinRT是为消费市场准备的,和传统的桌面、企业应用差别巨大。

When designing apps for Windows 8, you must keep this in mind as well. You will build apps for consumers when using WinRT. otherwise, you are most likely building software for providers or enterprise users. Metro style development is not aimed at those scenarios. WinRT exposes only the services needed for a great consumer experience.

系统结构图

clip_image002

参考资料

Ø Channel 9 on MSDN

Channel 9 has many resources for developers concerning WinRT. Visit the main site at http://channel9.msdn.com and search for “windows runtime” for a list.

Ø Recommended Videos from Channel 9

Using the Windows Runtime from C# and Visual Basic

http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-531T

Lap around the Windows Runtime

http://channel9.msdn.com/Events/BUILD/BUILD2011/PLAT-874T

Ø 2011 Build Conference Web Site

The 2011 Build conference is a little dated, but the information found on its site— http://www.buildwindows.com —is still helpful regarding WinRT.

Ø Windows Dev Center

One of the primary resources is the Windows Dev Center (http://dev.windows.com ). This is the starting place for Microsoft’s documentation regarding Windows 8 development and WinRT. Here are a few links to start with, but the Windows Dev Center is a vast collection of information. It will serve as a point of reference you will return to time and again.

Learn to build Metro style apps

http://msdn.microsoft.com/library/windows/apps

API reference for Metro style apps

http://msdn.microsoft.com/en-us/library/windows/apps/br211369.aspx

API reference for Windows Runtime and Windows Library for JavaScript

http://msdn.microsoft.com/en-us/library/windows/apps/br211377.aspx

Metro style app fundamentals

http://msdn.microsoft.com/en-us/library/windows/apps/hh750302.aspx

App capability declarations

http://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx

App contracts and extensions

http://msdn.microsoft.com/en-us/library/windows/apps/hh464906.aspx

Ø Miguel de Icaza wrote a nice article regarding WinRT.

“WinRT Demystified” http://tirania.org/blog/archive/2011/Sep-15.html

Ø CodePlex WinRT

http://winrt.codeplex.com

Ø Doug Steven discusses the Windows Runtime architecture diagram and what is missing.“A Bad Pi c ture I s Wor th a Thousand Long Di s cus s ions”

http://dougseven.com/2011/09/15/a-bad-picture-is-worth-a-thousand-long-discussions

Ø “The Windows Runtime”

http://devhawk.net/2011/09/15/the-windows-runtime


TAG:

学习Nop中Routes的使用

学习Nop中Routes的使用

1. 映射路由

大型MVC项目为了扩展性,可维护性不能向一般项目在Global中RegisterRoutes的方法里面映射路由。这里学习一下Nop是如何做的。

 

Global.cs  . 通过IOC容器取得IRoutePublisher实例

public static void RegisterRoutes(RouteCollection routes)        {            routes.IgnoreRoute("favicon.ico");            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                        //register custom routes (plugins, etc)            var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();            routePublisher.RegisterRoutes(routes);                        routes.MapRoute(                "Default", // Route name                "{controller}/{action}/{id}", // URL with parameters                new { controller = "Home", action = "Index", id = UrlParameter.Optional },                new[] { "Nop.Web.Controllers" }            );        }

 

IRoutePublisher.cs 只有一个方法

public interface IRoutePublisher    {        void RegisterRoutes(RouteCollection routeCollection);    }

 

实现类

public class RoutePublisher : IRoutePublisher    {        private readonly ITypeFinder _typeFinder;        public RoutePublisher(ITypeFinder typeFinder)        {            this._typeFinder = typeFinder;        }        public void RegisterRoutes(RouteCollection routes)        {            var routeProviderTypes = _typeFinder.FindClassesOfType<IRouteProvider>();            var routeProviders = new List<IRouteProvider>();            foreach (var providerType in routeProviderTypes)            {                var provider = Activator.CreateInstance(providerType) as IRouteProvider;                routeProviders.Add(provider);            }            routeProviders = routeProviders.OrderByDescending(rp => rp.Priority).ToList();            routeProviders.ForEach(rp => rp.RegisterRoutes(routes));        }    }

 

ITypeFinder之前已经介绍过。点击查看 ,搜索项目中所有的IRouteProvider实现。然后根据优先级排序,最后调用RegisterRoutes依次映射

 

image

 

竟然有这么多,大多都在Plugin程序集中为插件映射路由。随便打开一个。

public partial class RouteProvider : IRouteProvider    {        public void RegisterRoutes(RouteCollection routes)        {            routes.MapRoute("Plugin.Payments.AuthorizeNet.Configure",                 "Plugins/PaymentAuthorizeNet/Configure",                 new { controller = "PaymentAuthorizeNet", action = "Configure" },                 new[] { "Nop.Plugin.Payments.AuthorizeNet.Controllers" }            );            routes.MapRoute("Plugin.Payments.AuthorizeNet.PaymentInfo",                 "Plugins/PaymentAuthorizeNet/PaymentInfo",                 new { controller = "PaymentAuthorizeNet", action = "PaymentInfo" },                 new[] { "Nop.Plugin.Payments.AuthorizeNet.Controllers" }            );        }        public int Priority        {            get            {                return 0;            }        }    }

 

好处不用说了。模块化方便复用。

 

2.自定义Route

LocalizedRoute.cs

using System.Web;using System.Web.Routing;using Nop.Core.Data;using Nop.Core.Domain.Localization;using Nop.Core.Infrastructure;namespace Nop.Web.Framework.Localization{    /// <summary>    /// Provides properties and methods for defining a localized route, and for getting information about the localized route.    /// </summary>    public class LocalizedRoute : Route    {        #region Fields        private bool? _seoFriendlyUrlsForLanguagesEnabled;        #endregion        #region Constructors        /// <summary>        /// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern and handler class.        /// </summary>        /// <param name="url">The URL pattern for the route.</param>        /// <param name="routeHandler">The object that processes requests for the route.</param>        public LocalizedRoute(string url, IRouteHandler routeHandler)            : base(url, routeHandler)        {        }        /// <summary>        /// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern, handler class and default parameter values.        /// </summary>        /// <param name="url">The URL pattern for the route.</param>        /// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>        /// <param name="routeHandler">The object that processes requests for the route.</param>        public LocalizedRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)            : base(url, defaults, routeHandler)        {        }        /// <summary>        /// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern, handler class, default parameter values and constraints.        /// </summary>        /// <param name="url">The URL pattern for the route.</param>        /// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>        /// <param name="constraints">A regular expression that specifies valid values for a URL parameter.</param>        /// <param name="routeHandler">The object that processes requests for the route.</param>        public LocalizedRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)            : base(url, defaults, constraints, routeHandler)        {        }        /// <summary>        /// Initializes a new instance of the System.Web.Routing.Route class, using the specified URL pattern, handler class, default parameter values,         /// constraints,and custom values.        /// </summary>        /// <param name="url">The URL pattern for the route.</param>        /// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>        /// <param name="constraints">A regular expression that specifies valid values for a URL parameter.</param>        /// <param name="dataTokens">Custom values that are passed to the route handler, but which are not used to determine whether the route matches a specific URL pattern. The route handler might need these values to process the request.</param>        /// <param name="routeHandler">The object that processes requests for the route.</param>        public LocalizedRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)            : base(url, defaults, constraints, dataTokens, routeHandler)        {        }        #endregion        #region Methods        /// <summary>        /// Returns information about the requested route.        /// </summary>        /// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>        /// <returns>        /// An object that contains the values from the route definition.        /// </returns>        public override RouteData GetRouteData(HttpContextBase httpContext)        {            if (DataSettingsHelper.DatabaseIsInstalled() && this.SeoFriendlyUrlsForLanguagesEnabled)            {                string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath;                string applicationPath = httpContext.Request.ApplicationPath;                if (virtualPath.IsLocalizedUrl(applicationPath, false))                {                    //In ASP.NET Development Server, an URL like "http://localhost/Blog.aspx/Categories/BabyFrog" will return                     //"~/Blog.aspx/Categories/BabyFrog" as AppRelativeCurrentExecutionFilePath.                    //However, in II6, the AppRelativeCurrentExecutionFilePath is "~/Blog.aspx"                    //It seems that IIS6 think we're process Blog.aspx page.                    //So, I'll use RawUrl to re-create an AppRelativeCurrentExecutionFilePath like ASP.NET Development Server.                    //Question: should we do path rewriting right here?                    string rawUrl = httpContext.Request.RawUrl;                    var newVirtualPath = rawUrl.RemoveLocalizedPathFromRawUrl(applicationPath);                    if (string.IsNullOrEmpty(newVirtualPath))                        newVirtualPath = "/";                    newVirtualPath = newVirtualPath.RemoveApplicationPathFromRawUrl(applicationPath);                    newVirtualPath = "~" + newVirtualPath;                    httpContext.RewritePath(newVirtualPath, true);                }            }            RouteData data = base.GetRouteData(httpContext);            return data;        }        /// <summary>        /// Returns information about the URL that is associated with the route.        /// </summary>        /// <param name="requestContext">An object that encapsulates information about the requested route.</param>        /// <param name="values">An object that contains the parameters for a route.</param>        /// <returns>        /// An object that contains information about the URL that is associated with the route.        /// </returns>        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)        {            VirtualPathData data = base.GetVirtualPath(requestContext, values);                        if (DataSettingsHelper.DatabaseIsInstalled() && this.SeoFriendlyUrlsForLanguagesEnabled)            {                if (data != null)                {                    string rawUrl = requestContext.HttpContext.Request.RawUrl;                    string applicationPath = requestContext.HttpContext.Request.ApplicationPath;                    if (rawUrl.IsLocalizedUrl(applicationPath, true))                    {                        data.VirtualPath = string.Concat(rawUrl.GetLanguageSeoCodeFromUrl(applicationPath, true), "/",                                                         data.VirtualPath);                    }                }            }            return data;        }        public virtual void ClearSeoFriendlyUrlsCachedValue()        {            _seoFriendlyUrlsForLanguagesEnabled = null;        }        #endregion        #region Properties        protected bool SeoFriendlyUrlsForLanguagesEnabled        {            get            {                if (!_seoFriendlyUrlsForLanguagesEnabled.HasValue)                    _seoFriendlyUrlsForLanguagesEnabled = EngineContext.Current.Resolve<LocalizationSettings>().SeoFriendlyUrlsForLanguagesEnabled;                return _seoFriendlyUrlsForLanguagesEnabled.Value;            }        }        #endregion    }}

继承Route并且实现GetRouteData, GetVirtualPath这2个方法。从返回的参数可以知道一个是解析URL,一个是生成URL。是一个双向的过程。

注意 if (DataSettingsHelper.DatabaseIsInstalled() && this.SeoFriendlyUrlsForLanguagesEnabled)  这个判断条件,启用了地区化友好SEO。才进行URL转换。

简单说就是 http://localhost:2619/en  《=》http://localhost:2619/  的双向转换。 en,ch之类的就是网站设置的语言了。

 

 

2。MVC路由测试

先看单元测试

 

映射路由

new Nop.Web.Infrastructure.RouteProvider().RegisterRoutes(RouteTable.Routes);

 

[Test]        public void Boards_routes()        {            "~/boards/".ShouldMapTo<BoardsController>(c => c.Index());            //TODO add support for optional parameters in 'ShouldMapTo' method (such as in ~/boards/activediscussions/ or ~/boards/topic/11/). The same is about issue is in the other route test methods            //"~/boards/activediscussions/".ShouldMapTo<BoardsController>(c => c.ActiveDiscussions(0));            //"~/boards/activediscussionsrss/".ShouldMapTo<BoardsController>(c => c.ActiveDiscussionsRss(0));            "~/boards/postedit/1".ShouldMapTo<BoardsController>(c => c.PostEdit(1));            "~/boards/postdelete/2".ShouldMapTo<BoardsController>(c => c.PostDelete(2));            "~/boards/postcreate/3".ShouldMapTo<BoardsController>(c => c.PostCreate(3, null));            "~/boards/postcreate/4/5".ShouldMapTo<BoardsController>(c => c.PostCreate(4, 5));            "~/boards/topicedit/6".ShouldMapTo<BoardsController>(c => c.TopicEdit(6));            "~/boards/topicdelete/7".ShouldMapTo<BoardsController>(c => c.TopicDelete(7));            "~/boards/topiccreate/8".ShouldMapTo<BoardsController>(c => c.TopicCreate(8));            "~/boards/topicmove/9".ShouldMapTo<BoardsController>(c => c.TopicMove(9));            "~/boards/topicwatch/10".ShouldMapTo<BoardsController>(c => c.TopicWatch(10));            //"~/boards/topic/11/".ShouldMapTo<BoardsController>(c => c.Topic(11, 1));            //"~/boards/topic/11/test-topic-slug".ShouldMapTo<BoardsController>(c => c.Topic(11, 1));            "~/boards/topic/11/test-topic-slug/page/2".ShouldMapTo<BoardsController>(c => c.Topic(11, 2));            "~/boards/forumwatch/12".ShouldMapTo<BoardsController>(c => c.ForumWatch(12));            "~/boards/forumrss/13".ShouldMapTo<BoardsController>(c => c.ForumRss(13));            //"~/boards/forum/14/".ShouldMapTo<BoardsController>(c => c.Forum(14, 1));            //"~/boards/forum/14/test-forum-slug".ShouldMapTo<BoardsController>(c => c.Forum(14, 1));            "~/boards/forum/14/test-forum-slug/page/2".ShouldMapTo<BoardsController>(c => c.Forum(14, 2));            "~/boards/forumgroup/15/".ShouldMapTo<BoardsController>(c => c.ForumGroup(15));            "~/boards/forumgroup/15/test-forumgroup-slug/".ShouldMapTo<BoardsController>(c => c.ForumGroup(15));            //"~/boards/search/".ShouldMapTo<BoardsController>(c => c.Search(null, null, null, null, null, 1));        }

看来这里的代码。膜拜作者吧。。之前一直不知道如何测试Route,最多是装个Routedebug什么的

 

接下来进行解析匹配

/// <summary>        /// Asserts that the route matches the expression specified.  Checks controller, action, and any method arguments        /// into the action as route values.        /// </summary>        /// <typeparam name="TController">The controller.</typeparam>        /// <param name="routeData">The routeData to check</param>        /// <param name="action">The action to call on TController.</param>        public static RouteData ShouldMapTo<TController>(this RouteData routeData, Expression<Func<TController, ActionResult>> action)            where TController : Controller        {            routeData.ShouldNotBeNull("The URL did not match any route");            //check controller            routeData.ShouldMapTo<TController>();            //check action            var methodCall = (MethodCallExpression)action.Body;            string actualAction = routeData.Values.GetValue("action").ToString();            string expectedAction = methodCall.Method.ActionName();            actualAction.AssertSameStringAs(expectedAction);            //check parameters            for (int i = 0; i < methodCall.Arguments.Count; i++)            {                ParameterInfo param = methodCall.Method.GetParameters()[i];                bool isReferenceType = !param.ParameterType.IsValueType;                bool isNullable = isReferenceType ||                    (param.ParameterType.UnderlyingSystemType.IsGenericType && param.ParameterType.UnderlyingSystemType.GetGenericTypeDefinition() == typeof(Nullable<>));                string controllerParameterName = param.Name;                bool routeDataContainsValueForParameterName = routeData.Values.ContainsKey(controllerParameterName);                object actualValue = routeData.Values.GetValue(controllerParameterName);                object expectedValue = null;                Expression expressionToEvaluate = methodCall.Arguments[i];                // If the parameter is nullable and the expression is a Convert UnaryExpression,                 // we actually want to test against the value of the expression's operand.                if (expressionToEvaluate.NodeType == ExpressionType.Convert                    && expressionToEvaluate is UnaryExpression)                {                    expressionToEvaluate = ((UnaryExpression)expressionToEvaluate).Operand;                }                switch (expressionToEvaluate.NodeType)                {                    case ExpressionType.Constant:                        expectedValue = ((ConstantExpression)expressionToEvaluate).Value;                        break;                    case ExpressionType.New:                    case ExpressionType.MemberAccess:                        expectedValue = Expression.Lambda(expressionToEvaluate).Compile().DynamicInvoke();                        break;                }                if (isNullable && (string)actualValue == String.Empty && expectedValue == null)                {                    // The parameter is nullable so an expected value of '' is equivalent to null;                    continue;                }                // HACK: this is only sufficient while System.Web.Mvc.UrlParameter has only a single value.                if (actualValue == UrlParameter.Optional ||                    (actualValue != null && actualValue.ToString().Equals("System.Web.Mvc.UrlParameter")))                {                    actualValue = null;                }                if (expectedValue is DateTime)                {                    actualValue = Convert.ToDateTime(actualValue);                }                else                {                    expectedValue = (expectedValue == null ? expectedValue : expectedValue.ToString());                }                string errorMsgFmt = "Value for parameter '{0}' did not match: expected '{1}' but was '{2}'";                if (routeDataContainsValueForParameterName)                {                    errorMsgFmt += ".";                }                else                {                    errorMsgFmt += "; no value found in the route context action parameter named '{0}' - does your matching route contain a token called '{0}'?";                }                actualValue.ShouldEqual(expectedValue, String.Format(errorMsgFmt, controllerParameterName, expectedValue, actualValue));            }            return routeData;        }

 

这里又看到了表达式树强大的地方。关于表达式树具体使用请搜索博客园,  这里通过routeData和解析action来判断请求和action是否一致。

 

总结:通过学习Nop中路由的一些使用。掌握了一些很有用的Route的使用。这些模块今后也能根据需要加入到自己的网站中。

 

参考:

两篇关于自定义路由:http://www.cnblogs.com/john-connor/archive/2012/05/03/2478821.html 

http://www.cnblogs.com/ldp615/archive/2011/12/05/asp-net-mvc-elegant-route.html


TAG: