MVC是现在用的很多的设计模式之一,他很好的将业务逻辑和展示分开,让重构变得简单了很多,但我发现很多人对MVC有误解
V:view这个很好理解,就是展示数据用的,但对于M和C就不好理解了
最初我以为M:model就是单纯的数据C:controller就是业务逻辑,但后来发现错了,model不是单纯的数据
引用Struts2 in action中的解释,其实模型是应用程序的内部状态,这个状态由数据模型和业务逻辑共同组成,而Controller是决定请求映射到那个动作,从而返回模型,最后模型在view中展现
就拿Struts来取例子,filterDispatcher就应该是控制器的角色,他决定你的请求触发哪个动作,而Action和数据共同组成了模型,一个模型可以对应不同的view,比如一个User对象在一个view中只展现usernam,而在另一个view中展现username和age
而连接MVC的东西就是数据,数据贯穿了整个MVC,而数据的传递与转化就是问题了,struts2的ognl很好的解决了这个问题!
这就是个人的理解,如果有错误欢迎指出!
1.浏览器的请求方式
浏览器的请求方式有很多,最典型的就是get和post方式,但你是否知道其实还有几种方式,只是我们不经常用!options,head,put,delete,trace,至于为什么现在不经常用这些方式,我想是因为get和post就可以满足我们大多数的需求吧!
2.get和post的区别
这个问题似乎大家讨论了很久,而且面试题中也时常出现这类题,但他们的最大区别到底在哪里呢
其实最主要的区别在于
get 请求用于从服务器获取信息
post请求用于改变服务器的状态
当然还有其他的不同
(1) get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到
post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址
(2)get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制
(3)post的安全性比get高?有些人认为应为get方式请求时因为数据是加载url后面的,所以安全性不高,但其实很多工具都可以看,如firebug,所以安全性是相对的。
3.什么时候用get,什么时候用post
这就是根据他们的最大的区别来使用了
这里有一个概念叫idempotent(幂等),对于单目运算,如果一个运算对于在范围内的所有的一个数多次进行该运算所得的结果和进行一次该运算所得的结果是一样的,那么我们就称该运算是幂等的。如abs运算就是幂等的
对于一个请求,在服务器端没有变化的情况下,相同的请求不管请求多少次,得到的数据应该是相同的,这就是幂等的,也就要用get方式,一般就是用于向服务求获取数据。当你要改变服务器状态的时候,比如对数据库进行增删改操作时,你就应该用post方式了
4.乱使用get和post的后果
其实现在互联网里的很多网站都没有遵循使用规范,乱用get和post,比如用<a>标签请求一个action,达到修改服务器状态的目标,因为他们没有意识到危险
直到2005年google发布了GWA(google web accelerator),这个工具是一个客户端代码,他会预先扫描用户浏览的的页面,找出其中的连接,并读取连接后面的页面并缓存,从而达到提高浏览页面速度的目的
也许你现在想到了,但我们用<a>标签的时候,如果用于请求一个action改变服务求状态的时候,那就太糟糕了,gwa会请求所有<a>标签,然后请求action!比如一个购物网站。用一个<a>的连接来把物品加入购物车,那当用户访问的时候,GWA会把所有的物品加入你的购物车
5 建议
(1).使用表单和按钮(非超链接)来执行会改变服务器状态的操作,表单用post提交
(2).使用确认页面
其实最核心的一个就是:把所有具有破坏性的action放在一个post请求的后面
put all destructive actions behind a post request
如有错误欢迎指正!
rails generate controller home index 2.修改/views/home/index.html.erb 改为熟悉的<h1>Hello, Rails!</h1> 3.删除public/index.html 4.修改config/routes.rb 找到这里修改
#...
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root :to => "home#index"
rails generate scaffold Post name:string title:string content:text创建一个Post的model,有name,title,content字段,后面是类型这条命令后,rails会创建重model,view,controler的所有东西(很强大啊)(7)想model maping到数据库中运行rake db:migrate成功后数据库就会有你指定的字段了,除了你指定的字段,rails还帮你创建id,创建时间和跟新时间的两个时间戳,还有一张vision表(应该记录版本的吧)(8)修改app/views/home/index.html.erb,为post的页面添加一个连接 <h1>Hello, Rails!</h1>
<%= link_to "My Blog", posts_path %>(9) 然后就是http://localhost:3000,点击mypost你就可以增删改查了至此 你的比hellword更强大的程序就ok了,你想一下如果熟悉的话你花多少时间?3分钟?2分钟?还是更少?其实rails的功能远远不止这些,什么校验啊,ajax啊,ormapping ...........等等自己去发现吧然后要介绍的就是rubyonrail的开发工具,其实自己愿意什么都可以,但最好用的我觉得还是rubymine 收费的,你说好用不,不过我有序列号,要的可以给我邮件evan8126@gmai.com!由于我也是初学,如果有什么错误请高手指正,如果有问题请留言,能解决的一定回复!Thanks因为在做的一个项目里用的是velocity,以前一直没用过,一直都是用的框架自带的标签,如struts2等,做了一段时间感觉差不多都一样的,无非就是if..else...,foreach等,但是网上说freemaker要强大的多,我也没用过,所以就没资格说那个好,但是用velocity有点让我不爽,velocity不能用索引访问数组,也就是访问数组不能用 list[i]这样访问,只能用foreach遍历整个数组,要控制访问的位置,就只能用velocity自带的关键字velocitycount来控制(我是这样解决的,不知道还有没有更好的办法),所以有点麻烦
最近出现的一个错误更是让我抓狂,在就在页面中进行加减运算
#set($size=$page*10-10)
总是报错,在页面上打印出来就是 30-10 ,在纠结了很久以后终于解决了,在这里写出来,一是为了提醒自己,二是为了大家以后遇到这个 错误不用抓狂了
在velocity中页面上的符号会自动调用tostring方法,所以我的page转化为了string,所以就没有进行计算,解决的办法就是再操作符的两边加一个空格也就是
#set($size=$page*10 - 10)
程序运行正确
就是两个空格,让我抓狂了那么久,特别是在最后知道只是因为两个空格的原因时,欲哭无泪啊,有木有啊,有木有......
java中存储数据的几种区域
1首先是Pcregister
他存储的的线程运行的地址,每个线程会有一个
2然后是栈
他提供一个线程运行的场所,每一个线程都有一个栈,他存放局部变量,中间结果和返回值
3堆
他存放所有jvm的对象(其实不是所有,有时候对象也存放在栈上),每一个jvm只有一个堆
4方法区
他存放clss的相关信息,如常量池、字段和方法的数据、方法和构造器的代码
你是否认为所有的基本类型都放在栈上,所有的对象都放在堆上?答案是否定的
类是放在堆上的,而且类里面的基本类型还是放在堆上的,而基本类型的局部变量才是放在栈上的
方法在执行的时候会有一个压栈的过程,每个压入的东西就做frame,他保存了方法执行时的数据,当方法返回的时候(不管是正常返回还是异常返回),他都会弹出栈,如果有返回值,他会把返回值在压入栈中。一个方法不一定只有一个栈,如递归调用,执行一次方法就会push一个frame,return就pop,直到最后一frame被pop
大家可以做一个实验,有这样一个类
public class Load {
public static int a=5;
public static final int b=5;
public Load()
{
}
static
{
System.out.println("im loaded");
}
public static void main(String[] args) {
System.out.println(Load.a);//对象会被加载
System.out.println(Load.b);//对象是不会加载的
}
为什么呢
类加载有这样一条规则,当对象的一个静态方法或静态域被访问的时候,类就会被加载,所以即使构造方法没有加static,他还是一个静态方法,类加载后,静态方法会被放在静态区里,那为什么第二条不会被加载呢,因为在javac后,System.out.println(Load.b);会被编译System.out.println(5);所以他不会加载
jvm要学习的东西真的很多,但对于做业务的人来说真的不是很有用,但重要的是兴趣,做一辈子java开发,不知道他到底怎么实现的会不会有点悲哀,呵呵
最后说明两个关键字
transient
当你的一个对象或字段申明为这个的时候,但序列化时,他将不被序列化,所以平时我们所说的没有加这个字段的单例不能算是真正的单例,因为序列化再反序列化,就会存在连个对象,所以要加transient
native
本地方法,我学习hashcode方法的时候有个疑问,当一个类没有覆盖hashcode方法时,他会调用父类的hashcode方法,也就是object的hashcode方法
,但object的hashcode方法没有任何方法体,但他确实返回了一个值,
public native int hashCode();
但他申明了native后,这个方法由更底层的语言去实现,如C或C++,我是这样理解的,这个方法就好像一个接口,然后由其他更底层的语言来实现这个方法
欢迎大家指正错误
最近在看java的中finalizer终结方法,也就是用来释放内存的,但这绝对和C++中的析构函数不相同
C++中的析构函数是用来回收对象所占用的资源的方法,而在java中,当一个对象不可到达时(也就是重堆栈和静态存储区开始,由引用开始,寻找实体对象),垃圾回收器会释放该对象所相关联的存储空间,并不需要程序员的编码
对于finalizer方法的使用,就只有一条建议--------------尽量不要使用
effective java中有这几个结论
1 不应该依赖终结方法来更新重要的持久状态
如用finalizer方法释放数据库上的永久锁,而且finalizer方法是不一定会被调用的,只有到了内存满了系统才会调用垃圾回收
2 使用终结方法有非常严重的性能损失
而且性能损失还有点大
但有两种情况下可以使用
1.当对象所有者忘记调用显示的终结方法(如connection,inputstream,outputstream的close方法和Timer中的cancel方法,这只是一种保险的方法
完全可以由程序员的细心避免的,所以使用这些类的时候千万要记住调用显示的终结方法
2本地对象 也就是其他语言编写的对象托管给java管理,当垃圾回收器回收java对象时,那些本地对象占用的资源是不会回收的,所以这里就需要调用对象的finalizer方法
在说说垃圾回收器
垃圾回收器是用来回收java中无用的对象,也就是不可到达对象,他有很多种机制
1 引用计数器
每一个对象都会用一小块存储空间来存放引用计数器,当对象被引用时,计数器加1,当对象失去引用或对象引用被置为null时减1,当垃圾回收器检测到对象的引用计数器为0时
垃圾回收器释放资源,大家也许会想到资源释放后那空间是不连续的,所以垃圾回收器还有整理空间的功能,让空间连续
ps:这里会有一个缺陷,当几个对象引用形成一个循环时,这些对象本来应该被释放的,但由于他的引用计数器不为0,所以垃圾回收器不会释放对象的内存资源
2停止-复制
垃圾回收器回重堆栈和静态存储区开始检查所有引用,当对象是可到达时,就会把可到达的所有对象复制到另外一块存储空间上,而不可到达的便成为垃圾,这种机制的效率是非常低的,因为他会先停止程序,然后执行复制操作,复制的同时还必修改所有引用.完成复制后,空间是连续的,所以就不需要整理。当垃圾(不可到达对象)很少时,这种机制是非常不划算的,所以有了下面的方法
3标记-清扫
速度想当面慢,但垃圾很少时相对于停止-复制是相当快的
从堆栈和静态存储区开始,遍历所有引用,找出存活(可到达)对象并标记,当标记完后开始清理任务,清理后空间是不连续的,所以垃圾回收器还必须整理
如果只用一种机制,是不灵活的
所以有了第4种机制
4自适应
对象很稳定时用标记-清扫
垃圾回收器跟踪标记清扫,当碎片很多的时候用停止-复制
如过你发现我有说的不对的地方,欢迎说出来大家一起分享
