首页 > 编程语言 >java基础知识精华总结 java面试题

java基础知识精华总结 java面试题

时间:2023-02-09 16:35:51浏览次数:80  
标签:面试题 加密 对象 基础知识 import java throws select


1、文件拷贝,把一个文件的内容拷贝到另外一个文件里

package order;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class FileInputOutputStreamTest {
public static void main(String[] args) {
File af = new File("F:/srv/workspace/test/src/a.txt");
File bf = new File("F:/srv/workspace/test/src/b.txt");
FileInputStream is = null;
FileOutputStream os = null;
if(!bf.exists()){
try {
bf.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
is = new FileInputStream(af);
os = new FileOutputStream(bf);
byte b[] = new byte[1024];
int len;
try {
len = is.read(b);
while (len != -1) {
os.write(b, 0, len);
len = is.read(b);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
if(is != null) is.close();
if(os != null) os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

java基础知识精华总结 java面试题  _客户端

————————————————————————————————————————————————————————————————————————————

2、jsp里边的对象,以及常用的方法

————————————————————————————————————————————————————————————————————————————

内置对象特点:

1.           由JSP规范提供,不用编写者实例化。

2.           通过Web容器实现和管理

3.           所有JSP页面均可使用

4.           只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%>或<%使用内置对象%>)

常用内置对象:

1. 输出输入对象:request对象、response对象、out对象

2.   通信控制对象:pageContext对象、session对象、application对象

3.   Servlet对象:page对象、config对象

4.    错误处理对象:exception对象

 

对象常用方法说明:

1.out对象(数据流 javax.servlet.jsp.jspWriter)

方法名

说明

print或println

输出数据

newLine

输出换行字符

flush

输出缓冲区数据

close

关闭输出流

clear

清除缓冲区中数据,但不输出到客户端

clearBuffer

清除缓冲区中数据,输出到客户端

getBufferSize

获得缓冲区大小

getRemaining

获得缓冲区中没有被占用的空间

isAutoFlush

是否为自动输出

2.request对象(请求信息 javax.servlet.http.HttpServletrequest)

方法名

说明

isUserInRole

判断认证后的用户是否属于某一成员组

getAttribute

获取指定属性的值,如该属性值不存在返回Null

getAttributeNames

获取所有属性名的集合

getCookies

获取所有Cookie对象

getCharacterEncoding

获取请求的字符编码方式

getContentLength

返回请求正文的长度,如不确定返回-1

getHeader

获取指定名字报头值

getHeaders

获取指定名字报头的所有值,一个枚举

getHeaderNames

获取所有报头的名字,一个枚举

getInputStream

返回请求输入流,获取请求中的数据

getMethod

获取客户端向​​服务器​​端传送数据的方法

getParameter

获取指定名字参数值

getParameterNames

获取所有参数的名字,一个枚举

getParameterValues

获取指定名字参数的所有值

getProtocol

获取客户端向​​服务器​​端传送数据的协议名称

getQueryString

获取以get方法向​​服务器​​传送的查询字符串

getRequestURI

获取发出请求字符串的URI标识(不含协议,主机,端口和参数)

getRequestURL

获取客户端请求的URL地址

getRemoteAddr

获取客户端的IP地址

getRemoteHost

获取客户端的名字

getSession

获取和请求相关的会话

getServerName

获取​​服务器​​的名字

getServerPath

获取客户端请求文件的路径

getServerPort

获取​​服务器​​的端口号

removeAttribute

删除请求中的一个属性

setAttribute

设置指定名字参数值

setCharacterEncoding

设置请求的字符编码方式


 

3.response对象(响应 javax.servlet.http.HttpServletResponse)

方法名

说明

addCookie

添加一个Cookie对象

addHeader

添加Http文件指定名字头信息

containsHeader

判断指定名字Http文件头信息是否存在

encodeURL

使用sessionid封装URL

flushBuffer

强制把当前缓冲区内容发送到客户端

getBufferSize

返回缓冲区大小

getCharacterEncoding

获取响应的字符编码方式

getOutputStream

返回到客户端的输出流对象

sendError

向客户端发送错误信息

sendRedirect

把响应发送到另一个位置进行处理

setContentType

设置响应的MIME类型

setCharacterEncoding

设置响应的字符编码方式

setHeader

设置指定名字的Http文件头信息

4.session对象(会话 javax.servlet.http.HttpSession)

方法名

说明

getAttribute

获取指定名字的属性

getAttributeNames

获取session中全部属性名字,一个枚举

getCreationTime

返回session的创建时间

getId

获取会话标识符

getLastAccessedTime

返回最后发送请求的时间

getMaxInactiveInterval

返回session对象的生存时间单位千分之一秒

invalidate

销毁session对象

isNew

每个请求是否会产生新的session对象

removeAttribute

删除指定名字的属性

setAttribute

设定指定名字的属性值

5.pageContext对象(页面上下文 javax.servlet.jsp.PageContext)

方法名

说明

forward

重定向到另一页面或Servlet组件

getAttribute

获取某范围中指定名字的属性值

findAttribute

按范围搜索指定名字的属性

removeAttribute

删除某范围中指定名字的属性

setAttribute

设定某范围中指定名字的属性值

getException

返回当前异常对象

getRequest

返回当前请求对象

getResponse

返回当前响应对象

getServletConfig

返回当前页面的ServletConfig对象

getServletContext

返回所有页面共享的ServletContext对象

getSession

返回当前页面的会话对象


 

6.application对象(应用程序 javax.servlet.ServletContext)

方法名

说明

getAttribute

获取应用对象中指定名字的属性值

getAttributeNames

获取应用对象中所有属性的名字,一个枚举

getInitParameter

返回应用对象中指定名字的初始参数值

getServletInfo

返回Servlet编译器中当前版本信息

setAttribute

设置应用对象中指定名字的属性值

removeAttribute

删除属性,根据键/值来删除application中所存放的对象值

7.config对象(Servlet的配置信息 javax.servlet.ServletConfig)

方法名

说明

getServletContext

返回所执行的Servlet的环境对象

getServletName

返回所执行的Servlet的名字

getInitParameter

返回指定名字的初始参数值

getInitParameterNames

返回该JSP中所有的初始参数名,一个枚举

8.page对象(当前JSP的实例,java.lang.object)

它代表JSP被编译成Servlet,可以使用它来调用Servlet类中所定义的方法

9.exception对象(运行时的异常,java.lang.Throwable)

被调用的错误页面的结果,只有在错误页面中才可使用,

即在页面指令中设置:<%@page isErrorPage=“true”%>

Request(Javax.servlet.ServletRequest)它包含了有关浏览器请求的信息.通过该对象可以获得请求中的头信息、Cookie和请求参数。

Response(Javax.servlet.ServletResponse)作为JSP页面处理结果返回给用户的响应存储在该对象中。并提供了设置响应内容、响应头以及重定向的方法(如cookies,头信息等)

Out(Javax.servlet.jsp.JspWriter)用于将内容写入JSP页面实例的输出流中,提供了几个方法使你能用于向浏览器回送输出结果。

pageContext(Javax.servlet.jsp.PageContext)描述了当前JSP页面的运行环境。可以返回JSP页面的其他隐式对象及其属性的访问,另外,它还实现将控制权从当前页面传输至其他页面的方法。

Session(javax.servlet.http.HttpSession)会话对象存储有关此会话的信息,也可以将属性赋给一个会话,每个属性都有名称和值。会话对象主要用于存储和检索属性值。

Application(javax.servle.ServletContext)存储了运行JSP页面的servlet以及在同一应用程序中的任何Web组件的上下文信息。

Page(Java.lang.Object)表示当前JSP页面的servlet实例

Config(javax.servlet.ServletConfig)该对象用于存取servlet实例的初始化参数。

Exception(Javax.lang.Throwable)在某个页面抛出异常时,将转发至JSP错误页面,提供此对象是为了在JSP中处理错误。只有在错误页面中才可使用


————————————————————————————————————————————————————————————————————————————


3、HashMap遍历的几种方法

————————————————————————————————————————————————————————————————————————————

第一种:
  Map map = new HashMap();
  Iterator iter = map.entrySet().iterator();
  while (iter.hasNext()) {
  Map.Entry entry = (Map.Entry) iter.next();
  Object key = entry.getKey();
  Object val = entry.getValue();
  }
  效率高,以后一定要使用此种方式!
第二种:
  Map map = new HashMap();
  Iterator iter = map.keySet().iterator();
  while (iter.hasNext()) {
  Object key = iter.next();
  Object val = map.get(key);
  }
  效率低,以后尽量少使用!

————————————————————————————————————————————————————————————————————————————


4、写一个类,连接数据库并执行一条sql

————————————————————————————————————————————————————————————————————————————


public class Student{//主方法
private String name ;
private String id;
public Student(String name,String id){
this.name=name;
this.id=id;
}

package ch03;

import java.sql.Connection;
import java.sql.DriverManager;


public class JDBConnection {
private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
private static final String DATABASE_URL = "jdbc:mysql://localhost:8080;databaseName=student";
private static final String DATABASE_USER = "localhost";
private static final String DATABASE_PASSWORD = "123456";

private Connection con = null;

public Connection getConnection() {
try {
Class.forName(DRIVER_CLASS);
con=DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
System.out.println("连接成功!");
} catch (Exception ex) {
System.out.println("2:"+ex.getMessage());
}
return con;
}
}
需要一个名字是student的数据库 用户名localhost 密码123456



二、SQL
   Structur query language  
   结构化查询语言,是操作关系型数据库中的对象。   
  
   DDL(Data definition language 数据定义语言),用于建表或删表操作,以及对表约束进行修改 
      create table , alter table , drop table 对表结构的增删操作。
   DML(Data manipulation language 数据操作语言),向表中插入纪录,修改纪录
      insert , update , delete , merge
   transaction ,事务控制语言,由DML语句组成的,commit; ,rollback;                           
   select 查询语句
   dcl 授权语句 grant
  
三、Oracle
   DBMS 数据库管理系统
   有Oracle提供,还提供AS,应用服务器
   DBA 数据库管理员

四、相关操作  
1、sqlplus 访问数据库命令(本地访问/远程访问),和数据库建立连接的命令,是数据库操作的环境
   sqlplus 用户名/密码
2、show user 显示当前用户的用户名
   改变身份可以直接connect 用户名/密码   --- 这个是sqlplus命令
   在sqlplus中可以使用 ! 可以在shell和sqlplus间切换,!shell命令 可以在sqlplus中使用shell命令。
   实际上是sqlplus开了子进程来执行shell命令。
3、Oracle数据库中的表分两类:用户表(用户使用操作的表),系统表(数据库系统维护的表,也叫数据字典)
   对用户表的DDL操作出发了对系统表的DML操作!

五、基本语法

1、select查询语句

select table_name from user_tables;(查询系统表)
以上的查询语句就是查询本用户下所拥有的所有表的表名。

投影操作,只查看选择的字段的信息。
选择操作,查看字段中的特定某些信息。
联接操作,多表查询,通过表间连接,查寻出多表中的信息

(1)select table_name from user_tables;(查询系统表)
     以上的查询语句就是查询本用户下所拥有的所有表的表名。
    
(2)sqlplus的buffer中会缓存最后一条sql语句,可以使用"/"来执行这最后一条sql语句,也可以使用
     edit命令来编辑最后一条sql语句。
     l命令(list)(sqlplus命令)可以显示buffer中最后一条命令。  
    
     sqlplus命令可以缩写
    
(3)desc [表名]
     这是一条sqlplus命令,注意他不是sql语句,这条命令用于查看表的结构。descript的缩写
     [字段名] [字段的类型],这是使用完desc命令后显示的表结构。      
    
(4)select [表的字段名1],[表的字段名2], ... from 表名;
     select * from 表名; 查寻表中所有字段的信息    
    
(5)关键字不等拆分,sql语句,以及表名,字段名是大小写不敏感的。
     sql语句要以";"结尾,来表示sql语句结束,如果不加";"系统不会执行此条sql语句,并提示。    
     在Oracle中字符显示是左对齐,数值右对齐。
    
(6)在select 语句中可以使用数学表达式。
     select [表达式(必须包含本表字段名)],[...],.... from 表名;
     运算的优先级的先乘除后加减,同级自左向右运算,括号改变优先级。

(7)别名
     select [字段名或表达式] ["别名"],[...] ["..."],.... from 表名;
     可以通过在字段名或表达式后加空格"别名",可以给列,或者表达式结果其别名。    
     表达别名必须加双引号。
    
(8)字符串拼接使用||符号
     select 目标字段名||" "||目标字段名 from 表名;

     注意:在Oracle中的字符串要用'..'包含
     别名中需要使用空格,或是大小写敏感时需要用".."包含。    
    
练习:
自己写一条SQL语句,执行的结果是select * from ...;
其中...是每张系统表的表名
即在每张系统表的表名前加“select * from”  ,后加“;”
select 'select * from '||table_name||';' from user_tables; 
    
    
2、处理错误
(1)!oerr ora [错误号] ,系统可以显示错误的原因和如何修改。如果命令错误输入可以使用edit或ed来修改输入错误。
     实际上是在编辑缓存文件中的最后一条sql语句。
     也可以使用 (change) c /错误字段/正确字段,来进行替换操作进行修改。
     只有在Linux平台使用
     ! 相当于 host ,没有断连接,只是切换了一下,执行shell命令
(2)edit命令来编辑最后一条sql语句。

3、sqlplus设置
set pause on 回车响应,分屏显示,只在本会话中有效
set pause off 关闭分屏显示。
set pause "..."  设置分屏显示的提示信息。
set pause on 先输出提示信息,回车响应,分屏显示
set head off 提头输出关闭
set feed off 结尾输出关闭
set echo off 回写关闭
spool 文件名.sql 写入指定文件
spool off 关闭写入。   

4、sql脚本
   也就是在文件中写有sql语句的文件,可以在sqlplus中运行。
   引入sql脚本
   sqlplus 用户名/密码 @sql脚本 (注意:在用户名密码输入结束后一定要加空格然后再写@sql脚本)
   在脚本中最后一行写上“exit”,则运行完脚本以后,回到shell上
  
  
5、
Oracle中的空值 空值会当无穷大处理,其实空值根本就不会存储,只是看作是无穷大。

Oracle中控制处理函数 NVL(字段名,值),这个字段中的空值替换为指定值,如果不为空,则会返回其原值。
例:select (salary*12)*(NVL(commission_pct,0)/100+1) salary,first_name from s_emp;

distinct关键字,去掉重复行(这个关键字会触发排序操作)
例: select distinct dept_id,title from s_emp;
        dept_id与title的联合不唯一
注意:distinct,关键字之后会对from之前的字段进行排重操作。

6、column命令 --- sqlplus命令
   column命令 列格式的定义

    column 目标列名 查看这个类是否定义了格式

    column 目标列名 format a.. 设置列宽。
    column last_name heading 'Employee|Name'  FORMAT A15
    设置题头
    这其中的'|'是换行符

    column salary justify left format $99,990.00
    定义数字显示格式
    注意:如果不满足显示的格式,就会把数据显示为"#"
   
    column salary justify left format $00,000.00
    会出现$00,928.00 ,用0补齐

    column 列名 clear (清除列格式定义)

    注意:只有sqlplus命令才有简写,并且在使用sqlplus命令时结尾也不能加分号。


六、选择操作
1、order by
   排序子句 ASC(默认,升序) DESC(降序)
   order by 目标列名(别名) 排序顺序(不写排序顺序,会默认为升序排序)

   例:select first_name from s_emp order by first_name;
       select first_name from s_emp order by first_name desc;

   注意:升序空值在结果的末尾,降序空值在结果的最前面。
  
2、where子句

where子句使用在 select ... from ... 后面,用来选择所需(符合条件的)的记录

where后面跟的是表达式 也就是 XXX=XXX, XXX between X and X  ,XXX in(X,X,X)
like '...' 通配查询

between ... and ... ,表示结果在这之间,between and是一个闭区间,
也就相当于... <= ... and ... >= ... 。
!=,<>,^=,这三个都标识不等于,<=,>=,=,这些运算符都可以使用。
... in (va1,val2,...) 判断结果是否在这个枚举中存在
like '...' 字符串通配查询,'%'表示多个字符,'_',表示一个字符。
注意:转义的用法:like ‘S\_%’ escape ‘\’
... and ... 表示只有两个条件同时满足
... or ... 表示条件只要满足其中只一就可以
all ... 是要求都满足条件。
not .....,则是可以与以上的条件产生反效果。
空值会对not in造成影响,也就是不等于任何值,但是空值例外。
... is null 使用来判断值是否为空。
    
注意:Oracle中的字符串是严格区分大小写的。

(1)注意数据类型,数字类型直接写,字符用'......' ,缺省格式的Date可以用'......',只有别名
  才用" "包含。
(2)选择合适的运算符  


七、单行函数
1.字符函数

   字符是大小写敏感的
   转小写 lower(字段名)      ---  其中的参数可以是一个字符串常量或是一个字段名
   转大写 upper(字段名)
   首字母大写 initcap(字段名)
   字符串拼接 concat(字段1, 字段2)
   截取子串 substr(字段名, 起始位置,取字符个数)
   dual表,是专门用于函数测试和运算的,他只有一条记录
   字符串拼接 concat(...,....)
   求指定子串 substr(...,起始位置,取字符个数)
   可以使用"-"表示从右向左取,取的时候可以从左往友取。
    例:select substr(first_name,-2,2) sub from s_emp;(取后两个)
       select substr(first_name,2,2) sub from s_emp;(取前两个)
      
2,数值函数

   四舍五入 round(数据,保留小数点后几位)
   可以用负数表示小数点前,0,表示小数点后第一位,也就是保留个位,-1表示个位(保留到十   位)。
   例:select round(15.36,1) from dual;
   截取数字函数 trunc(数据,保留的位数(小数点后位数)) 截取个位之后补0
   例:select trunc(123.456,1) from dual; 
  
3,日期函数
 
   日期格式,
   全日期格式 世纪信息,年月日,时分秒。
   缺省日期格式,日-月-年 dd-mon-rr
   修改当前会话的日期格式,会按照指定的格式输出日期
   alter session set nls_date_format='yyyy mm dd hh24:mi:ss';

   返回当前日期 sysdate
   例:select sysdate from dual;
       select sysdate+1 from dual;  获得明天的日期,加1,单位是天
   
   日期是格式敏感的
   求两个日期间相隔了多少个月 months_between(date1,date2)
   加减指定数量的月份 add_months(date,月数),月数可以为负,负值就是减去相应的月数。
   从date日期开始的第一个星期五 next_day(date,FriDay)
   返回月末的日期 last_day(date)
   截取日期 trunc(date,'年或月或日或时分秒')
   例:select next_day(sysdate,2) from dual;
   例:select trunc(add_months(sysdate,1),'month') from dual;  
   ROUND('25-MAY-95','MONTH')  01-JUN-95
   ROUND('25-MAY-95 ','YEAR')  01-JAN-95
   TRUNC('25-MAY-95 ','MONTH') 01-MAY-95
   TRUNC('25-MAY-95 ','YEAR')  01-JAN-95
  
   练习:
   返回下个月的第一天的日期
   select round(last_day(sysdate),'MONTH') from dual;
   select add_months(trunc(sysdate,'MONTH'),1);
  
4,不同数据类型间转换函数

   将日期转成字符 tochar(date,'日期格式')
   日期格式要用有效格式,格式大小写敏感 'yyyy mm dd hh24:mi:ss',
   'year'(全拼的年),'mm'(数字表示的月) 'month'(全拼的月),'day'(星期的全拼),'ddspth' (日期的全拼) 'yy mm dd'
   例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss')from dual;

   将字符转换成数字 to_number('...')
  
   将数字转字符to_char(number,'fmt') fmt是数字格式

   将字符串转成日期 to_date('...','日期格式')
   例:select to_char(to_date('2006 11 03','yyyy mm dd'),'dd-month-yy') from dual;
  


1、等值连接

  select [表别名1.字段名1],[表别名2.字段名2],...
  from 表1 表别名1 ,表2 表别名2
  where 表别名1.字段名3=表别名2.字段名4;
  表连接时,当表与表之间有同名字段时,可以加上表名或表的别名,加以区分,使用时要用
  表名.字段名或表别名.字段名(列名)。当表的字段名是唯一时,可以不用加上表名或表的别名。

  注意:当为表起了别名,就不能再使用表名.字段名。

  例:select a.first_name,a.last_name,b.name
      from s_emp a,s_dept b
      where a.dept_id=b.id;    

2、非等值连接

  select [表别名1.字段名1],[表别名2.字段名2],...
  from 表1 表别名1 ,表2 表别名2
  where 表别名1.字段名3 ..... 表别名2.字段名4

  ....可以使比较运算符,也可以使其他的除了'='的运算符

  例:select e.ename, d.grade,e.sal
      from emp e,salgrade d
      where e.sal between d.losal and d.hisal;     

3、自连接

  用别名把一张表中的数据分成两部分,然后在使用条件过滤。
  select [表别名1.字段名1],[表别名2.字段名2],...
  from 表1 表别名1 ,表1 表别名2
  where 表别名1.字段名3=表别名2.字段名4;

  例:select a.first_name ename,b.first_name cname
      from s_emp a,s_emp b
      where a.manager_id=b.id;

  以上所提到的表连接,都叫做内连接,严格匹配两表的记录。         
 
4、外连接

  会使用一方表中的所有记录去和另一格表中的记录按条件匹配,空值也会匹配,这个表中的所有记录都会显示,数据库会模拟出记录去和那些不匹配的记录匹配。

  例:select a.first_name enamei,a.id,b.first_name cname,b.id
      from s_emp a,s_emp b
      where a.manager_id=b.id(+);
      即用a表中的数据去匹配b表的,若b表中有null,系统模拟纪录与其匹配

  注意:要把那一方的记录全部都显示出来,还有注意条件(+)跟在要全部选出的对端。              
 
  外连接的应用:
  列出哪个部门没有员工
  select e.deptno,d.deptno
  from emp e,dept d
  where e.deptno(+)=d.deptno
  and e.deptno is null;
 
三、组函数

group 组
group by 分组子句,按指定的分组规则分组 ,这个group by 子句可以跟在 select 语句后或是 having后面。
group by子句也会出发排序操作,会按分组字段排序。

select [组函数或分组的字段名] ,... from 表名 group by [字段名1],[字段名2],.....;

例:select avg(salary) from s_emp group by dept_id;

注意:组函数可以处理一组数据,返回一个值。
      组函数会忽略空值。

avg(..),求平均值,sum(..),求和 这两个函数的参数只能是number型的。

以下所提到的函数可以使用任意类型做参数。
count(..),用来统计记录数,可以使用排重命令。count(...)默认使用的是all。
max(..),min(..)求最大值和最小值,
count(*),统计表中记录数。

例:select max(b.name),avg(a.salary), max(c.name)
    from s_emp a,s_dept b,s_region c
    where a.dept_id=b.id and b.region_id=c.id
    group by b.dept_id;

注意:只要写了group by子句,
      ***   select后就只能用group by后的字段或者是组函数。  ***
      where子句只能够过滤记录,放单行函数。


having子句可以过滤组函数结果或是分组的信息,且写在group by子句后。

例:
select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.id
having sum(a.salary)>4000;

column 也可以定义有别名的列的格式。
column "别名" 格式定义

注意:要先过滤掉不需要的记录,然后再进行分组操作,提高效率。


四、子查询

子查询,就是可以嵌在任何的sql语句中的select语句。

在select语句中嵌套子查询时,会先执行子查询。一般的会将子查询放在运算符的右边。

注意:在使用子查询时,要注意这个运算符是单行的(也就是只能是单值),还是多行运算符(范围,多值,in)。
配合使用子查询返回的结果必须符合运算符的用法。

例:
select first_name,title
from s_emp
where title=any(select title from s_emp
                where last_name='Smith')
and upper(last_name)!='SMITH';

select first_name,title
from s_emp
where title in (select title from s_emp
                where last_name='Smith')
and upper(last_name)!='SMITH';
 
 
 
五、将业务需求转换成可操作的表

一: 需求分析
二: 画E-R图
三: 转换成表关系
四: 割接(新老系统交接)
五:


E-R图属性:
* 为强制且非空属性
o 可选属性(可以有值也可以没有)
#* 表示此属性唯一且非空 

实体关系:
mastbean maybean

数量关系:   多对一关系
     一对多关系
     一对一关系
     多对多关系 

第一范式,所有的属性都必须是单值,也就是属性只表示单一的意义。(记录可以重复,没有任何限制)
第二范式,属性要求唯一且非空,(记录不可重复,但是数据可能会出现冗余)。
第三范式,非主属性只能依赖于主属性,不能依赖于其他非主属性。(解决数据冗余问题)


六、约束

约束是针对表中的字段进行定义的。

primary key (主键约束 PK)保证实体的完整性,保证记录的唯一
主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键,只有两个字段放在一起唯一标识记录,叫做联合主键。

foreign key (外建约束 FK)保证引用的完整性,
外键约束,外键的取值是受另外一张表中的主键或唯一值得约束,不能够取其他值,只能够引用主键会唯一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入也是如此,先父表后子表,删除记录,要先删除子表记录,后删除父表记录,要修改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。

unuque key(唯一键),值为唯一

index(索引)是数据库特有的一类对象,view(示图)
典型的一对多 class 对应多个学生。

student table                      class table 
______________________________ _________________________
| id | name | address| class_id| | id |class_desc|class_num|
|(PK)|______|________|___(FK)__| |(pk)|__________|_________|
| | | | | | | | |




一对一

student tabel             shenfenzheng table
____________________ _________________________________
| id | name | address| | s_id |shenfen_desc|shenfen_num|
|(PK)|______|________| |(PK,FK)|____________|___________|
| | | | | | | |



多对多

student tabel             zhongjian table                      kecheng table
____________________ _________________________________ __________________
| id | name | address| | s_id |shenfen_desc|shenfen_num| | kid | kechengname|
|(PK)|______|________| |(FK,FK)|____________|___________| | (PK)|____________|
| | | | |联合主键| | | | | |



引用对方表的主键,当作本身的主键,所以这个表的主键,既是主键又是外建

建表和其他相关操作

DDL语句

创建表:
   create    table  表名   (    字段名1    类型(数据长度)(default ...)   约束条件,   字段名2    类型(数据长度)    约束条件 );

Oracle数据库中的数据类型

varchar(长度),可变长字符串,char(长度) 定长
number(..,..),number 表示浮点数,或者是整数
long 大对象,clog 字符的大对象,相当于文本文件在表中只存放一个相当于只针对值
             blog 二进制的大对象,也是以相当于指针的形式存放的。
primary key约束:
主键约束的定义:
第一种定义形式:
create table   test(c  number  primary key  );     列级约束
第二种定义形式:
create table  test(c  number , primary key(c) )  ; 表级约束
create table   test( c1  number  constraints   pkc1  primary key );   此约束有名字:  pkc1
create table   test(c number , c2  number ,  primary key (c ,c1) )  ; 用表级约束可以实现联合主键

foregin  key   (fk)   外键约束:
(先定义父表,再定义子表)
carete   table     parent(c1 number  primary key );
create   table    child  (c  number primary key ,   c2 number  references parent(c1));
或表级约束定义:
create   table  child( c number primary key ,  c2  number  , foreign key(c2)  references  parent(c1));

如果两个字段都为唯一且非空,这时可以定义成UK+NOT NULL


(PK或UK)一对多(FK)
(PK+UK)一对一(FK)      或   (PK)一对一(PK)
多对对多关系,一般都通过一张中间表来分解成两个一对多的表


建立表
create table[schema]table
schema: 一个用户对应一个schema       不同用户下的表不能互相查看

select count(*) from s_dept;     <===>     select count(*) from sd0611.s_dept;


一个表中只能存储一个LONG类型
CLOB 存储大的文本对象
BLOB 存储大的二进制对象

create table test(c1 number primary key);   设置主键
create table test(c1 number constraints test_c1 primary key);   定义约束名,默认约束名为SYS_      在列后面定义约束称为列级约束
create table test(c1 number primary key(c1));   所有列定义完后再定义约束称为表级约束(能定义联合主键)
cretae table test(c1 number,c2 number,priary key(c1,c2));    定义联合主键
create table child(c1 number primary key);    先要定义父表
create table child(c1 number primary key, c2 number references parent(c1));   然后定义子表  references parent定义外键
create table child(c1 number primary key, c2 number references parent(c1) on delete cascate);  on delete cascate为级联删除
create table child(c1 number primary key, c2 number references parent(c1) on delete set null);   on delete set null删除后将外键置空
create table child (c1 number primary key, c2 number,foreignkey(c2) references parent(c1));
 

二、约束

1、非空约束(not null)
   这是一个列级约束
   在建表时,在数据类型的后面加上 not null ,也就是在插入时不允许插入空值。 
   例:create table student(id number primary key,name varchar2(32) not null,address varchar2(32));
  
2、unique 唯一约束
   唯一约束,是会忽略空值的,唯一约束,要求插入的记录中的值是为一的。
   例:create table student(id number,name varchar2(32),address varchar2(32),primary key (id),unique (address));  
   如果创建一个uk,系统自动建一个唯一索引
  
3、pk、uk
   Oralce支持级联删除,不支持级联更新  

4、check约束
检查约束,可以按照指定条件,检查记录的插入。check中不能使用尾列,不能使用函数,不能引用其他字段。
例:create table sal (a1 number , check(a1>1000));


连接实例:

package com.jdbc;
import java.sql.Connection; //代表对特定数据库的连接
import java.sql.DriverManager; //处理数据的调入并且对产生新的数据库连接提供支持
import java.sql.ResultSet; //控制执行查询语句得到的结果集
import java.sql.SQLException;
import java.sql.Statement; //代表一个特定的容器,容纳并执行一条SQL语句public class JdbcText {
// URL数据库连接串信息,ip未你的IP地址,“1521”为端口,“orcl”为sid
String URL = "jdbc:oracle:thin:@ip:1521:orcl";
String user = "scott"; //数据库用户名
String password = "password"; //登陆数据库密码 Connection conn = null;
Statement stmt; // 初始化连接
public JdbcText(){
try
{
//构造驱动实例
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
// 与url指定的数据源建立连接
conn = DriverManager.getConnection(URL, user, password);
System.out.println("成功连接数据库!");
// 采用Statement进行查询
stmt = conn.createStatement(); // 创建连接状态对象
} catch (Exception e)
{
System.out.println("连接数据库失败!");
e.printStackTrace();
}
} // 执行查询 获取结果存入容器中
public ResultSet executeQuery(String sql) {

ResultSet rs = null;
try
{
rs = stmt.executeQuery(sql); //执行SQL语句,将获取内容存入 rs
} catch (SQLException e)
{
System.out.println("SQL语句书写错误!");
e.printStackTrace();
}
return rs;
} public void close() {
try
{
conn.close();
stmt.close();
} catch (Exception e)
{
e.printStackTrace();
}
} public static void main(String[] args) {

ResultSet rs;
JdbcText jdbc = new JdbcText();
rs = jdbc.executeQuery("SELECT empno,ename from emp"); //从emp表中查询员工编号和姓名
try
{
while (rs.next()) // 遍历结果集
{
System.out.print(rs.getString("empno"));
System.out.println(":" + rs.getString("ename"));
}
} catch (Exception e)
{
e.printStackTrace();
}
jdbc.close();
}}

首先保证你Oracle相关服务是正常打开的

可能出项的异常:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver

没有加载数据库驱动

解决:导入class12.jar包

若还是连接数据库失败,那把IP地址改为 localhost  或你的计算机名(至于原因,还未解决,如果你能解决,还请告知一声)

若报SQL异常,就好好检查一下你的 SQL语句吧


————————————————————————————————————————————————————————————————————————————


 

5、JVM性能调优,都做了什么?

———————————————————————————————————————————————————

一、CPU过高

1、  us过高

使用监控工具快读定位哪里有死循环,大计算,对于死循环通过阻塞式队列解决,对于大计算,建议分配单独的机器做后台计算,尽量不要影响用户交互,如果一定要的话(如框计算、云计算),只能通过大量分布式来实现

2、  sy过高

最有效的方法就是减少进程,不是进程越多效率越高,一般来说线程数和CPU的核心数相同,这样既不会造成线程切换,又不会浪费CPU资源

二、内存消耗过高

1、  及时释放不必要的对象

2、  使用对象缓存池缓冲

3、  采用合理的缓存失效算法(还记得我们之前提到的弱引用、幽灵引用么?)

三、磁盘IO过高

1、  异步读写文件

2、  批量读写文件

3、  使用缓存技术

4、  采用合理的文件读写规则

四、网络

1、增加宽带流量

五、资源消耗不多但程序运行缓慢

1、使用并发包,减少锁竞争

2、对于必须单线程执行的使用队列处理

3、大量分布式处理

六、未充分利用硬件资源

1、  修改程序代码,使用多线程处理

2、  修正外部资源瓶颈,做业务拆分

3、  使用缓存



在CPU负载不足的同时,偶尔会有用户反映请求的时间过长,我们意识到必须对程序及JVM进行调优。从以下几个方面进行:

  • 线程池:解决用户响应时间长的问题
  • 连接池
  • JVM启动参数:调整各代的内存比例和垃圾回收算法,提高吞吐量
  • 程序算法:改进程序逻辑算法提高性能


———————————————————————————————————————————————————

6、forward和sendRedirect的区别


———————————————————————————————————————————————————

SendRedirect

Forward

不同的request

不同的对象,但是可以渠道上一个页面的内容

send后面的语句会继续执行,除非return

Forward后面的语句不会继续发送给客户端

速度慢

速度快

需要到客户端的往返,可以跳转到任何页面

服务器内部转换

地址栏有变化

地址栏没有变化

可以传参数,直接写在URL后面

可以传参数

 / 代表的是http://127.0.0.0/
<%response.sendRedirect();%>
<form action="/test/ServletToJSP">
<a href="/test/ServletToJSP">test</a>

 / 代表的是 http://127.0.0.1/test
this.getServletContext().getRequestDispatcher
("/servlet_jsp/ServletUseJSP.jsp").forward
(req,resp); 并且只能以 / 开头







ITeye ​​​sendRedirect和forward原理及区别总结​​​ITeye  ​​forward与sendRedirect区别​​CSDN forward和sendRedirect的区别

HttpServletResponse.sendRedirect与RequestDispatcher.forward方法都可以实现获取相应URL资源。

sendRedirect实现请求重定向,forward实现的是请求转发。

在web服务器内部的处理机制也是不一样的。

 

1.forward方法只能转发给同一个web站点的资源,而sendRedirect方法还可以定位到同一个web站点的其他应用,甚至可以通过传入绝对路径定位到别的web站点,这事forward的方法所不能比拟的优势。

可以看到这两种方法的用法,如果传给RequestDispatcher 的参数以"/"开头,则访问的是当前web应用的根目录

加入当前web的根目录是myweb。如果传给sendRedirect方法以"/"开头,访问的是整个web站点的根目录。



RequestDispatcher rd = request.getRequestDispatcher("/index.jsp");
rd.forward(request, response);

response.sendRedirect("/index.jsp");

2.forward重定向后,浏览器url地址不变,sendRedirect转发后,浏览器url地址变为目的url地址。


 

3. 使用forward重定向的过程,是浏览器先向目的Servlet发送一次Request请求,然后再服务器端由Servlet再将请求发送到目的url,再由服务器端Servlet返回Response到浏览器端。浏览器和服务器一次请求响应。

    使用sendRedirect转发的过程,浏览器先向目的Servlet发送一次请求,Servlet看到sendRedirect将目的url返回到浏览器,浏览器再去请求目的url,目的url再返回response到浏览器。浏览器和服务器两次请求响应。

 

4. forward方法的调用者与被调用者之间共享Request和Response

    sendRedirect方法由于两次浏览器服务器请求,所以有两个Request和Response。

    如果使用request.setAttribute传递一些属性就需要用forward,如果想要跳转到别的应用的资源,就需要用sendRedirect。

 

5.无论是forward方法还是sendRedirect方法调用前面都不能有PrintWriter输出到客户端。

   forward方法报错: java.lang.IllegalStateException: Cannot forward after response has been committed

   sendRedirect报错:java.lang.IllegalStateException
 at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:435)


———————————————————————————————————————————————————

6、<jsp:include page=''> 和 <%@include file=''%>的区别

———————————————————————————————————————————————————

1.<jsp:include page=""/>是运行时包含,面向的是静态和动态对象,其JSP引擎不对所包含的文件进行语法分析。

2.<%@ include file="" %>是编译时包含,面向的仅是静态的对象,其JSP引擎对所包含的文件进行语法分析。

所以在使用一个jsp页面包含另一个页面时要注意,如果另一个页面是静态不重新加载的页面或者是两个页面不包含相同的变量时使用<%@ include file="" %>,否则使用<jsp:include page=""/>。


———————————————————————————————————————————————————


7、你们系统的数据库切分,按什么切?  横向 纵向切分?

———————————————————————————————————————————————————

数据的切分分为两种模式,一种是按照不同的表(或者schema)来切分到不同的数据库(主机)上,这种切分可以称之为垂直(纵向)切分;另外一种是根据数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上,这种切分称之为数据的水平(横向)切分。

一个架构较好的应用系统,其总体功能肯定是由多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或多个表。而在架构设计中,各个功能模块相互之间的交互点越统一,越少,系统的耦合度就越低,系统各个模块的维护性及扩展性就越好。这样的系统,实现数据的垂直切分也就越容易。

数据的垂直切分基本上可以简单地理解为按照表或模块来切分数据,而水平切分则不同。一般来说,简单的水平切分主要是将某个访问及其平凡的表再按照某个字段的某种规则分散到多个表中,每个表包含一部分数据。就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他数据库中。为了容易地判定各行数据被切分到哪个数据库了,切分总是要按照某种特定的规则来进行的:如根据某个数据类型字段基于特定数据取模,某个时间类型字段的范围,或者某个字符类型字段的hash值。如果整个系统中大部分核心表都可以通过某个字段来进行关联,那这个字段自然是一个进行水平分区的上上之选了。
———————————————————————————————————————————————————

8、熟悉linux下的开发么?

____________________________________________________________________________________________

熟悉

____________________________________________________________________________________________


9、tcp头部都什么东西,http呢?

____________________________________________________________________________________________

HTTP 头部解释

1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
 
2. Accept-Charset:   浏览器申明自己接收的字符集
   Accept-Encoding:  浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法  (gzip,deflate)
   Accept-Language::浏览器申明自己接收的语言语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。
 
3. Accept-Ranges:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
 
4. Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
 
5. Authorization:当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,该头部来回应自己的身份验证信息给WEB服务器。
 
6. Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取)
                                     max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)
                                     max-stale:(可以接受过去的对象,但是过期时间必须小于
                                                        max-stale 值)
                                     min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的
                                                        缓存对象)
                            响应:public(可以用 Cached 内容回应任何用户)
                                      private(只能用缓存内容回应先前请求该内容的那个用户)
                                      no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)
                                      max-age:(本响应包含的对象的过期时间)
                                      ALL:  no-store(不允许缓存)
 
7. Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应
                                                  后,断开连接,不要等待本次连接的后续请求了)。
                                 keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的
                                                         响应后,保持连接,等待本次连接的后续请求)。
                       响应:close(连接已经关闭)。
                                 keepalive(连接保持着,在等待本次连接的后续请求)。
   Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持
                      连接多长时间(秒)。
                      例如:Keep-Alive:300
 
8. Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。 
                                 例如:Content-Encoding:gzip                  
   Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。
   Content-Length:    WEB 服务器告诉浏览器自己响应的对象的长度。
                                例如:Content-Length: 26012
   Content-Range:    WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。
                                例如:Content-Range: bytes 21010-47021/47022
   Content-Type:      WEB 服务器告诉浏览器自己响应的对象的类型。
                                例如:Content-Type:application/xml
 
9. ETag:就是一个对象(比如URL)的标志值,就一个对象而言,比如一个 html 文件,
              如果被修改了,其 Etag 也会别修改, 所以,ETag 的作用跟 Last-Modified 的
              作用差不多,主要供 WEB 服务器 判断一个对象是否改变了。
              比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时, 
              浏览器就会把先前获得的 ETag 值发送给  WEB 服务器,然后 WEB 服务器
              会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件
              有没有改变了。
        
10. Expired:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在
                    跟WEB服务器验证了其有效性后,才能用来响应客户请求。
                    是 HTTP/1.0 的头部。
                    例如:Expires:Sat, 23 May 2009 10:02:12 GMT
 
11. Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。
                例如:Host:rss.sina.com.cn
 
12. If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。
    If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。
 
13. If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求
                                 的动作(比如返回对象),否则返回代码304,告诉浏览器该对象
                                 没有修改。
                                 例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
    If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行
                                   请求的动作(比如返回对象)。
 
14. If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分
                       给我,如果对象改变了,就把整个对象给我。 浏览器通过发送请求对象的
                       ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否
                       改变了。
                       总是跟 Range 头部一起使用。
 
15. Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,
                                 动态页面的最后产生时间等等。
                                 例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
 
16. Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,
                        到该头部指定的位置去取。
                        例如:Location:
​​​                                   http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif​​​ 
17. Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。
                      例如:Pragma:no-cache
 
18. Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。
      Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。
 
19. Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。
                    例如:Range: bytes=1173546-
 
20. Referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。
                   例如:Referer:http://www.sina.com/
 
21. Server: WEB 服务器表明自己是什么软件及版本等信息。
                  例如:Server:Apache/2.0.61 (Unix)
 
22. User-Agent: 浏览器表明自己的身份(是哪种浏览器)。
                        例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN;   
                                  rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
 
23. Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)
                                  作了怎样的编码,比如是否分块(chunked)。
                                  例如:Transfer-Encoding: chunked
 
24. Vary: WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应
                 所返回的对象响应后续的请求。
                 假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:
                 Content-Encoding: gzip; Vary: Content-Encoding  那么 Cache 服务器会分析后续
                 请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值
                 一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己
                 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。
                 例如:Vary:Accept-Encoding
 
25. Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用
                什么协议(和版本)发送的请求。
                当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面
                添加 Via 头部,并填上自己的相关信息,当下一个代理服务器 收到第一个代理
                服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via 
                头部,并把自己的相关信息加到后面, 以此类推,当 OCS 收到最后一个代理服
                务器的请求时,检查 Via 头部,就知道该请求所经过的路由。
                例如:Via:1.0 236-81.D07071953.sina.com.cn:80 (squid/2.6.STABLE13

1)IPv4 头部
 


java基础知识精华总结 java面试题  _客户端_02


 

  版本   IP报文首部的第一个字段是4位版本字段。对IPv4来说,这个字段的值是4。

   首部长度(IHL)   第二个字段是4位首部长度,说明首部有多少32位字长。由于IPv4首部可能包含数目不定的选项,这个字段也用来确定数据的偏移量。这个字段的最小值是5(RFC 791),最大值是15。 

   服务类型(TOS) 在转发过程中用来提供特别的服务。


   全长 这个16位字段定义了报文总长,包含首部和数据,单位为字节。这个字段的最小值是20(20字节首部+0字节数据),最大值是65,535。所有主机都必须支持最小576字节的报文,但大多数现代主机支持更大的报文。有时候子网会限制报文的大小,这时报文就必须被分片。

   标识符  这个字段主要被用来唯一地标识一个报文的所有分片。一些实验性的工作建议将此字段用于其它目的,例如增加报文跟踪信息以协助探测伪造的源地址。[5]


   标志 这个3位字段用于控制和识别分片,它们是: 

              位0:保留,必须为0;

              位1:禁止分片(DF);

              位2:更多分片(MF)。

      如果DF标志被设置但路由要求必须分片报文,此报文会被丢弃。这个标志可被用于发往没有能力组装分片的主机。

当一个报文被分片,除了最后一片外的所有分片都设置MF标志。不被分片的报文不设置MF标志:它是它自己的最后一片。


   分片偏移  这个13位字段指明了每个分片相对于原始报文开头的偏移量,以8字节作单位。

   存活时间(TTL) 这个8位字段避免报文在互联网中永远存在(例如陷入路由环路)。存活时间以秒为单位,但小于一秒的时间均向上取整到一秒。在现实中,这实际上成了一个跳数计数器:报文经过的每个

​路由器​

都将此字段减一,当此字段等于0时,报文不再向下一跳传送并被丢弃。常规地,一份ICMP报文被发回报文发送端说明其发送的报文已被丢弃。这也是traceroute的核心原理。 


   协议  这个字段定义了该报文数据区使用的协议。IANA维护着一份协议列表(最初由RFC 790定义)。 

   首部检验和 这个16位检验和字段用于对首部查错。在每一跳,计算出的首部检验和必须与此字段进行比对,如果不一致,此报文被丢弃。 

   源地址 一个IPv4地址由四个字节共32位构成,此字段的值是将每个字节转为二进制并拼在一起所得到的32位值。

   目的地址 与源地址格式相同,但指出报文的接收端。

   选项 附加的首部字段可能跟在目的地址之后,但这并不被经常使用。 

 (2)IPv6头部


java基础知识精华总结 java面试题  _客户端_03


 


(3)UDP 头部


 


java基础知识精华总结 java面试题  _java_04


 


(4)TCP 头部
 


java基础知识精华总结 java面试题  _表名_05



____________________________________________________________________________________________

10、加密解密的东西做过么?如md5什么的


____________________________________________________________________________________________

加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密单向加密,而双向加密又分为对称加密非对称加密(有些资料将加密直接分为对称加密和非对称加密)。

双向加密大体意思就是明文加密后形成密文,可以通过算法还原成明文。而单向加密只是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算是加密的一种,应该算是摘要算法吧。具体区分可以参考:
(本人解释不清呢 …… )
​​​http://security.group.iteye.com/group/wiki/1710-one-way-encryption-algorithm​一、双向加密
(一)、对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
需要对加密和解密使用相同密钥的加密算法。由于其速度,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。
所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。

算法是一组规则,规定如何进行加密和解密。因此对称式加密本身不是安全的。   
常用的对称加密有:DES、IDEA、RC2、RC4、SKIPJACK、RC5、AES算法等

对称加密一般java类中中定义成员


Java代码 ​

java基础知识精华总结 java面试题  _客户端_06


//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;

在构造函数中初始化


Java代码 ​

java基础知识精华总结 java面试题  _客户端_06

Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DES");//
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DES");

1. DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。 明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。


Java代码 ​

java基础知识精华总结 java面试题  _客户端_06


import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypDES {

//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;

public EncrypDES() throws NoSuchAlgorithmException, NoSuchPaddingException{
Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DES");
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DES");
}

/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Encrytor(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}

/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}

/**
* @param args
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws Exception {
EncrypDES de1 = new EncrypDES();
String msg ="郭XX-搞笑相声全集";
byte[] encontent = de1.Encrytor(msg);
byte[] decontent = de1.Decryptor(encontent);
System.out.println("明文是:" + msg);
System.out.println("加密后:" + new String(encontent));
System.out.println("解密后:" + new String(decontent));
}

}

2. 3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对3DES
数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。   
3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法,其具体实现如下:
设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,
这样,   
3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密过程为:P=Dk1((EK2(Dk3(C)))


Java代码 ​​​​​   ​

java基础知识精华总结 java面试题  _表名_09

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypDES3 {

// KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
// SecretKey 负责保存对称密钥
private SecretKey deskey;
// Cipher负责完成加密或解密工作
private Cipher c;
// 该字节数组负责保存加密的结果
private byte[] cipherByte;

public EncrypDES3() throws NoSuchAlgorithmException, NoSuchPaddingException {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
// 实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DESede");
// 生成密钥
deskey = keygen.generateKey();
// 生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DESede");
}

/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Encrytor(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}

/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}

/**
* @param args
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws Exception {
EncrypDES3 des = new EncrypDES3();
String msg ="郭XX-搞笑相声全集";
byte[] encontent = des.Encrytor(msg);
byte[] decontent = des.Decryptor(encontent);
System.out.println("明文是:" + msg);
System.out.println("加密后:" + new String(encontent));
System.out.println("解密后:" + new String(decontent));

}

}

3. AES密码学中的高级加密标准(Advanced Encryption Standard,AES),又称  高级加密标准
Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。   该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhinedoll"。)


Java代码 ​


​​   ​

java基础知识精华总结 java面试题  _java_10


import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypAES {

//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;

public EncrypAES() throws NoSuchAlgorithmException, NoSuchPaddingException{
Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("AES");
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("AES");
}

/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Encrytor(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}

/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}

/**
* @param args
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws Exception {
EncrypAES de1 = new EncrypAES();
String msg ="郭XX-搞笑相声全集";
byte[] encontent = de1.Encrytor(msg);
byte[] decontent = de1.Decryptor(encontent);
System.out.println("明文是:" + msg);
System.out.println("加密后:" + new String(encontent));
System.out.println("解密后:" + new String(decontent));
}

}

(二)、非对称加密
1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥
(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

1. RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。


Java代码 ​

java基础知识精华总结 java面试题  _客户端_06

import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class EncrypRSA {

/**
* 加密
* @param publicKey
* @param srcBytes
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
protected byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
if(publicKey!=null){
//Cipher负责完成加密或解密工作,基于RSA
Cipher cipher = Cipher.getInstance("RSA");
//根据公钥,对Cipher对象进行初始化
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] resultBytes = cipher.doFinal(srcBytes);
return resultBytes;
}
return null;
}

/**
* 解密
* @param privateKey
* @param srcBytes
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
protected byte[] decrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
if(privateKey!=null){
//Cipher负责完成加密或解密工作,基于RSA
Cipher cipher = Cipher.getInstance("RSA");
//根据公钥,对Cipher对象进行初始化
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] resultBytes = cipher.doFinal(srcBytes);
return resultBytes;
}
return null;
}

/**
* @param args
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
EncrypRSA rsa = new EncrypRSA();
String msg = "郭XX-精品相声";
//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//初始化密钥对生成器,密钥大小为1024位
keyPairGen.initialize(1024);
//生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
//得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
//得到公钥
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();

//用公钥加密
byte[] srcBytes = msg.getBytes();
byte[] resultBytes = rsa.encrypt(publicKey, srcBytes);

//用私钥解密
byte[] decBytes = rsa.decrypt(privateKey, resultBytes);

System.out.println("明文是:" + msg);
System.out.println("加密后是:" + new String(resultBytes));
System.out.println("解密后是:" + new String(decBytes));
}

}

2. DSA
Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。(感觉有点复杂,没有附代码)
详见​​​http://63938525.iteye.com/blog/1051565​​​
(三)、题外话 MySQL加密解密函数
MySQL有两个函数来支持这种类型的加密,分别叫做ENCODE()和DECODE()。
下面是一个简单的实例:


Mysql代码 ​

mysql> INSERT INTO users (username,password) VALUES ('joe',ENCODE('guessme','abr'));

Query OK, 1 row affected (0.14 sec)

其中,Joe的密码是guessme,它通过密钥abracadabra被加密。要注意的是,加密完的结果是一个二进制字符串,如下所示:

提示:虽然ENCODE()和DECODE()这两个函数能够满足大多数的要求,但是有的时候您希望使用强度更高的加密手段。在这种情况下,您可以使用AES_ENCRYPT()和AES_DECRYPT()函数,它们的工作方式是相同的,但是加密强度更高。


单向加密与双向加密不同,一旦数据被加密就没有办法颠倒这一过程。因此密码的验证包括对用户输入内容的重新加密,并将它与保存的密文进行比对,看是否匹配。一种简单的单向加密方式是MD5校验码。MySQL的MD5()函数会为您的数据创建一个“指纹”并将它保存起来,供验证测试使用。下面就是如何使用它的一个简单例子:


Mysql代码 ​

mysql> INSERT INTO users (username,password) VALUES ('joe',MD5('guessme'));

Query OK, 1 row affected (0.00 sec)


或者,您考虑一下使用ENCRYPT()函数,它使用系统底层的crypt()系统调用来完成加密。这个函数有两个参数:一个是要被加密的字符串,另一个是双(或者多)字符的“salt”。它然后会用salt加密字符串;这个salt然后可以被用来再次加密用户输入的内容,并将它与先前加密的字符串进行比对。下面一个例子说明了如何使用它:


Mysql代码 ​

mysql> INSERT INTO users (username,password) VALUES('joe', ENCRYPT('guessme','ab'));

Query OK, 1 row affected (0.00 sec)


提示:ENCRYPT()只能用在UNIX、LINIX系统上,因为它需要用到底层的crypt()库。

二、单向加密(信息摘要)
Java一般需要获取对象MessageDigest来实现单项加密(信息摘要)。
1. MD5 即Message-Digest Algorithm 5(信息-摘要算法 5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。
除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等


Java代码 ​

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class EncrypMD5 {

public byte[] eccrypt(String info) throws NoSuchAlgorithmException{
//根据MD5算法生成MessageDigest对象
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] srcBytes = info.getBytes();
//使用srcBytes更新摘要
md5.update(srcBytes);
//完成哈希计算,得到result
byte[] resultBytes = md5.digest();
return resultBytes;
}


public static void main(String args[]) throws NoSuchAlgorithmException{
String msg = "郭XX-精品相声技术";
EncrypMD5 md5 = new EncrypMD5();
byte[] resultBytes = md5.eccrypt(msg);

System.out.println("密文是:" + new String(resultBytes));
System.out.println("明文是:" + msg);
}

}

2. SHA 是一种数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说时对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。


Java代码 ​

java基础知识精华总结 java面试题  _客户端_06


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class EncrypSHA {

public byte[] eccrypt(String info) throws NoSuchAlgorithmException{
MessageDigest md5 = MessageDigest.getInstance("SHA");
byte[] srcBytes = info.getBytes();
//使用srcBytes更新摘要
md5.update(srcBytes);
//完成哈希计算,得到result
byte[] resultBytes = md5.digest();
return resultBytes;
}

/**
* @param args
* @throws NoSuchAlgorithmException
*/
public static void main(String[] args) throws NoSuchAlgorithmException {
String msg = "郭XX-精品相声技术";
EncrypSHA sha = new EncrypSHA();
byte[] resultBytes = sha.eccrypt(msg);
System.out.println("明文是:" + msg);
System.out.println("密文是:" + new String(resultBytes));

}

}

附件中是以上几种的源代码,附带额外的两种使用方式。

增加一种关于文件的哈希算法源代码:


Java代码 ​

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;

public class FileHashUtil {

public static final char[] hexChar = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static final String[] hashTypes = new String[] { "MD2", "MD5", "SHA1", "SHA-256", "SHA-384", "SHA-512" };

public void MD5File(String fileName) throws Exception{
//String fileName = args[0];
System.out.println("需要获取hash的文件为: " + fileName);
java.util.List<MessageDigest> mds = new java.util.ArrayList<MessageDigest>();
for (String hashType : hashTypes) {
MessageDigest md = MessageDigest.getInstance(hashType);
mds.add(md);
}
InputStream fis = null;
try {
fis = new FileInputStream(fileName);
byte[] buffer = new byte[1024];
int numRead = 0;
while ((numRead = fis.read(buffer)) > 0) {
for (MessageDigest md : mds) {
md.update(buffer, 0, numRead);
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
for (MessageDigest md : mds) {
System.out.println(md.getAlgorithm() + " == " + toHexString(md.digest()));
}
}


public static void main(String[] args) throws Exception {
String[] fileName = new String[] {"D:/hapfish/ShellFolder.java","D:/hapfish/ShellFolder - 副本.java",
"E:/ShellFolder - 副本.java","E:/ShellFolder.txt","D:/hapfish/ShellFolder.jpg",
"E:/ShellFolder增加字符.txt","D:/hapfish/birosoft.jar"};
FileHashUtil files = new FileHashUtil();
for(int i=0;i<fileName.length;i++){
files.MD5File(fileName[i]);
}


}

public static String toHexString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; i++) {
sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
sb.append(hexChar[b[i] & 0x0f]);
}
return sb.toString();
}

}

运行说明


说明代码 ​

java基础知识精华总结 java面试题  _客户端_06


"D:/hapfish/ShellFolder.java",
"D:/hapfish/ShellFolder - 副本.java",
"E:/ShellFolder - 副本.java",
"E:/ShellFolder.txt",
"D:/hapfish/ShellFolder.jpg",
以上五个文件是同一文件经过复制、改扩展名的,最后计算哈希结果是一致的。

"E:/ShellFolder增加字符.txt" 增加了几个字符串,就不一样了

"D:/hapfish/birosoft.jar" 完全不相关的另外一个文件

运行结果:


Java代码 ​

java基础知识精华总结 java面试题  _客户端_06


需要获取hash的文件为: D:/hapfish/ShellFolder.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: D:/hapfish/ShellFolder - 副本.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder - 副本.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder.txt
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: D:/hapfish/ShellFolder.jpg
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder增加字符.txt
MD2 == f2717c24c6c0e110457bd17221c9ca6c
MD5 == c49e353a7c4c26bd7ccb5e90917c230f
SHA1 == 477c8a9e465bfaa4be42d35c032a17f7e6b42b97
SHA-256 == 9fa18adaf242ebcdc6563922d84c2a163c82e1a24db2eb2b73978ed1f354a8a3
SHA-384 == 4eee8f8e6d64d21c15dc01fa049f4d12a3b8e1d94d87763fe0bea75ab5ea8432fa8251289ece45ee39fe3d36b3c3020c
SHA-512 == e852ec0ff77250be497389d2f5a1818c18bb66106b9905c4ee26fe0d256eb3b77e0ce9a28a84e4b67e4332ba37ec3aa7518148e3a682318c0fc34c391f45c201
需要获取hash的文件为: D:/hapfish/birosoft.jar
MD2 == 38c5e1404718916dec59c33cafc909b3
MD5 == dc3e2cc4fb3949cf3660e0f5f8c3fba3
SHA1 == cde3dc25498afc5a563af0bb0eb54dc45f71bb28
SHA-256 == adf6a961c70c6ea677dff066fc5d896fb0beb4dd442ca0eb619ae1d1b04291e5
SHA-384 == fe7c6b754893c53ebd82bb53703fb5cc32115c9a38f98072f73def90729b271ee3c5c78e258bd9ff5ee5476193c2178b
SHA-512 == a15376f327256a6e049dfbdc5c2ad3a98bffccc6fa92ee01ff53db6b04471ca0f45ca28f76ff4a6911b57825afa046671299141f2499d71f1dac618c92385491

最后,把运行结果贴出来有点占空间,主要为了说明表述自己的猜想。一般来说同一哈希算法对同一文件(镜像、扩展名被修改)所产生的结果应该是一致的。

因此有个猜想,在baidu文库、腾讯的群共享上传时,先会判断是否有相同文件,从某种可能上来说也采用了对文件的哈希算法,毕竟从本地运算一个哈希算法后获得的数值要比把整个文件传过去比较实惠得多。而且字符串的比较也是很方便的。

对于某一种哈希算法,存在一种可能:就是两个不同的文件,计算出来的哈希值可能是一样的。当然为了保险,可以用两种甚至更多的哈希算法,只有在每种算法获得的哈希值都相同时,才能判断是同一个文件。
如果我们也对用户上传的文件进行哈希计算的话,就可以节省资源,同样的文件按理说可以减少上传次数……




____________________________________________________________________________________________

tcp三次握手的过程,accept发生在三次握手哪个阶段?

accept发生在三次握手之后。

第一次握手:客户端发送syn包(syn=j)到服务器。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)。

三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接。

___________________________________________________________________________________________

用UDP协议通讯时怎样得知目标机是否获得了数据包

用UDP协议通讯时怎样得知目标机是否获得了数据包?

可以在每个数据包中插入一个唯一的ID,比如timestamp或者递增的int。

发送方在发送数据时将此ID和发送时间记录在本地。

接收方在收到数据后将ID再发给发送方作为回应。

发送方如果收到回应,则知道接收方已经收到相应的数据包;如果在指定时间内没有收到回应,则数据包可能丢失,需要重复上面的过程重新发送一次,直到确定对方收到。

关于UDP协议的简单介绍,可以参考

——————————————————————————————————————————————————————————————————————

统计论坛在线人数分布

求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。

一天总共有 3600*24 = 86400秒。

定义一个长度为86400的整数数组int delta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。

然后依次读入每个用户的登录时间和退出时间,将与登录时间对应的整数值加1,将与退出时间对应的整数值减1。

这样处理一遍后数组中存储了每秒中的人数变化情况。

定义另外一个长度为86400的整数数组int online_num[86400],每个整数对应这一秒的论坛在线人数。

假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0] = delta[0]。第n+1秒的人数online_num[n] = online_num[n-1] + delta[n]。

这样我们就获得了一天中任意时间的在线人数。

—————————————————————————————————————————————————————————————————————————————两个整数集合A和B,求其交集

两个整数集合A和B,求其交集。

1. 读取整数集合A中的整数,将读到的整数插入到map中,并将对应的值设为1。

2. 读取整数集合B中的整数,如果该整数在map中并且值为1,则将此数加入到交集当中,并将在map中的对应值改为2。

通过更改map中的值,避免了将同样的值输出两次。

 

标签:面试题,加密,对象,基础知识,import,java,throws,select
From: https://blog.51cto.com/u_5112239/6047098

相关文章

  • json转java以及校验用户名是否存在
    json转java步骤:1.导入jackson相关jar包2.创建Jackson核心对象ObjectMapper3.调用ObjectMapper的相关方法进行转换1.readValue(json字符串数据,C......
  • Java Swing 禁止黏贴动作
    碰到一个需求,不让复制黏贴。可考的方法有:1重写JTextFieldpaste函数  2 删除组件ActionMap中与CTRL+V按键相关的操作因为JTextField已经被封装了一层,就不想再......
  • VUE相关面试题目01
    一、MVVM是什么;   MVC:               MVVM的描述:                常见库实现数据双向绑定的效果......
  • 使用AES的256位密钥加解密报错java.security.InvalidKeyException: Illegal key size
     使用AES的256位密钥加解密报错java.security.InvalidKeyException:Illegalkeysize。编写微信小程序在获取用户时,需要根据小程序传来的iv,encryptedData,和se......
  • JAVA缓存规范 —— 虽迟但到的JCache API与天生不俗的Spring Cache
    大家好,又见面了。本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面。如果感兴趣,欢迎关注以获取后续更新。有......
  • java冒泡排序
    java/**冒泡排序1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置2.每一次比较,都会产生一个最大或者最小的数字;3.下一轮则可以少一次排序!4......
  • java基础
    注释注释并不会被执行,是给我们写代码的人看的;书写注释是一个非常好的习惯单行注释//多行注释/*注释*/文档注释/**文档*/标识符关键字java所有的组成部......
  • 【Java面试】Runnable和Thread比较
    在线程使用过程中,我们肯定会用到Runnable与Thread,前者的实现方式是实现其接口即可,后者的实现方式是继承其类。两者实现方式带来最明显的区别就是,由于Java不允许多继承,因此......
  • JAVA PDF转图片,以及几种方案对比
    背景项目需要将PDF转为图片存储,在网上搜索,找到了三种方案(这里链接都是找的github上的地址):pdfbox,开源软件,apache社区在维护,还比较活跃icepdf,商业软件,但是github上有开......
  • java基础常用
    数组java数组需要先初始化才能使用初始化后未填充的位置自动填充nullObject数组能存储任意类型数据,包括基本数据类型Object数组1@Test2publicvoidobje......