c#|面试题及答案_Java


  1. 1.java与C#相比,Java的优势在哪里?

答案
1, 比c# 难入门些,提高了档次
2,同样的功能,要写的代码比c#多些,软件的价值更高些
3,同2,要多写些代码, 锻炼了编程能力
4,框架多多,有机会选择,同时锻炼了你“学会选择”的能力
5,开源,降低软件发布的成本
[wm1]

  1. 2.struts运作过程,hibernate的作用?
答案
1)客户端发送来的请求,由ActionServlet接收,转发给RequestProcessor类,这个类负责读配置文件,把请求中的值付给ActionForm,并调用Action处理.Action处理完后,返回映射,跳转到响应页面.
2)Hibernate做数据持久化的架构.

  1. 3.说一说Struts或MVC?
答案
1)Struts实现了mvc模式.其中,自定义标签和ActionForm实现了视图层,ActionServlet,struts-Config.xml,action,RequestProcessor类实现了控制器.JavaBean实现了业务逻辑层.


  1. 4.怎么使用javascript进行页面跳转?
答案
1、location.href="https://www.it610.com/article/a.jsp"
2、window.location='a.jsp'

  1. 5.如果在一个try里面有return的时候,会不会执行finally里面的东西,如果执行是在return 后面执行还是什么时候执行?
答案
finally会执行,在return 前执行.

  1. 6.equals和==的区别?
答案
equals指的是两个对象相等
==指对象有value相等

  1. 7.J2EE是平台还是框架?
答案
是平台

  1. 8.ILoginDAO,UserDaolmp1,BLLFactory,MemberBLL从命名上看,以你的理解,写出这四个类(接口)的作用?
答案
ILoginDAO数据库增删改查的接口
UserDaolmp1数据库增删改查的实现类
BLLFactory工厂类
MemberBL业务逻辑类


  1. 9.Math.round(25.5)反回多少?Math.round(-25.5)反回多少?
答案
Math.round(25.5)返回26
Math.round(-25.5)返回-26

  1. 10.List、Map、Set按存储方式说说都是怎么存储的?
答案
List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set容器中。它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用类:Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。

Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性; 如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。Map有两种比较常用的实现:HashMap和TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。


  1. 11.说明一下final,finally,finalize的用法?
答案
final修饰符(关键字),如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。方法的参数被final修饰表示在方法体内,该参数的值不可以被修改。

private final String ss = "ss";

public final void m(){

}
public String m2(final String param){

}
finally在异常处理时提供finally块来执行任何清除操作。无论有没有异常被抛出、捕捉,finally块都会被执行。

finalize是方法名。Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

  1. 12.程序部署在tomcat,weblogic那个目录里?
答案
1)webapps

  1. 13.JSP有那些动作元素?
答案





















  1. 14.include与forward,请求转发和重定向的区别?
答案
include包含
forward跳转

  1. 15.JAVA的11个特点?
答案
Java语言有下面一些特点 :简单、面向对象、分布式、解释执行、鲁棒、 安全、体系结构中立、可移植、高性能、多线程以及动态性。
:1.简单性
Java语言是一种面向对象的语言 ,它通过提供最基本的方法来完成指定的任务 ,只需理解一些基本的概念 ,就可以用它编写出适合于各种情况的应用程序。 Java略去了运算符重载、多重继承等模糊的概念 ,并且通过实现自动垃圾收集大大简化了程序设计者的内存管理工作。另外 ,Java也适合于在小型机上运行 ,它的基本解释器及类的支持只有 40KB左右 ,加上标准类库和线程的支持也只有 215KB左右。库和线程的支持也只有 215KB左右。
2.面向对象
Java语言的设计集中于对象及其接口 ,它提供了简单的类机制以及动态的
接口模型。对象中封装了它的状态变量以及相应的方法 ,实现了模块化和信息隐藏 ; 而类则提供了一类对象的原型 ,并且通过继承机制 ,子类可以使用父类所提供的方法 ,实现了代码的复用。
3.分布性
Java是面向网络的语言。通过它提供的类库可以处理 TCP/IP协议 ,用户
可以通过 URL地址在网络上很方便地访问其它对象。
4.鲁棒性
Java在编译和运行程序时 ,都要对可能出现的问题进行检查 ,以消除错误
的产生。它提供自动垃圾收集来进行内存管理 ,防止程序员在管理内存时容易产生的错误。通过集成的面向对象的例外处理机制 ,在编译时,Java提示出可能出现但未被处理的例外 ,帮助程序员正确地进行选择以防止系统的崩溃。另外, Java在编译时还可捕获类型声明中的许多常见错误 ,防止动态运行时不匹配问题的出现。
5.安全性
用于网络、分布环境下的 Java必须要防止病毒的入侵。 Java不支持指针,
一切对内存的访问都必须通过对象的实例变量来实现 ,这样就防止程序员使用"特洛伊 "木马等欺骗手段访问对象的私有成员 ,同时也避免了指针操作中容易产生的错误。
6.体系结构中立
Java解释器生成与体系结构无关的字节码指令 ,只要安装了 Java运行时系统 ,Java程序就可在任意的处理器上运行。这些字节码指令对应于 Java虚拟机中的表示 ,Java解释器得到字节码后 ,对它进行转换 ,使之能够在不同的平台运行。
7.可移植性
与平台无关的特性使 Java程序可以方便地被移植到网络上的不同机器。同时 ,Java的类库中也实现了与不同平台的接口 ,使这些类库可以移植。另外, Java编译器是由 Java语言实现的 ,Java运行时系统由标准 C实现 ,这使得Java系统本身也具有可移植性。
8.解释执行
Java解释器直接对 Java字节码进行解释执行。字节码本身携带了许多编译时信息 ,使得连接过程更加简单。
9.高性能
和其它解释执行的语言如 BASIC、 TCL不同 ,Java字节码的设计使之能
很容易地直接转换成对应于特定CPU的机器码 ,从而得到较高的性能。
10.多线程
多线程机制使应用程序能够并行执行 ,而且同步机制保证了对共享数据的正确操作。通过使用 多线程 ,程序设计者可以分别用不同的线程完成特定的行为 ,而不需要采用全局的事件循环机制 ,这样就很容易地实现网络上的实时交互行为。
11.动态性
Java的设计使它适合于一个不断发展的环境。在类库中可以自由地加入新的方法和实例变量而不会影响用户程序的执行。并且 Java通过接口来支持多重继承 ,使之比严格的类继承具有更灵活的方式和扩展性。

  1. 16.Hibernate中了lazy,inverse,fetch,cascade作用跟意义?
答案
表示对主表操作是否会关连到子表

  1. 17.JSP的内置对象?
答案
request:
该对象封装了用户提交的信息,通过调用该对象相应的方法可以获取封装的信息,既使用该对象可以获取用户提交的信息。
当Request对象获取客户提交的汉字字符时,会出现乱码问题,必须进行特殊处理。首先,将获取的字符串用ISO-8859-1进行编码,并将编码存发到一个字节数组中,然后再将这个数组转化为字符串对象即可。
例:
String textContent=request.getParameter("boy");
byte b[]=textContent.getBytes("ISO-8859-1");
textContent=new String(b);
request常用的方法:
※getParameter(String strTextName) 获取表单提交的信息。
例:String strName=request.getParameter("name");
※getProtocol() 获取客户使用的协议。
例:String strProtocol=request.getProtocol();
※getServletPath() 获取客户提交信息的页面。
例:String strServlet=request.getServletPath();
※getMethod() 获取客户提交信息的方式。
※getHeade() 获取HTTP头文件中的accept、accept-encoding和Host的值。
例 String strHeade=request.getHeader("accept");
※getRermoteAddr() 获取客户的IP地址。
※getRemoteHost() 获取客户机的名称。
※getServerName() 获取服务器名称。
※getServerPort() 获取服务器的端口号。
※getParameterNames() 获取客户端提交的所有参数的名字。
************
1.2:Response
************
对客户端发出的请求作出动态的响应,向客户端发送数据
※setContentType() 动态响应页面用page指令设置的contentType属性
例:response.setContentType(String strCT);
注:参数strCT可取"text/html","application/x-msexcel","application/msword"等。
※sendRedirect() 实现客户的重定向
例:response.sendRedirect(strURL);
************
1.3:Session
************
JSP页面被装载时自动创建,完成会话期管理。
※public String getId() 获取Session对象编号
※public void setAttribute(String key,Object objS)将参数Object指定的对象obj添加岛Session对象
※public Object getAttribute(String key) 获取Session对象中含有关键字的对象。
※public Boolean isNew() 判断是否时一个新的客户。
************
1.4:Application
************
服务器启动后就产生了Application对象,一直到服务器关闭,所有的客户端共享这个内置的Application对象。
※setAttribute(String key,Object objA)将参数objA添加到Application对象中
※getAttribute(String key)获取指定关键字Application对象中对象。
************
1.5:Out
************
一个输出流,用来向客户端输出数据。
※out.ptint() 输出各种类型数据
※out.newLine() 输出一个换行符
※out.close() 关闭流
************
1.6:Cookie
************
Cookie是Web服务器保存在客户端的一段文本信息,并且允许Web服务器在以后的客户端访问时取回它是以“关键字key=值value”格式存储的。
※Cookie("userName","john") 构造函数,创建Cookie对象。
※response.addCookie(cookie) 将Cookie对象传送到客户端
※request.getCookies() 获取保存到客户端的Cookie对象数组。
例: Cookie[] cookieArray= request.getcookies();
if(null!=cookieArray)
for(int i=0; i< cookieArray.length; i++)
if("userName".equale(cookieArray[i].getName()))
out.prinln(cookieArray[i].getValue());
※setMaxAge(intTime) 设置Cookie对象的有效时间,intTime为时间
************
1.7:pageContext
************
页面上下文对象
************
1.8:Config
************
配置对象
************
1.9:Page
************
页面对象
************
1.10:Exception
************
例外对象

  1. 18.在jbuilder和eclipse中make 和 rebuilder 有什么区别?如何编译和运行java文件?
答案
make会把所有的类重新编译一遍.rebuilder则是把所有的.class文件删除,再把所有的类重新编译一遍

  1. 19.手写一个表单内容包括 ‘用户名 text’ ‘年龄 text’ ‘性别 单选 默认没有选中’ ‘提交按钮’ ‘重置按钮’
答案







  1. 20.手写一个表格, 第一行2列, 第二行1列
答案







12
合并


  1. 21.有两个字符串变量Atr与Btr,写出这两个字符串变量如何判断它们的内容相等
答案
1)Atr == Btr
2)Atr.Equals(Btr)

  1. 写出几个Java编程中最常用的类、接口、包?
答案
java.lang.*;
java.util.*;
String Math

  1. request都有哪些方法
答案
java.lang.StringgetPathInfo()
HttpSessiongetSession()
java.lang.String getParameter()
java.lang.Object getAttribute()

  1. response在什么时候用
答案
当跳转到的资源不需要请求中信息的时候可以用response.sendRedirect()跳转.
当中文处理时


  1. Vector与ArrayList区别
答案
Vector : 基于Array的List,其实就是封装了Array所不具备的一些功能方便我们使用,它不可能走出Array的限制。性能也就不可能超越Array。所以,在可能的情况下,我们要多运用Array。另外很重要的一点就是Vector是“sychronized”的,这个也是Vector和ArrayList的唯一的区别。
ArrayList:同Vector一样是一个基于Array上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。

  1. JavaScript与JAVA的区别?(从它们的解释,运行等方面说)
答案
1.基于对象和面向对象
Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象。JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object Based)和事件驱动(Event Driver)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用。
2.解释和编译
两种语言在其浏览器中所执行的方式不一样。Java的源代码在传递到客户端执行之前,必须经过编译,因而客户端上必须具有相应平台上的仿真器或解释器,它可以通过编译器或解释器实现独立于某个特定的平台编译代码的束缚。
JavaScript是一种解释性编程语言,其源代码在发往客户端执行之前不需经过编译,而是将文本格式的字符代码发送给客户编由浏览器解释执行。
3.强变量和弱变量
两种语言所采取的变量是不一样的。Java采用强类型变量检查,即所有变量在编译之前必须作声明。如:
Integer x;
String y;
x=1234;
x=4321;
其中X=1234说明是一个整数,Y=4321说明是一个字符串。JavaScript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是解释器在运行时检查其数据类型,如:
x=1234;
y="4321";
前者说明x为其数值型变量,而后者说明y为字符型变量。
4.代码格式不一样
Java是一种与HTML无关的格式,必须通过像HTML中引用外媒体那么进行装载,其代码以字节代码的形式保存在独立的文档中。JavaScript的代码是一种文本字符格式,可以直接嵌入HTML文档中,并且可动态装载。编写HTML文档就像编辑文本文件一样方便。
5.嵌入方式不一样
 在HTML文档中,两种编程语言的标识不同,JavaScript使用来标识,而Java使用...来标识。
6.静态联编和动态联编
Java采用静态联编,即Java的对象引用必须在编译时的进行,以使编译器能够实现强类型检查。JavaScript采用动态联编,即JavaScript的对象引用在运行时进行检查,如不经编译则就无法实现对象引用的检查。

  1. 怎么使用javascript将一个页面的一个参数传递到另外一个页面?
答案
function getparastr(strname)
{
var hrefstr,pos,parastr,para,tempstr;
hrefstr = window.location.href;
pos = hrefstr.indexOf("?")
parastr = hrefstr.substring(pos+1);
para = parastr.split("&");
tempstr="";
for(i=0; i{
tempstr = para[i];
pos = tempstr.indexOf("=");
if(tempstr.substring(0,pos) == strname)
{
return tempstr.substring(pos+1);
}
}
return null;
}
// 获取program参数
var programstr = getparastr("program");
document.write(programstr);

  1. 使用存储过程进行分页,页面使用javascript分页
答案
ALTER PROCEDURE [dbo].[SelectTeacher]
@startIndex int,
@pagesize int
AS
BEGIN
WITH teacherList AS (
select ROW_NUMBER() OVER (ORDER BY teacher_id asc)AS Row,* from teacher
)
select teacher_id,teacher_name from teacherList where Row between @startIndex and @startIndex+@pageSize-1
END

  1. ORM的原理是什么?
答案
ORM的全称是Object Relational Mapping,即对象关系映射。它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作。因此它的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。

  1. string和stringBuffer区别
答案
StringBuffer是可变的而String是不可变的.
而且String用得多个的话会占用不同的内存.
如:String str = "bb";
str = "aa";
前一个bb的内存地址不变,当又给它赋值为aa时它又指向aa的地址.
而StringBuffer就不会这样.

  1. 如果在一个try里面有return的时候,会不会执行finally里面的东西,如果执行是在return 后面执行还是什么时候执行?
答案
会执行
Return之后执行

  1. 在浏览器的菜单高级里面把cookie设置成高级的时候,限制用户访问,这时候session还会起作用吗?如果客户端还是想访问的话,应该采取什么方法?
答案
起作用
通过Url保持Session ID

  1. MVC各部分都由什么技术实现?怎么实现?
答案
M 由JAVABEAN实现
V 由JSP实现
C 由Servlet实现
[wm1]作者:
这世界上没有什么比编程工具更加牵动程序员的心。VC、VB、DELPHI、JAVA……这些耀眼的名字不仅占据了程序员的生活,而且似乎已经成为了某种信仰。可是,伴随着新世纪的脚步,这些信仰又一次遭遇了重大的挑战。微软,这头被法官和黑客们折腾得既疲惫又恼怒的狮子,发誓要保住它头上的王冠,拼尽全力,拿出了看家的本事——.NET战略。作为 .NET的核心开发语言,C# 顺理成章地浮出了水面。程序员们也就不得不做出一个痛苦的选择,跟在谁的后面?要找出答案就不得不作一番比较和预测。笔者作为一个资深的程序员,斗胆在此狂言,权作抛砖引玉。

如果抛开一切非技术方面的因素,C# 无疑是这个星球上有史以来最好的编程语言,它几乎集中了所有关于软件开发和软件工程研究的最新成果。面向对象、类型安全、组件技术、自动内存管理、跨平台异常处理、版本控制、代码安全管理……你不可能在另外的一种语言中找到所有这些特性。尽管像很多人注意到的一样,当我罗列上述特性时,总是让人想到JAVA,然而C# 确实走得更远。但现实的情况是,非技术的因素往往更能决定一个产品的未来,尤其在计算机软件的历史上,技术卓越的产品,如OS/2、Mac OS、UNIX等,都败在了Windows那漂亮的脸蛋儿下。而这一次,微软的角色好像从一个赤手空拳的革命者变成了仗势欺人的老地主,如果真是要变天,那C# 这孩子岂不是投错了胎?可能情形并非如此糟糕,毕竟瘦死的骆驼比马大,而且C# 已经提交给了一个标准化组织,一旦成了国际标准,说不准真有哪个手痒的大侠(也有可能是微软自己)给移植到Linux 和别的平台上。那样的话,JAVA可就惨了。因为JAVA的用户主要是网络服务的开发者和嵌入式设备软件的开发者,嵌入式设备软件不是C# 的用武之地,而在网络服务方面,C# 的即时编译和本地代码Cache方案比JAVA虚拟机具有绝对的性能优势。何况C# 一旦成为一个像C++ 一样的公共的标准,软件开发商既可以省去JAVA的许可证费用,也不必担心成为微软的奴隶,那些反微软的人士和主张厂商独立的人士可能也不会有什么意见。这可能正是微软所期待的。

如果把C# 和 JAVA 在网络服务领域的争夺比作未来制空权的争夺的话,那么C# 和传统通用快速开发工具——VB、DELPHI等的较量将是地地道道的白刃战。可能最惨的程序员就是VB程序员,在微软,VB就像离任的克林顿,不但失去了所有的光辉,而且乱事缠身。想想吧,VB6写的项目必须用转换工具转换成基于.NET的代码才能在VB7中调入,几乎面目全非。由于VB7遵循为迎合.NET而建立的通用语言规范(CLS),几乎把所有原来只在C++、JAVA等语言中可以运用的特性统统加了进来,只是语法和原来兼容。如果你是第一次在VB7中看到自己的旧VB6项目转换之后的代码,一定要当心你的心脏!所以,努力吧,别告诉我你将就此退休。DELPHI的状况也好不到哪里去,原来的看家本领是做起应用来又快又好,可现在看看最新的VS.NET Beta 1, 你会感到如此熟悉,众多的属性列表、组件……谁让你穷呢,连总设计师都养不住。

其实在编程语言中真正的霸主多年来一直是C++,所有的操作系统和绝大多数的商品软件都是用C++作为主要开发语言的。JAVA的程序员绝大多数也是C++的爱好者,PHP的成功里面也有类似C++的语法的功劳。在操作系统、设备驱动程序、视频游戏等领域,C++在很长的时间内仍将占据主要地位,而在数量最大的应用软件的开发上,C# 很可能取代C++的位置。首先,C# 和JAVA一样,简直就是照搬了C++的部分语法,因此,对于数量众多的C++程序员学习起来很容易上手,另外,对于新手来说,比C++要简单一些。其次,Windows是目前占垄断地位的平台,而开发Windows应用,当然微软的声音是不能忽略的。最重要的是,相对于C++,用C# 开发应用软件可以大大缩短开发周期,同时可以利用原来除用户界面代码之外的C++代码。

但是,C# 也有弱点。首先,在大量的现有Windows平台上,C# 的程序还不能运行,因为C# 程序需要 .NET运行库作为基础,而 .NET运行库将作为新一代的Windows(Whistler)的一部分发行, 或以Service Pack的形式提交给Windows Me 和 Windows 2000用户。所以在近期,C# 会主要在服务器上得到应用。其次,C# 能够使用的组件或库还只有 .NET 运行库等很少的选择,没有丰富的第三方软件库可用,这需要有一个过程,同时各软件开发商的支持也很重要。第三,JAVA的成功因素里有一些是反微软阵营的吹捧,虽然“只写一次,到处运行”只是一句口号,但毕竟已经是一种成熟的技术。而C# 的鼓吹者目前只有名声不佳的微软,且只能运行在Windows上。实际上这两种语言都不是不可替代的,理智的说,对软件开发商而言,什么用的最熟什么就是最好的工具。尤其对C++的使用者,C# 没有带来任何新东西,因为.NET运行库在C++中也可以使用,没有要换的绝对的理由。

综上所述,我个人认为,近几年,C# 将不可避免地崛起,在Windows平台上成为主角,而JAVA将在UNIX、Linux等平台上成为霸主,C++ 将继续在系统软件领域大展拳脚。非常有意思的是,这些语言的语法极其接近,因为JAVA和C# 都是由C++发展而来的。其他的开发工具当然还会在相当长的时间里继续他们的旅程,不过在市场份额上,将不可避免地受到冲击。

C#和.net framework在Linux已经有实现了,只不过不叫.net 而叫 Mono




【c#|面试题及答案_Java】本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/archive/2010/12/19/1910674.html,如需转载请自行联系原作者

    推荐阅读