JAVA EE 学习笔记(二)

碎语:

好久没有写文章,除了临近期末,要准备考试之外,还有个原因则是生活上遇到一些问题。大三了,马上就大四了,由于参加了个软件的培训,这个暑假估计都没法出去实习了,现在有些矛盾,感觉培训这边的话进度有点慢,还没自己学得快,但是有个学习环境还是很好的,到时候集中训练的时候再看看效果吧。人生总是充满了这种矛盾,就像女朋友并不赞成我留着现在这个城市一样,她希望我可以回到那个小城市,安安稳稳地过日子,但是她是一个喜欢享受的人,没有一个良好的经济基础,怎么过上安逸的生活。我的想法很简单,男子汉大丈夫,事业未立,何以家为。如果以后要我去做些和IT无关或者卖卖电脑打打杂的这种工作,我还不如死了算了。从小到大我字写得都很差,但是我从来不在意这点,也没刻意去做改变,因为我知道我以后的工作,只要有个电脑就好了,打字速度快点就差不多了,想法很简单,但这就是我的路,我希望能走这个路,未来如何,我都无所畏惧。

言归正传,对这个阶段的学习做下整理吧。

笔记:

这个阶段主要是学习了下javascript,复习了下css。

页面布局:

之前CSS其实也有学过,不过对于布局一直不是很清楚,东西可以做出来,但是花的时间特别多。经过这次的学习感觉用起来顺手很多了,扒了个新浪微博的界面

我扒的新浪微博界面

感觉布局中有几点很是重要:

1.margin是外边距,不计算到元素自身大小里面

2.padding是内边距,使用padding的时候,面积会变大

3.display: 这个比较重要,通过更改display的属性可以更改元素默认的display属性,不居中很有用,比如你可以将一个p改为inline,这样两个段落之间不会换行了。

4.position属性很重要,

static是默认值,这个出现在它应该在的地方

relative是相对定位,使用这个可以对元素进行偏移,但是元素会占用它本应该占用的空间

absolute绝对定位,当使用绝对定位的时候,它将不占用空间(层叠了),但是当它的父元素为relative的时候,它绝对定位的基础是父元素的位置

fixed定位,可以理解为将元素设成父元素为当前窗口的absolute定位(在特定位置停留不动)。

关于这个有个文章有详细介绍,有兴趣可以看看: CSS定位属性Position详解

5.display none 和 visibility hidden 之间的区别

这两个配合js动态调用和position可以做些漂亮的弹出菜单,或者是一些动态效果。它们之间的区别在于:display:none这个设置之后,元素不再占用空间。visibility:hidden设置后,会占用原来的空间

这个在w3schools上面有个示例很形象可以看看:CSS Display and Visibility http://www.w3schools.com/css/css_display_visibility.asp

6.浮动float 这个可以说是重中之重了,布局神器。

使用float可以让元素浮动起来,完成平常常见的2栏或者3栏布局,或者是生成一个漂亮的横向菜单。

使用这个属性后有一件事情很重要,得清除浮动。

就现在总结了下,清除浮动的方法:

1.父元素下面加个div块设置clear:both;
2.父元素添加overflow:hidden 这个比较费解,但是它的确可以起到清除浮动的作用,可以让内部的元素撑开父元素。
3.还有个方法是新浪微博用的方法。给父元素添加一个.clearfix样式。
这个其实和1方法原理是相同的。

.clearfix::after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}

7.CSS sprite,这个可以讲多张背景图片拼接到一起,使用同一个background-image ,然后通过background-position进行移位

如果向上移动10px ,左移动20px 应该这么设置:background-position:-10px 20px;

这个实例比较好理解,这里推荐一篇老外写的文章,很详细,介绍了为什么要使用css sprite,如何使用css sprite,英文要是不好的话,可以直接跳到后面看关键的内容http://css-tricks.com/css-sprites/

JAVA EE 学习笔记(一)

碎语:

学JAVA好几个月了,断断续续的,怕贪多嚼不烂一直都不敢学得太快,还是从基础开始学起。

先是大致看了下教程,然后再找了本《JAVA疯狂讲义》来进行学习,这本书讲得很细,这是个优点,也是它的缺点了,大部分还是完整看下来了,跳过后面一些章节,例如讲界面部分的内容可以大致看看,等到以后如果有需要的话去查询也是可以的。

近期正式进入web部分,这部分感觉和之前学过的php差不多,有许多概念都是重复的http响应头,之类内容算是有了一个较好的整合。

找的 韩顺平.2011最新j2ee视频教程 学习,基本一天学好几天的课程,速度比较快,觉得有必要做些笔记进行温习,不然容易忘记,至于练习的话则暂时不做,有php的经验,等到后面学Jsp的时候将 servlet ,jsp ,javabean一起来个统一练习。

笔记:

tomcat部分

1.tomcat运行需要设置环境变量主要是JAVA_HOME,CLASS_PATH,不然的话有些应用汇不正常。

2.tomcat的应用目录是webapps,应用的目录结构是 WebRoot –> WEB-INF ;WEB-INF目录下情况:classes,lib,web.xml。其中classes包含的是编译后的.class文件,lib包含的是应用需要的jar包,web.xml是服务的配置文件。程序源码并不需要发布到应用上面。

web.xml 文件,主要分层如下  service –> connector –> engine –> host->context

1.此文件可以配置servlet访问路径等信息,mapping 可以映射为 /* , *.do,/具体内容,各种形式,其采用的是最长匹配。

2.<load-on-startup>参数可以让servlet在后台启动,这个可以执行定时任务。

3<init-param> 可以配置变量被程序使用

Servlet部分:

1.servlet生存周期: 请求->反射方式装载类-> init()调用一次 ->使用service方法。

2.单例会出现线程同步问题。

3.现在基本继承 HttpServlet来实现功能。

Request & Response对象  主要是几个常用方法需要注意下

1.request.setCharacterEncoding(“utf-8”); response.setContentType(“text/html;charset=utf-8”) 可以进行编码设置,防止乱码的出现。

2.response输出流只能获取一次,之后系统会返回给用户然后自动关闭。

3.两者均有一个跳转 request.getRequestDispatcher(“path”).forward(request,response),response.sendRedirect(url) ,前者是服务器端进行的,可以附带请求和解析的转发,后者是浏览器的302重定向。

4.request主要用于获取客户机的一些信息,url,uri,queryString ,remoteAddr之类。

中文编码乱码处理

   这个比较麻烦,简单说是编码不一致导致的乱码问题。

   需要编码的地方:浏览器编码(request),web服务器编码,返回对象编码(response),文件编码,编译编码(jsp页面)。

   web服务器编码默认是iso-8859-1方式,浏览器默认get使用iso-8859-1(不确定,查协议再说),Post提交的数据encoding一下就可以了。

   如果是要生成url的话,就需要用URL Encoder Decoder 工具对其进行编码/解码了。

post get看实例:

//响应头设成utf-8编码 设置返回编码
    response.setContentType("text/html;charset=utf-8");
    
    //post直接对request 转码就可以  get转码是没用的
    request.setCharacterEncoding("utf-8");


    //如果不转码但是使用 以下方法     post or get都可以顺利转换编码
    String s = new String(request.getParameter("name").getBytes("iso-8859-1"),"utf-8");

    out.println( s  + "get  encode");
    out.println("自己设定的中文"); //这样是可以的
    System.out.println(s + "get提取"); //查看获取到的是否是好码
    out.println("<form name=’form1′ action=” method=’get’>");
    out.println("<input type=’text’ name=’name’>");
    out.println("<input type=’submit’ />");
    out.println("</form>");
    out.flush();
    out.close();

MVC模式

   这个是重点了,model view controller ,分层三块各司其职。   其中model可以细分为 业务逻辑,DAO,持久层。

model主要处理业务逻辑部分,实现业务需要的功能。

controller 主要负责请求的调度,根据请求转向不同的view调用不同的model来处理请求。

view  主要负责界面的显示。

如果用纯servlet实现的话,可以分 domain, service,view,controller 来进行编程。

 

 

个人小结:

不总结的时候以为什么都懂了,看一遍什么都知道了,学得快忘得也快,还需要看书巩固知识。同时需要学习下javascript,至少要会简单的判断。

搭建属于你自己的RAMOS系统 – WIN7+VHD+GURB map方式

前段时间加了一个内存条,将笔记本内存升级到了6G,由于之前用的是32位的win7不可以直接使用6G内存,便装了64位的系统。网上找资源的时候发现,大内存可以使用RamOS,从内存中虚拟出来一个硬盘,然后从虚拟硬盘中启动,系统运行速度可以超过大多数的SSD硬盘。

经过两天尝,N次重启终于成功安装并启动了Win7 RAMOS,下面贴出教程。

安装前需要的一些准备工作:

精简版WIN7镜像678MB:w7_678.gh 点击下载 http://www.anxz.com/down/7197.html

GRUB4DOS :提取grldr.mbr grldr用于启动引导。点击下载

firadisk_driver:grub map出来的虚拟硬盘驱动。点击下载

VSuite.Ramdisk:用于虚拟内存硬盘(64位系统可以装服务器版)。点击下载

Ghost11:这个用来解压镜像的,可以随便找个PE提取。很好找的,自己搜下看吧。

EasyBCD:修改启动项,使用从VHD启动的功能。点击下载

准备做好后就可以开始安装啦。

第一步,建立VHD文件。

win+r 运行compmgmt.msc,切换到磁盘管理器。操作->创建VHD,建立VHD-WIN7.vhd镜像。

创建VHD

选择路径,并指定大小上面镜像需要差不多2.5个G(固定大小)

选择路径

建立好后,挂载到系统上面。记住盘符,最好指定一个卷标。

第二步,使用GHO镜像覆盖VHD磁盘。

打开Ghost11选择local – partition- from image 选择你的GHO镜像文件。

gho1

然后选择镜像分区,确定就可以了

选择镜像分区

接下来注意,他要你选择需要恢复到的目的磁盘,千万别选错了。根据大小来选择就不会错的。

选择目标磁盘

最后选择目标分区,点击确定就可以了。

目标分区

接下来选择覆盖分区,就可以泡茶等了,注意完成后不要重启,我们还有事要做。

第三步,用EasyBCD写入启动项。

分离你刚刚挂载的VHD-WIN7.vhd镜像。

安装easyBCD,启动以后,点击那个Add—以后,选择VHD启动选项卡,然后填写启动菜单名,指定你刚刚使用的VHD-WIN7.vhd镜像。

添加VHD系统的引导

第四部,重启系统,进入VHD系统进行系统安装以及软件、驱动的安装。

1.系统安装完毕后,进入从vhd虚拟硬盘启动的系统,给你的系统安装必要的显卡驱动,以及firadisk驱动

你还可以给你的系统装些必要的软件,例如wps,qq,chrome之类。

确保你的驱动安装上了。

2.安装VSuite.Ramdisk,运行。

先点击杂项,勾上使用未识别内存。

然后选择内存虚拟硬盘,选择大小,指定盘符,勾选优先使用未识别内存。

创建内存硬盘

确定后内存硬盘就生成了。

3.将你的分页文件设置到刚刚生产的内存硬盘上(因为系统占了大量内存,导致可用内存只用700M左右,把分页文件放到内存硬盘上面,可以解决内存不足的问题),同时删除其它所有的分页文件。

右击我的电脑,属性,高级系统设置-切换高级选项卡,设置-切换高级选项卡,更改来设置你的分页文件到RAMDISK

设置分页文件

第五步,安装GRUB,写入引导。

管理员运行命令行中运行下面的指令(点击获取bcdedit语法资料

Bcdedit /create {ffffffff-8d96-11de-8e71-ffffffffffff} /d "grub4dos" /application BOOTSECTOR

Bcdedit /set {ffffffff-8d96-11de-8e71-ffffffffffff} device partition=%systemdrive%

bcdedit /set {ffffffff-8d96-11de-8e71-ffffffffffff} path \grldr.mbr

bcdedit /displayorder {ffffffff-8d96-11de-8e71-ffffffffffff} /addlast

然后将grub中的grldr.mbr grldr 文件提取到引导盘目录下(我这是C)。

创建一个menu.lst文件,写法是这样的

color black/cyan yellow/cyan
timeout=0
default 0

title vhd win7 hd0,1 in top ram
find --set-root /VHD-WIN7.vhd
map --mem--top (hd0,1)/VHD-WIN7.vhd (hd0)
map --hook
root (hd0,0)
chainloader /BOOTMGR

top指令也可以不加,如果镜像超过3.25G必须加top指令,下面的路径自己对应修改((hd0,1)对应的是第一块硬盘的第二分区,我这里的D盘)。

之后重启,从Grub4dos菜单启动,系统就会从硬盘读取镜像到内存启动了,体验下飞一样的感觉吧!

硬盘测试

注意事项:

1.  firadisk驱动在VHD启动的时候必须要装好,不然用grub4dos 启动的时候会直接蓝屏。

2. 如果ramos进去提示页面文件配置失败,自动指定页面文件的消息。你可以先进VHD系统,修改分页文件到物理硬盘,重启,用VSuite.Ramdisk删除新建的RAMDISK,再重建RAMDISK,再修改分页文件到RAMDISK上面,之后直接重新启动到Grub4dos启动的RAMOS中就可以了。

3.如果要安装软件修改系统设置的话,请进入VHD系统进行修改,ramos中所做的任何修改都不回保存。

4.暂时没什么办法进行热备份,使用winhex进行热备份失败了,如果你找到了热备份的方法,一定要告诉我哦!

博客godaddy域名,SF空间,cloudflare的CDN,搬迁成功啦~

一阵子的忙碌以后,网站终于搭建起来了,真挺不容易的。写篇文章做个记录吧。

建个独立博客,这个想法其实一直都有。玩过gae,co.cc,各种免费空间,也给hduradio做过整站修改,还有其他一些乱七八糟的东西,好歹也算是给积攒了些经验吧。

这次建站,花的时间算是有点多了,主要一直想不好空间放哪里,国外用不起,也麻烦,国内要备案,是个硬伤,本来sae是很好的选择,可惜我的身份信息给别人盗用做了备案,国内是不用想了。

申请域名还是很容易的,上godaddy申请就可以了,英文还算好懂,记得使用优惠码,还有别乱点广告就可以了。后台的使用的话网上教程一找一大堆,我就不多说了。

国外找空间找了好久,之前是有个000webhost的一个空间的,做了些坏事,被K了,于是找了pipni.cz的空间来做,有5个G空间,还比较稳定,运气比较差,申请来的ip是被封的,郁闷了。之后就只能用sourceforge的空间的,这个是全球最大的软件仓库,提供免费的PHP空间。这玩意用起来还是很麻烦的。主要流程是这样的 申请以后,建立新的项目,然后进项目管理,给项目主页空间添加上你的域名的别名,修改mysql数据库信息,然后ping下你的项目地址例如:myproject.sourceforge.net,获取ip后就可以进行域名绑定。绑定后用支持SFTP的工具连接你的web主页空间,这里需要注意下主机地址是:web.sourceforge.net 用户名是:你的用户名,你的项目名  比如我的是[heybody,heybody] 这个千万要注意。关于如何使用sourceforge的空间这里有篇文章有需要的可以看看:

http://www.freehao123.com/sourceforge-net/

注意别滥用。

我分配到的空间国内ping有400+以上,国内访问起来像龟爬一样。

空间速度比较慢,除了用CDN,没什么好办法了。国内免费CDN还是有几家的,webluker其实是最佳选择,奈何还是备案,加速乐也需要备案,还有个wdcdn可以用,嗯,它就是个玩具,还是算了吧。国外的找了好几家,cdnzz,speedymirror,cloudflare,cdnzz速度其实还可以,香港有节点,加速效果挺明显的,就是流量少了点,一个月1G流量,怎么都不够用啊,speedymirror的话还是给海外加速比较好点,据说只有美国和英国有加速节点,国内用起来的话速度实在是可怜了。最后还是选了cloudflare,这个是个新秀,国外很火,国内由于一些政策知道的人不怎么多。

用cloudflare后,国内访问的流量走的是 Los Angeles, CA 加利福尼亚州洛杉矶机房的线路,小站访问速度快了50%左右,做加载测试比之前好了很多。如果直接访问速度不是太夸张的话,其实直接用DNSPOD还是很好的选择,解析快,及时生效。

最后的话就是选个主题了,个人要求不高,简单就好,以后想改动比如加个weibo关注什么功能的会比较方便。最重要的是——加载快。

接下来应该会在sae上做个图床,或者给站点加上微博关注,人人分享之类的东西,anyway…写php练练手,长时间不写,真的会退化的。

注意:

dns nameserver修改是有生效时间的,如果已经收录以后还乱修改,会由于访问不稳定给K站的。

分析sql注入的原理与条件

现在的网络,脚本入侵十分的流行,而脚本注入漏洞更是风靡黑客界。不管是老鸟还是新起步的小菜,都会为它那巨大的威力和灵活多变的招式所着迷。正是因为注入攻击的流行,使的市面上的注入工具层出不穷。比较出名的有小竹的NBSI、教主的HDSI和啊D的注入工具等等。这大大方便的小菜们掌握注入漏洞。可是,工具是死的,注入的手法却是活的,能否根据实际情况灵活地构造SQL注入语句,得到自己想要的信息,是高手与小菜的根本区别。只用工具,而不去管它的原理,是不可能得到提高的,当然,在遇到一些特殊情况的时候,那些只会用工具的小菜们也只能放弃了。所以学会手工注入自己构造SQL注入语句是一个黑客爱好者必上的一堂课。

恶补基础:

要想学会手工注入,有一个名词是不得不提的,那就是数据库系统。

1。简介

数据库系统分为数据库和数据库管理系统!数据库是存放数据的地方,数据库管理系统则是管理数据库的软件!数据库中数据的存储节构叫数据模型!有四种常见的数据模型,分别是层次模型、网状模型、关系模型和面向对象模型。其中关系数据模型是最主要的数据模型,ACCESS、MSSQL、ORACLE等都是关系模型数据库系统。其中以ACCESS、MSSQL数据库系统最为常见!这些都是理论的知识,希望大家理解。

2。基本概念

表:表是一个关系数据库的基本组成元素!它按行与列组合排列成相关信息。通常行称为记录,列称为域。每个域称为一个字段!每一条记录都由多个字段组成。每个字段的名字叫做字段名,每个字段的值叫估字段值。表中的每一行即每一条记录都拥有想同的结构。如图1。

图1中的这张表里有14行,即14条记录。有4列,即4个字段,4个字段的名字分别叫:job_id(下面对应的1、2、3等都是这个字段的值,后面三个字段的值举一反三!) 、job_ desc、 min_lvl、max_lvl。因为本文不是专讲数据库知识的,所以这里只讲一些最重要的概念,有兴趣的朋友可以自己去查看数据库的有关资料!

3。注入的条件

只有调用数据库的动态页面才有可有存在注入漏洞,动态页面包括asp php jsp cgi等。本文只讲对asp页面的注入。那什么是调用数据库的页面呢?比如这样的形势:

asp?id= php?id= 这样的样子的都是调用数据库的页面。”?”后面加的id的名字叫变量,注意这个变量是可以随便换的,”=”号后面的值名字叫参数!这个参数也是可以变的!大家的思路一定要灵活,要学会举一反三,不要太死板。

4。注入漏洞的原理分析:

程序对用户提交的变量没有进行有效的过滤,就直接带入查询语句中,这样,我们就可以提交具有数据查询功能的语句,加入到程序将要提交的信息中去,再根据服务器返回的信息来判断数据库里的内容!光这样说大家可能不太好理解,不要紧,接着往下看。

有关的基础已经讲完了 下面开始实战练习部分。

实战部分

如果是刚刚接触注入的新手朋友,我们要做的第一步就是,用鼠标右键点击桌面上的IE图标,再点属性,然后再点“高级”,然后往下拉滚动条,找到“显示

友好HTTP错误信息”,把前面的勾去掉,再点“确定”,这样做是为了让我们得到更多的服务器返回的信息。

第一部分:ACCESS数据库手工注入

1。判断是否存在注入漏洞:

这个相信大家都应该知道! 就是在一个调用数据库的网址后面加上分别加上 and 1=1和 and 1=2 ,如果加入and 1=1返回正常(就是和原来没有加 and 1=1时页面样子的一样),而加入 and 1=2返回错误(和原来没有加 and 1=2时页面的样子不一样),就可以证明这个页面存在注入漏洞。比如:

http://www.xxx.com/a.asp?id=7,这个网页,我们在后面加上 and 1=1(两个空格,and前面一个,and和1=1之间一个!),网址就变成了

http://www.xxx.com/a.asp?id=7 and 1=1,用IE打开这个网页,返回正常!再尝试在后面加上and 1=2,网址就变成了

http://www.xxx.com/a.asp?id=7 and 1=2,同样用IE打开这个网页,返回错误!这就说明这个网页http://www.xxx.com/a.asp?id=7存在注入漏洞,是一个注入点!(存在注入漏洞的网页叫注入点!)可是,并不是所有的页面都可以这样判断,有的页面不管你加入 and 1=1 还是 and 1=2,返回的都是错误的页面,难道这样的页面就没有注入漏洞吗?不一定!比如这个页面:http://www.xxxxxx.com/b.asp?id=ade7, 不管我们在后面上的是and 1=1还是and 1=2,它都返回错误的页面!这个时候我们就要尝试用另一种方法来测试漏洞了,这种方法可以说是and 1=1和and 1=2的变种方法。原来的网址是这样的:http://www.xxxxxx.com/b.asp?id=ade7,现在我们把它变成这个样子:http://www.xxxxxx.com/b.asp?id=ade7′ and ‘1’=’1 ,用IE打开它,看看返回正不正常!如果正常,那就可以接着用这个地址来进一步测试漏洞是否存在(如果返回不正常那这个页面就很有可能不存在注入漏洞!):http://www.xxxxxx.com/b.asp?id=ade7′ and ‘1’=’2 ,用IE打开这个网址,如果返回错误的话,那这个网址http://www.xxxxxx.com/b.asp?id=1就存在注入漏洞!

A。数字型参数注入点分析

这时肯定有朋友要问了,为什么用一开始那种and 1=1 and 1=2不行呢!呵呵,先不要急,先看看这两个存在注入漏洞的页面有什么不一样?

(你不要告诉偶第二个网址比第一个网址多了几个X),相信大家已经看到了,第二个网址后跟的参数是ade7,是字符!而第一个网址后跟的参数是7,是数字!就是因为这里,才引起了测试漏洞的语句的不同!学过数据库的朋友们应该知道,在查询中,字符型的值,是要用单引号包起来的,也就是这个样子’字符型数据’。这里假设第一个注入页面所对应的查询语句是这样的(凡是调用数据库的页面都会有一条或者几条对应的查询语句,用来对数据库里的内容进行查询!)

 

 

:select * from 表名 where id=7。这是原来的那条查询语句,这条语句是正确的,可以在数据库中查询出相应的内容!可是如果我们在网址后面加上了 and 1=1,那这条查询语句就会变成select * from 表名 where id=7 and 1=1(这下知道了注入漏洞原理分析那里讲的变量没有过滤的意思了吧!),这里有必要说一些数据库的有关知识,这条语句里,and是逻辑运算符!(这个记住就行了),用中文翻译过来就是“和”的意思!在高中的数学里讲过,用“和”来连接的两个句子,必须都是真的,不然整个句子就不是真的!比如:苹果和大象都是水果。这句话就是错的,苹果是水果,可是大象不是!这下大家应该可以理解“用“和”来连接的两个句子,必须都是真的,不然整个句子就不是真的”这句话了吧。如果换成苹果和梨都是水果,那这句话就是对的。知道了and的用处后,再回来看select * from 表名 where id=7 and 1=1这个句子,and 前面的select * from 表名 where id=7肯定是对的,(为什么呢,如果这条查询语句都不对,那这个注入页而就有问题了!所以and前面的那个句子一定是对的!)。再看and后面,1=1,不用我说了吧,也是对的(难道一不等于一吗?)根据刚才说的and用处,现在我们可以判定select * from 表名 where id=7 and 1=1这条查询语句,仍然是对的!所以它还是可以正确地从数据库里查询出信息,返回给我们!

举一反三,那这个句子:select * from 表名 where id=7 and 1=2,肯定是不对的了,那这条查询语句就不能正确地从数据库里查询出信息,所以我们就会看到一个错误的页面! 以上是注入点参数是int(整数型)时的分析。

B。字符型参数注入点分析

和刚才一样,我们先来看第二个字符型注入页面里的查询语句,比如是这个select * from 表 where id=’ade7′(为什么加引号?看前面吧!)。原来的查询语句是这个样子的,如果我们还按照数字型参数的那种测试漏洞的方法的话,语句就会变成这样:select * from 表 where id=’ade7 and 1=1’和

select * from 表 where id=’ade7 and 1=2′ ,因为程序会自动查询引号里的内容,如果我们按前面这两个语句这样提交的话,程序就会查询id值为ade7 and 1=1和ade7 and 1=2的记录,这样是查不到结果的(你可不要告诉我数据库里正好有两个记录的id就是ade7 and 1=1 和and 1=2)。这里可能有朋友要问了,为什么不是查询id为’ade7,然后and 1=’1呢?好,我现在回答你们,就算可以查询id值为’ade7的记录,那这个句子也是错的,1怎么会等于’1呢?对吧?更何况程序是不可能查询’ade7的,更准备的说是数据库中不可能有一个字段的值是’ade7,因为这个字符串少一个引号,如果直接把这个字符串存入数据库的话,程序会报错的!怎么样?明白了吧?现在再说用 ‘ and ‘1’=’1和’ and ‘1’=’2来测试的的原理!同样是这个查询语句:

select * from 表 where id=’ade7’,如果我们在网址后面加了’ and ‘1’=’1,那这个查询语句就会变成

select * from 表 where id=’ade7′ and ‘1’=’1′(这里最外面的那一层引号是程序自动加上的),变成这个样子!这个语句对不对呢?我们分析一下。如果我们提交个语句,那程序就会自动查询id值是ade7的记录!因为这个记录是存在的(不存在的话那就是这个网页有问题了!),然and后面跟的’1’=’1’是正确的,所以这个语句是正确的!如果我们把’ and ‘1’=’1换成’ and ‘1’=’2,那语句就成了select * from 表 where id=’ade7′ and ‘1’=’2’,只看后面我们就可以知道这个语句对不对了!’1’怎么可能等于’2’呢?是吧?好了,字符型参数的注入点的原理就介绍到这里!

2。数据库类型的判断

在确定了一个地址是注入点后,我们首先要判断这个注入点所连接的数据库的类型!这里介绍几种简单的方法。如果一种判断不出来就再换另一种判断方法!

A。在注入点后直接加上单引号。有的时候我们可以根据服务器报错的信息来判断它用的是什么数据库。如图2!通过这个错误信息我们可以看出来这个注入点所连接的数据库的类型是ACCESS,为什么呢,仔细看!它说的是Microsoft JET Database Engine 錯誤 ‘80040e14’ ,说明是通过JET引擎连接数据库,而不是ODBC!如果是用JET方法连接的话就说明用的是ACCESS数据库,如果是ODBC的话就说明数据库是MSSQL!这个记住就行了。其实还有详细的错误信息,它直接把数据库的类型告诉你了!因为我没有找到这样的注入点,这里就截不了图了。大家遇的到话肯定一眼就可以看出来!

B。在注入点后加上(注意,你先确定了它是注入点后再加,不是注入点你加了也没用!): ;–(一个分号,两个横线!)比如这个网址

http://www.xxxxxxxx.com/Article/as.asp?id=875,我们事先已经确定了它是注入点了, 这样的话我们就可以在后面加上;–让它变成

http://www.xxxxxxxx.com/Article/as.asp?id=875;– 提交这个网址,如果页面返回正常的话,说明数据库是MSSQL。因为在MSSQL数据库里,;和–都是存在的,”;” 用来分离两个语句,而”–“就是注释符,在它后面的语句都不执行!而ACCESS数据库里没有!所以如果是ACCESS的数据库,当你在注入地址

后面加上”;–“的话那程序就会把”;–“当成参数的一部分,这样查询就会出错!如果错误,那基本上可以肯定是ACCESS了(因为网上用这两种数据库的网站最多!)

C。用以上方法都判断不出来的话,那可以用这一招!利用ACCESS和MSSQL数据库的差异来进行判断!要用到两个查询语句!同样,如果注入点是http://www.xxxxxxxx.com/Article/as.asp?id=875,那我们在后面加上 and exists (select count(*) from sysobjects),那么地址就变成了http://www.xxxxxxxx.com/Article/as.asp?id=875 and exists (select count(*) from sysobjects)。如果页面正常返回,那就可以证明数据库是MSSQL的。我来解释一下这个语句:这个句子的意思是查询sysobjects表里的记录数大于0!(有点别扭!)如果返回正常,说明大于0,也就说明存在sysobjects这个表,因为这个表只有MSSQL数据库里才有,所以可以确定数据库的MSSQL的!如果返回错误,那就不是!那我们怎么用查询语句来判断数据库是不是ACCESS的呢!别急,往下看!我们在注入点后加上 and exists (select count(*) from msysobjects)。就成了http://www.xxxxxxxx.com/Article/as.asp?id=875

 

 

exists (select count(*) from msysobjects),按刚才理解MSSQL数据库的方法去理解这条语句!这里要注意,提交这个语句是不会返回正常页面的!就算是ACCESS数据库也不会返回正常的页面!因为默认情况下,我们是没有权限查询这个表里的数据的!不过WEB会提示我们 “记录无法读取;’msysobjects’没有读取权限”!如果返回的是这个错误信息的话,那就证明是ACCESS数据库了!如图3!简单地来说就是两条查询语句:

 

and exists (select count(*) from sysobjects)

and exists (select count(*) from msysobjects)

如果第一条返回正常,那就是MSSQL数据库,如果两条都不正常,那就是ACCESS数据库了(这里只讨论MSSQL和ACCESS)

注意:上面讲的全是参数是int的时候的检测方法,如果参数是字符型的,那就先要在参数后面加上单引号,然后再在查询语句最后加上”;–“

3。猜表、字段名、检测记录数、检测字段长度。

我按照工具注入的流程给大家讲!

A。猜表!

用到的语句:and exists (select count(*) from 你要猜的表名) 。在注入点后加上这句话,如果返回正常,说明你猜的表是存在的!比如

http://www.xxxxxxxx.com/Article/as.asp?id=875 and exists (select count(*) from admin),如果返回正常,说明admin这张表存在!如果返回错误,就说明不存在!。别的表也都是这么猜!

B。猜列!

用到的语句:and (select count(列名) from 猜到的表名)>0 。在注入点后加上这句话,如果返回正常,说明你猜的列是存在的!比如

http://www.xxxxxxxx.com/Article/as.asp?id=875 and (select count(username) from admin)>0,如果返回正常,那username这个列就存在!不过首先要确定from后面跟的表名要是存在的哦!不然你怎么猜都是错的!

C。检测记录数

用到的语句:and (select count(*) from 猜到的表名)>X (X是个数字)。在注入点后加上这句话,并不停地变换X这个数字,直到猜到准确的记录数为止!比如http://www.xxxxxxxx.com/Article/as.asp?id=875 and (select count(*) from admin)>2 ,这个句子是猜admin表里有几条记录的,也就是有几个管理员(因为一个管理员对应一条记录嘛!)。如果返回正常,说明admin这张表里的记录数大于2。这个时候我们把2改成别的大一点的数!比如5,如果返回错误,说明管理员的个数在2和5之间,2和5之间的整数是3和4,这个时候我们变换语句为http://www.xxxxxxxx.com/Article/as.asp?id=875 and (select count(*) from admin)=3或者=4,哪个返回正常那管理员的个数就是哪个。如果提交>5还返回错误,那就再取一个更大的数,再重复刚才的动作就可以猜到记录数!

D。检测字段长度

用到的语句:and (select top 1 len(列) from 表)>X (X和刚才一样!)。我来解释一下这个句子,select top 1是查询第一条数据的意思!(在WEB环境下不支持多行回显!只是一次查询的数据不能超过一行!),len是MSSQL里的一个函数,用法是len(),()里可以是字符串也可以是表达式也可以是列名!知道这些,大家应该可以看懂了吧!后面那个X的变换方法上面的一样!

 

 

 

 

数据结构课程设计报告,哈夫曼树

 

 

 

 

数据结构课程设计 

 

实验题目:赫夫曼编码/译码器 

 

 

       

 

 

 

 

 

 

 

 

 

 

一、需求分析 

      利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个赫夫曼码的编/译码系统。 

 

 

二、基本要求 

    1.基本要求 

一个完整的系统应具有以下功能: 

     (1) I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中。 

 (2) E:编码(Encoding)。利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 

 (3) D:译码(Decoding)。利用已建好的赫夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。 

2.测试要求 

(1) 利用教科书例6-2的数据调试程序:已知某系统在通信联络中只可能出现八种字符,其频率分别0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计赫夫曼编码。 

(2) 用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:“THIS PROGRAME  IS  MY  FAVORITE”。 

 

字符 

 

A 

B 

C 

D 

E 

F 

G 

H 

I 

J 

K 

L

M

频度

186

64

13

22

32

103

21

15

47

57

1

5

32

20

字符

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

 

频度

57

63

15

1

48

51

80

23

8

18

1

16

1

 

 

3.实现提示

(1) 编码结果以文本方式存储在文件Codefile中。

(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。请用户键入一个选择功能符。此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。

(3) 在程序的一次执行过程中,第一次执行IDC命令之后,赫夫曼树已经在内存了,不必再读入。每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。

概要设计 

   程序主要分为五部分,哈夫曼节点的定义,哈夫曼编码的定义,Select函数选择出权值最小的节点,Initialization函数生成哈夫曼树,主函数。

  

四、详细设计

1. 数据存储结构设计

1哈夫曼节点

 哈夫曼节点数据类型如下,包含字符,权值,父节点,左右孩子:

typedef struct{

        char ch;

        unsigned int weight;

        unsigned int parent,lchild,rchild;       

}HTNode,*HfmTree;

(2)哈夫曼编码

     哈夫曼编码用二级指针存储,动态分配空间:

typedef char **HfmCode;

2. 算法的设计思想

   1Select函数

 

void Select(HfmTree HT,int a,int &s1,int &s2){
     //选择出parent为0的两个权值最小的两个节点,s1节点权值小于s2节点
     int i,temp;
     i=0;
     while(HT[++i].parent!=0);
     s1=i;
     while(HT[++i].parent!=0);
     s2=i++;
     if(HT[s1].weight>HT[s2].weight){
        temp=s1;
        s1=s2;
        s2=temp;
     }
     for(;i<=a;i++){
        if(HT[i].parent==0)
           if(HT[i].weight<HT[s1].weight)  s1=i;
             else if(HT[i].weight<HT[s2].weight) s2=i;
     }
}//选出权值最小且无父节点的节点,选择范围为i-a;

 

   2Initialization函数

 

void Initialization(HfmTree &HT,HfmCode &HC,int n,string ch,int *w)
   {
     int i,m,s1,s2,start,c,f;
//i HTNode位置,m为哈夫曼树节点数,s1s2选择节点,start开始点,c当前节点,f父节点
     char* cd;
     if(n<=1) return;
     m=2*n-1;
     HT=(HfmTree)malloc((m+1)*sizeof(HTNode));//0号单元使用
     for(i=1;i<=n;i++){
        HT[i].ch=ch[i-1];
        HT[i].weight=w[i-1];
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
     }//初始化叶子节点

     for(;i<=m;i++){
        HT[i].ch='0';
        HT[i].weight=0;
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
     }//----------------为什么不能批量赋值----------!!

     for(i=n+1;i<=m;i++){//建立 哈夫曼树
        Select(HT,i-1,s1,s2);
        HT[s1].parent=i;
        HT[s2].parent=i;
        HT[i].lchild=s1;
        HT[i].rchild=s2;
        HT[i].weight=HT[s1].weight+HT[s2].weight;
     }
     HC=(HfmCode)malloc((n+1)*sizeof(char*));
     cd=(char*)malloc(n*sizeof(char));
     cd[n-1]='';
     for(i=1;i<=n;i++){
        start=n-1;
        for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){
           if(HT[f].lchild==c){
              cd[--start]='0';
           }else{
              cd[--start]='1';
           }
        HC[i]=(char*)malloc((n-start)*sizeof(char));
        strcpy(HC[i],&cd[start]);
        }
     }
     free(cd);
     cout<<"生成成功!"<<endl<<endl;;
     cout<<"IDtchart"<<"weight"<<"t"<<"parent"<<"t"<<"lchild"<<"t"<<"rchild"<<"t"<<endl;
     for(i=1;i<2*n;i++){
          cout<<i<<"t"<<HT[i].ch<<"t"<<HT[i].weight<<"t"<<HT[i].parent<<"t"<<HT[i].lchild<<"t"<<HT[i].rchild<<"t"<<endl;
     }
     cout<<"chart"<<"Codet"<<endl;
     for(i=1;i<=n;i++){
           cout<<HT[i].ch<<"t"<<HC[i]<<"t"<<endl;
    }
}
 //生成,前半部分为生成哈夫曼树,调用Select得出权值最小的两项,计算权值
 //后半部分为哈夫曼编码生成,从后到前生成,动态分配空间大小

 

 

3.源程序

 

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
typedef struct{
        char ch;
        unsigned int weight;
        unsigned int parent,lchild,rchild;
}HTNode,*HfmTree;

typedef char **HfmCode;

void Select(HfmTree HT,int a,int &s1,int &s2){
     //选择出parent为0的两个权值最小的两个节点,s1节点权值小于s2节点
     int i,temp;
     i=0;
     while(HT[++i].parent!=0);
     s1=i;
     while(HT[++i].parent!=0);
     s2=i++;
     if(HT[s1].weight>HT[s2].weight){
        temp=s1;
        s1=s2;
        s2=temp;
     }
     for(;i<=a;i++){
        if(HT[i].parent==0)
           if(HT[i].weight<HT[s1].weight)  s1=i;
             else if(HT[i].weight<HT[s2].weight) s2=i;
     }
}


void Initialization(HfmTree &HT,HfmCode &HC,int n,string ch,int *w)
   {
     int i,m,s1,s2,start,c,f;
     //i HTNode位置,m为哈夫曼树节点数,s1s2选择节点,start开始点,c当前节点,f父节点
     char* cd;
     if(n<=1) return;
     m=2*n-1;
     HT=(HfmTree)malloc((m+1)*sizeof(HTNode));//0号单元使用
     for(i=1;i<=n;i++){
        HT[i].ch=ch[i-1];
        HT[i].weight=w[i-1];
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
     }//初始化叶子节点

     for(;i<=m;i++){
        HT[i].ch='0';
        HT[i].weight=0;
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
     }//----------------为什么不能批量赋值----------

     for(i=n+1;i<=m;i++){//建立 哈夫曼树
        Select(HT,i-1,s1,s2);
        HT[s1].parent=i;
        HT[s2].parent=i;
        HT[i].lchild=s1;
        HT[i].rchild=s2;
        HT[i].weight=HT[s1].weight+HT[s2].weight;
     }
     HC=(HfmCode)malloc((n+1)*sizeof(char*));
     cd=(char*)malloc(n*sizeof(char));
     cd[n-1]='';
     for(i=1;i<=n;i++){
        start=n-1;
        for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){
           if(HT[f].lchild==c){
              cd[--start]='0';
           }else{
              cd[--start]='1';
           }
        HC[i]=(char*)malloc((n-start)*sizeof(char));
        strcpy(HC[i],&cd[start]);
        }
     }
     free(cd);
     cout<<"生成成功!"<<endl<<endl;;
  cout<<"IDtchart"<<"weight"<<"t"<<"parent"<<"t"<<"lchild"<<"t"<<"rchild"<<"t"<<endl;
     for(i=1;i<2*n;i++){
cout<<i<<"t"<<HT[i].ch<<"t"<<HT[i].weight<<"t"<<HT[i].parent<<"t"<<HT[i].lchild<<"t"<<HT[i].rchild<<"t"<<endl;
     }
     cout<<"chart"<<"Codet"<<endl;
     for(i=1;i<=n;i++){
           cout<<HT[i].ch<<"t"<<HC[i]<<"t"<<endl;
    }
}



int main(){
    ifstream input_file;
    ofstream output_file;
    char action;
    string toBeTranSource,textFileSource;
    string charsIn,code;
    int i,j,c,n,w[100];
    HfmTree HT;
    HfmCode HC;
    while(action!='Q'){
        cout<<endl<<"**********************************************"<<endl;
        cout<<"*          哈夫曼编码/译码器                 *"<<endl;
        cout<<"*                                            *"<<endl;
        cout<<"*  I.初始化  E.编码  D.译码 /P.印码  /T.印树 *"<<endl;
        cout<<"*  C.清屏                                    *"<<endl;
        cout<<"*     Code by whocaresu    16/12/2010        *"<<endl;
        cout<<"**********************************************"<<endl;
        cout<<endl<<"请输入操作码:";
        cin>>action;
        action=toupper(action);
        switch(action){
                       case 'I':
                            // 输入信息
                            cout<<"请输入字符数:";
                            cin>>n;
                            cout<<"请输入字符组(紧密输入不用空格区分):";
                            getline(cin,charsIn);
                            getline(cin,charsIn);
                            cout<<"输入各个权重(中间空格):";
                            for(i=1;i<=n;i++){
                            cin>>w[i-1];
                            }
                            Initialization(HT,HC,n,charsIn,w);
                            //输出备份到文件
                            cout<<"正在输出备份到hfmTree.txt..."<<endl;
                            output_file.open("hfmTree.txt");
                            if(!output_file){
                                 system("cls");
                                 cout<<"Can't open file!"<<endl;return 1;
                            }
                            output_file<<n;
                            output_file<<charsIn<<"n";
                            for(i=0;i<n;i++){
                               output_file<<w[i]<<" ";
                            }
                            output_file<<"--------以下为具体编码信息--------"<<endl;
                            output_file<<"ChartCodet"<<endl;;
                            for(i=1;i<=n;i++){
                            output_file<<HT[i].ch<<"t"<<HC[i]<<"t"<<endl;
                            }
                            output_file.close();
                            cout<<"备份到hfmTree.txt成功!"<<endl;
                            ;break;

                       case 'E':
                            //判断内存中是否有生成哈夫曼树,没有的话从文件读入
                            if(sizeof(HC)<5){
                           cout<<"内存中不存在哈夫曼树,从hfmTree.txt读入!"<<endl;
                               input_file.open("hfmTree.txt");
                               if(!input_file){
                                 system("cls");
                                 cout<<"Can't open file!"<<endl;return 1;
                               }
                               input_file>>n;
                               getline(input_file,charsIn);
                               for(i=1;i<=n;i++){
                                  input_file>>w[i-1];
                               }
                               input_file.close();
                               Initialization(HT,HC,n,charsIn,w);
                            }
                            input_file.open("ToBeTran.txt");
                            if(!input_file){
                                 system("cls");
                                 cout<<"Can't open file!"<<endl;return 1;
                            }
                            cout<<"-------从ToBetTran.txt读取数据为--------"<<endl;
                            getline(input_file,toBeTranSource);
                            cout<<toBeTranSource<<endl;
                            input_file.close();
                            cout<<"----------------------------------------"<<endl;
                            output_file.open("CodeFile.txt");
                            if(!output_file){
                                 system("cls");
                                 cout<<"Can't open file!"<<endl;return 1;
                            }
                            cout<<"------编译的密文(输出到CodeFile.txt)----"<<endl;
                            for(i=0;i<=toBeTranSource.length();i++){
                               for(j=1;j<=n;j++){
                                  if(toBeTranSource[i]==HT[j].ch){
                                     cout<<HC[j];
                                     output_file<<HC[j];
                                  }
                               }
                            }
                            output_file.close();
                            cout<<endl<<"------------编译完成--------------------"<<endl;
                            ;break;
                      case 'D':
                           //译码
                           input_file.open("CodeFile.txt");
                           if(!output_file){
                                 system("cls");
                                 cout<<"Can't open file!"<<endl;
                                 return 1;
                           }
                           cout<<"------------读取的编码为----------------------"<<endl;
                           getline(input_file,code);
                           cout<<code<<endl;
                           input_file.close();
                           cout<<"----------------译码为--------------------"<<endl;
                           c=2*n-1;
                           output_file.open("TextFile.txt");
                           for(i=0;i<=code.length();i++){
                               if(HT.lchild==0){
                                 cout<<HT.ch;
                                 c=2*n-1;
                               }
                               if(code[i]=='0') c=HT.lchild;
                               else c= HT.rchild;
                           }
                           cout<<endl;
                           cout<<"-------------------------------------------"<<endl;
                           ;break;
                      case 'C':
                           system("cls");
                           break;
                      default:
                              cout<<endl<<"操作码错误,重新输入!"<<endl;
        }
   }
   system("pause");
   return 0;
    }

 

 

 

五、调试分析

1.测试数据列表:

(1) 利用教科书例6-2的数据调试程序:0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11

(2) 用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:“THIS PROGRAME  IS  MY  FAVORITE”。

 abcdefghijklmnopqrstuvwxyz

186 64 13 22 32 103 21 15 47 57 1 5 32 20 57 63 15 1 48 51 80 23 8 18 1 16 1


 

 

 

 

 

 

 

 

 

 

、课程设计总结及心得体会

     不得不说,这个是目前做到的最复杂的一个程序,与停车场相比,它的函数,数据存储结构的定义少了不少,但是其复杂度却比停车场有过之无不及,文件操作比较复杂,为此我查阅了相关资料,做到了基本能够实现文件的读取和写入,程序中依然存在一个问题,那就是它只能读取一段文字,遇到回车会终止读入,这也局限了程序的使用面。

     在开发哈夫曼编译器的时候,发现一个整体概念很重要,要很清晰地知道它具体是怎么运作的。双亲结点,左右孩子,字符,权值组成哈夫曼节点,二级指针来动态存储哈夫曼编码,然后分配空间,调用Select函数帮助生成哈夫曼树,最后才生成哈夫曼节点。

     这次课程设计,加深了我对哈夫曼树的理解,巩固了数据结构的知识。但是我认为其中更加重要的是实践的一个过程,实践中学习,清楚了理论与实践之间的差距。用google搜索相关的资料,然后从资料中获取自己需要的信息,化为己用,这种学习的能力的锻炼,我认为才是最为重要的。

     

 

Chrome 常用键盘快捷键

Chrome 常用键盘快捷键

如果你是初次使用Chrome,有可能你会感觉Chrome好像缺少了某些东西似的,没错,为了让用户获得最大的浏览界面,Chrome连工具栏都缩成一个小小的按钮了。别以为这样会很不方便,Chrome提供了大量的键盘快捷方式,让你轻松打开你想要的功能。

窗口和标签页快捷键

 

Ctrl+N 打开新窗口
Ctrl+T 打开新标签页
Ctrl+Shift+N 在隐身模式下打开新窗口
Ctrl+O,然后选择文件 在谷歌浏览器中打开计算机上的文件
按住 Ctrl 键,然后点击链接 从后台在新标签页中打开链接,但您仍停留在当前标签页中
按住 Ctrl+Shift 键,然后点击链接 在新标签页中打开链接,同时切换到新打开的标签页
按住 Shift 键,然后点击链接 在新窗口中打开链接
Alt+F4 关闭当前窗口
Ctrl+Shift+T 重新打开上次关闭的标签页。谷歌浏览器可记住最近关闭的 10 个标签页。
将链接拖动到标签页内 在指定标签页中打开链接
将链接拖动到两个标签页之间 在标签页横条的指定位置建立一个新标签页,在该标签页中打开链接
Ctrl+1 到 Ctrl+8 切换到指定位置编号的标签页。您按下的数字代表标签页横条上的相应标签位置。
Ctrl+9 切换到最后一个标签页
Ctrl+Tab 或Ctrl+PgDown 切换到下一个标签页
Ctrl+Shift+Tab Ctrl+PgUp 切换到上一个标签页
Ctrl+W 或 Ctrl+F4 关闭当前标签页或弹出式窗口
Alt+Home 打开主页

地址栏快捷键

在地址栏,进行下列操作之一:

 

键入搜索字词 使用默认搜索引擎进行搜索
键入网址中”www.”和”.com”之间的部分,然后按 Ctrl+Enter 为您在地址栏中输入的内容添加”www.”和”.com”,然后打开网址
键入搜索引擎关键字或网址,按 Tab 键,然后键入搜索字词 使用与关键字或网址相关联的搜索引擎进行搜索。如果谷歌浏览器可以识别您要使用的搜索引擎,则会提示您按 Tab 键。
F6 或 Ctrl+L 或 Alt+D 选中网址区域中的内容
键入网址,然后按Alt+Enter 键 在新标签页中打开网址

打开谷歌浏览器各功能的快捷键

 

Ctrl+B 打开和关闭书签栏
Ctrl+Shift+B 打开书签管理器
Ctrl+H 查看”历史记录”页
Ctrl+J 查看”下载”页
Shift+Escape 查看任务管理器
Shift+Alt+T 将焦点设置在工具栏上。使用键盘上的向右和向左箭头,可导航至工具栏上的不同按钮。

网页快捷键

 

Ctrl+P 打印当前页
Ctrl+S 保存当前页
F5 重新加载当前页
Esc 停止加载当前页
Ctrl+F 打开”在网页上查找”框
点击鼠标中键或滚轮(只在谷歌浏览器测试版(只有英文版)中可用) 激活自动滚动。当您移动鼠标时,网页会根据鼠标的移动方向自动滚动。
Ctrl+F5 或 Shift+F5 重新加载当前页,但忽略缓存内容
按住 Alt 键,然后点击链接 下载链接
Ctrl+G 或 F3 查找与您在”在网页上查找”框中输入的内容相匹配的下一个匹配项
Ctrl+Shift+G 或 Shift+F3 查找与您在”在网页上查找”框中输入的内容相匹配的上一个匹配项
Ctrl+U 查看源代码
将链接拖动到书签栏 将链接加入书签
Ctrl+D 将当前网页加入书签
Ctrl++,或者按住 Ctrl 键并向上滚动鼠标滚轮 放大网页上的所有内容
Ctrl+-,或者按住 Ctrl 键并向下滚动鼠标滚轮 缩小网页上的所有内容
Ctrl+0 将网页上的所有内容都恢复到正常大小

文字快捷键

 

选中内容,然后按 Ctrl+C 键 将内容复制到剪贴板
将光标置于文本字段中,然后按 Ctrl+V 或Shift+Insert 键 从剪贴板粘贴当前内容
将光标置于文本字段中,然后按 Ctrl+Shift+V 键 从剪贴板粘贴当前内容的纯文本部分
选中文字字段中的内容,然后按 Ctrl+X 或Shift+Delete 键 删除内容并将其复制到剪贴板

我想你,但不会找你

我想你,但不会找你,来自张小娴。女人心,海底针。

有时候,你很想念一个人,但你不会打电话给他。打电话给他,不知道说甚麼好,还是不打比较好。

想念一个人,不一定要听到他的声音。听到了他的声音,也许就是另一回事。想像中的一切,往往比现实稍微美好一点。想念中的那个人,也比现实稍微温暖一点。思念好像是很遥远的一回事,有时却偏偏比现实亲近一点。

一个女人因为一个男人的离开而自寻短见,只有一个原因,就是除了他以外,她一无所有。拥有得愈多的人,愈舍不得死。一无所有的人,才会觉得活著没意思。

他不爱你,再过一万年之后也不爱你,你为甚麼还要为他痴迷,为他流泪?醒醒吧。

有些事情是不可以勉强的。恋爱是双程路,单恋也该有一条底线,到了底线,就是退出的时候。这条路行不通,你该想想另一条路,而不是在路口徘徊。这里不留人,自有留人处。

如果你开心和悲伤的时候,首先想到的,都是同一个人,那就最完美,如果开心的时候和悲伤的时候,首先想到的,不是同一个人,我劝你应该选择你想和他共度悲伤时刻的那一个,人生本来是苦多於乐。你的开心,有太多人可以和你分享,不一定要是情人,如果日子过得快乐,自己一人也很好,悲伤,却不是很多人可以和你分担。你愿意把悲伤告诉他,他才是你最想亲近和珍惜的人。

爱情里的所谓期限,都是用来延迟的。我很想不等你了,我却舍不得走。我知道我会老,我却舍不得放手。为甚麼要有期限?因为我担心我做不到。

爱情有生、老、病、死。爱情老了,生病了,治不好,爱情就会死。爱情要死,是时限到了。我们何必要恋恋不肯放手?万物有时序,你不可能一无所知,你只是希望把大限再延迟一点。花开花落,万物有时,你为甚麼不肯接受这是自然的定律?

离开之后,我想你不要忘记一件事:不要忘记想念我。想念我的时候,不要忘记我也在想念你。

就是喜欢这样,即使想你想到哭,我也不会去找你,我只是静静的想你。

c++数据结构编程,停车场管理

终于好了~~中间一个错误,内存分配有问题,原来malloc分配空间太小了~~解决了
/*
 * 停车场管理
 * author:whocares
 * date:20101125
  */
#include<stdio.h>
#include<iostream>
using namespace std;
#include<malloc.h>
const int ParkingAreaSize=2;         //停车场位置数
const int DetourLength=100;			//便道位置数
const int Price=10;
#define ERROR 0;
#define OK 1;
#define OVERFLOW -1;
typedef int Status;
/*
-----------------------停车场定义-------------------------
*/
typedef struct CarInfo{
        int number;
	    int ar_time;
}CarInfo;
typedef struct{
           CarInfo  *base;    //停车场的堆栈底
           CarInfo  *top;    //停车场的堆栈顶
           int ParkingAreaSize_now ;
}ParkingArea;

//停车场操作;
Status InitStack(ParkingArea &L){
         L.base=(CarInfo*)malloc(ParkingAreaSize*sizeof(CarInfo));
         if(!L.base) return OVERFLOW;
         L.top=L.base;
         L.ParkingAreaSize_now=0;
         return OK;
       }

Status Push(ParkingArea &L,CarInfo e){
         *L.top++=e;
         L.ParkingAreaSize_now++;
		 return OK;
       }

Status Pop(ParkingArea &L,CarInfo &e){
        if(L.top==L.base) return ERROR;
        e=*--L.top;
        L.ParkingAreaSize_now--;
        return OK;
       }
Status DestoryStack(ParkingArea &L){
        free(L.base);
        return OK;
       }
/*
--------------------便道定义------------------
*/
typedef struct DetourCarInfo{
    int number;      //汽车车号
    int ar_time;      //汽车到达时间
    struct DetourCarInfo *next;
}DetourCarInfo,*DetourPtr;

typedef struct{
    DetourPtr front;    //便道的队列的对头
    DetourPtr rear;    //便道的队列的队尾
    int DetourLength_now;
}Detour;

//便道操作;
Status InitDetour(Detour &d){
        d.front=d.rear=(DetourPtr)malloc(sizeof(DetourCarInfo)); //这里第一次把DetourCarInfo 写成CarInfo 造成分配空间小的悲剧了
        if(!d.front) return OVERFLOW;
        d.rear->next=NULL;
        d.DetourLength_now=0;
        return OK;
       }
Status EnDetour(Detour &d,CarInfo c){//便道,车辆信息
        DetourPtr p;
        p=(DetourPtr)malloc(sizeof(DetourCarInfo));
        if(!p) return OVERFLOW;
        p->ar_time=c.ar_time;
        p->number=c.number;
        p->next=NULL;
        d.rear->next=p;
        d.rear=p;
        d.DetourLength_now++;
        return OK;
       }
Status PopDetour(Detour &d,CarInfo &c){
        DetourPtr dp;
        if(d.rear==d.front){
           cout<<"*|便道为空!"<<endl;
           return OK;
           }
        dp=d.front->next;
        c.ar_time=dp->ar_time;
        c.number=dp->number;
        d.front->next=d.front->next->next;
        if(d.rear==dp)d.rear=d.front;//如果出便道的是最后一辆车,特殊处理下rear
		free(dp);
		d.DetourLength_now--;
		return OK;
       }

void CarIn(ParkingArea &p,Detour &d,CarInfo c){//停车场,车辆信息
    if(p.ParkingAreaSize_now<ParkingAreaSize){
       Push(p,c);
       cout<< "*|车牌号为"<<c.number<<"的车进入停车场,停在 "<<p.ParkingAreaSize_now<<" 号停车位!"<<endl<<endl;
    }else{
       EnDetour(d,c);
       cout<<"*|停车场已满,车牌号为"<<c.number<<"先停在便道的第"<<d.DetourLength_now<<"个位置上"<<endl<<endl;
     }

}


void CarLeave(ParkingArea &p,ParkingArea &temp,Detour &d,CarInfo c){ //停车场,倒车,便道,离开车的信息
    int cost,time_now;
    time_now=c.ar_time;//当前时间保存
    if(p.ParkingAreaSize_now==0){cout<<"没车了,还离开?"<<endl;return;}
    while(p.top->number!=c.number&&(p.top!=p.base)){//第二次看的生活发现这里有个问题。。思维有点混乱了,要需要的话自己改下吧,不花多少时间
           Pop(p,c);
           Push(temp,c);
         }
    Pop(p,c);
    cost=Price*(time_now-c.ar_time);
    cout<<"*|车牌号为";
    cout<<c.number;
    cout<<"的车离开停车场,离开时间: ";
    cout<<time_now;
    cout<<",在停车场停留时间为:";
    cout<<time_now-c.ar_time;
    cout<<"收费:";
    cout<<cost;
    cout<<"元"<<endl<<endl;
    while(temp.ParkingAreaSize_now){
          Pop(temp,c);
          Push(p,c);
          }
    if((p.ParkingAreaSize_now<ParkingAreaSize)&&(d.DetourLength_now>0)){
         PopDetour(d,c);
         c.ar_time=time_now;
         Push(p,c);
         cout<<"停车场有空位,车牌号为:"<<c.number<<"的车由便道进入"<<p.ParkingAreaSize_now<<"号车道。"<<endl;
         }
}

int main()
    {
     char action;
     CarInfo c;
     ParkingArea parkingAreaInstance,temp;
     Detour   line;
     InitStack(parkingAreaInstance);
     InitStack(temp);
     InitDetour(line);
     while(1)
         {
         cout<<endl;
         cout<<"           --停车场管理系统-- CODE BY WHOCARESU    "<<endl;
         cout<<"---------------------------------------------------"<<endl;
         cout<<"|     A-到达         D-离开        E-退出         |"<<endl;
         cout<<"|                                                 |"<<endl;
         cout<<"|     示例:A:牌号为1的车于5点到达:A 1 5         |"<<endl;
         cout<<"|           D:牌号为1的车于7点离开:D 1 5         |"<<endl;
         cout<<"---------------------------------------------------"<<endl;
         cout<<" 请输入信息: ";
         cin>>action;
         cout<<endl;
         action=toupper(action);
         switch(action)
             {
              case 'A':
                    cin>>c.number>>c.ar_time;
                    CarIn(parkingAreaInstance,line,c);break;        //汽车进车场
              case 'D':
                   cin>>c.number>>c.ar_time;
                   CarLeave(parkingAreaInstance,temp,line,c);break; //汽车出车场
              case 'E':
                    return 0;
              default:
                    cout<<"*|操作码有误,请重新输入!"<<endl;
                    break;
            }
        }
}



青蛙有那么蠢吗?

青蛙有那么蠢吗?

   ——另一个“温水煮青蛙”的故事

         时寒冰

 

    “温水煮青蛙”的著名故事,被很多人引用过。大意是这样的:将

青蛙投入已经煮沸的开水中时,青蛙因受不了突而其来的的高温刺激立即奋力从开水中跳出来得以成功逃生。同样是水煮青蛙实验,把青蛙先放入装着冷水的容器

中,然后再加热。结果就不一样了。青蛙反倒因为开始时水温的舒适而水中中悠然自得。直至发现无法忍高温时,已经心有余而力不足了。被活生生的在热水中热

死。

    青蛙真的有那么蠢吗?

    上个世纪九十年代,北京一位女生物老师,组织全班同学做了一次这样的实验(我认识的一位朋友正好在这个班):

同学们两三位一组,分配一个容器和一只青蛙,文火加热,使水温缓缓升高,以符合“温水煮青蛙”的基本条件。同学们激动而焦急地看着显示水温的温度计和容器

中的青蛙。当温度缓步升到60度时,开始有青蛙跳出。水温到65度的时候,所有容器中的青蛙一个不拉地全部跳出来了。

    女生物老师说:“青

蛙在水温升到60多度后自动跳走,说明它对水温的本能反应并不因为温度变化的快慢而存在大的差异。它们没有蠢到被煮死而不逃离的地步。你们要记住,即便所

有人都认同并且经常说的道理,也可能是错的。那些被社会普遍认定的真理,也可能是谎言。凡事一定要经过亲自实验、调查、思考,不要人云亦云。”

    那位朋友告诉我说:“那次实验改变了他一生,让他懂得理性思考是何等的重要。”

    女生物老师证明了青蛙没有那么蠢,她却忽略了,人却可以蠢到不可思议的程度。学校对她组织的“温水煮青蛙”实验表示了极大的愤怒,因为,这种实验并非教学中安排的内容,与学生的分数没有任何关系。老师据理力争,反而埋下更大隐患,后来学校找借口把她辞退了。

    那位朋友说,他从此再也没有见过这位可敬的老师,他曾经去打听过,也没有结果。

    这是我听到的与众不同的“温水煮青蛙”的故事。我没有去做过类似的实验,但那位朋友讲起此事的眼神,让我相信,他曾经被这个实验震撼,并被老师的话打动。

    如果中国的教育环境,赞赏并鼓励这位老师的教学方式,带出来的孩子,将来该是何等的优秀?孩子们那么喜欢和认同她的教学方式,却不能改变她被逐出校园的命运。

    后来,我无意中与一位外国朋友谈起此事,问他对“温水煮青蛙”怎么看?他耸耸肩,抱歉说从未听说过这个原理,但说会请教做过实验的专家。哦,原来,在我们这里几乎人尽皆知的“温水煮青蛙”故事,并非全球流行。

    “温水煮青蛙”的不难做,但所有的人宁肯直接引用“温水煮青蛙”典故去论证从量变到质变的顺理成章,也不愿意去做任何一点质疑,也包括我自己,至少在听到这个故事以前,我和人们一起认为,青蛙就是那么蠢。

    “温水煮青蛙”的后续故事让我思索了很久。

 

这何尝不是我们这个社会的弊端呢?谎言重复一千遍,所有的人都认为谎言是真理,而与谎言不一样的说法就是荒谬绝伦。或者,几个人凑到一起,为某个说法到底

是真理还是谎言论战得面红耳赤,却没有一个人去实验,让事实说话。人们觉得做实验是浪费时间,是一种愚蠢的行为,而无聊地无休止地争论却是一种享受。

 

中国人更推崇小聪明,即便在决策上,亦显现出这一特征。因为,决策者也是在这样的土壤中长大的。当外国人生产的计算机越来越先进而价格越来越低的时候,我

不知道,我们的决策者是不是在因为中国质量低劣寿命短暂的房屋价格越来越高而喜不自胜,笑到裤子掉到地上还浑然不觉。相比之下,外国人多蠢哪!竟然连在民

生领域敛财易如反掌这样简单的道理都不懂得!

 

电影《阿甘正传》对我的影响非常大,他让我感悟到,人是聪明绝不在投机取巧的技能方面,而在于脚踏实地,在于善良、勤奋、认真、守信和对正义、真理的执著

追求和坚守。后来,我自己也接触到几位像阿甘那样的外国人,他们是那么简单、善良、热心助人。我弟弟在大学时的英语老师,是一位70岁的美国老太太,她的

收入大都用于资助中国贫困孩子上学,暑期的时候她专门去打工,以挣点钱资助更多的孩子读书。2002年的时候,十几位美国朋友在河南资助因为疾病等原因被

遗弃的孤儿,我受报社委派做了一个星期的采访调查,我被那种纯粹的爱心和奉献精神深深打动。他们是那么简单、善良、执著和热心助人。

    虽然我对美国金融集团对外的掠夺和美国政府的一些做法表示愤怒,但是,简单、善良、执著、爱心、奉献精神,却是美国公民社会的主流。这种精神面貌不断激发一个民族勃勃生机,推动它的进步和发展。从那时起,我开始学会分开去看待他们,从不同角度去看人事物。

 

在全球化日益深入的今天,在全球普遍面临资源短缺的今天,国家、民族之间的利益博弈将变得日益激烈,要想真正胜出,就必须靠一个有着良好精神面貌、积极向

上,有着爱心公心、奉献精神、实干精神的公民社会,就必须靠良好机制让优秀人才脱颖而出,由他们而不是由虚伪的政客去与强敌博弈。

 

因为愚蠢或者自私,或者所谓的公仆背叛而在国家利益竞争中处于被动地位的国家,其公众不应该是简单地对强敌充满仇恨,而应该认真反省自身,清算恶化民生、

出卖民族利益者,推动自身制度的进步和完善,通过制度体系的重建,激发起一个民族的不竭动力。与美国的博弈同样如此。我不觉得美国政府或者华尔街的利益集

团有多么深不可测,有多么聪明(他们的行为目的和方式是可以推导、把握的)——中国与美国的竞争败在机制上,中国的机制首先就将大量优秀人才排斥在外,而

留下很多深谙耍弄权术和演技超群之徒与美国的专家团打拼,这些政治演员在与强敌的博弈中娇喘吁吁、气若柔丝,不堪一击是必然的,结局也是必然的。

    我想强调的是,极端的仇视往往容易忽略自身的问题,只有当自身的问题得以修正,我们才能真正发现强敌的软肋,并在竞争中,改变被动局面,甚至在一些方面占据主动或者上风。

    这个“温水煮青蛙”的故事,感染我多年,忍不住写下了上面的话。

           2010年8月10日   

 

以上内容摘自:– 青蛙有那么蠢吗?——另一个“温水煮青蛙”的故事-时寒冰-搜狐博客 –