`
huiqinbo
  • 浏览: 333417 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

oa源码解析(挺好的)

阅读更多
关键字: drp手记
----------------v1.0---------------
1、用户添加
2、用户查询
3、用户修改
4、用户删除
5、用户登录
6、filter解决字符集问题
7、Ajax应用
----------------v1.1---------------
1、分销商树的读取:client_tree.jsp
	
	<%=ClientManager.getInstance().getClientTreeString()%>

2.分步骤的写出树形结构:
第一步:1. 用加号“+”表示非叶子节点,用减号“-”表示叶子节点 
/**  
     * 递归读取分销商树  
     *   
     * 1. 用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
     * @param conn  
     * @param id   
     * @param level 控制层次的  
     */  
 private void read(Connection conn, int id, int level) {   
        level++;   
      String sql="select * from t_client where pid=?";   
        PreparedStatement pstmt=null;   
        ResultSet rs=null;   
      try {   
        pstmt=conn.prepareStatement(sql);   
        pstmt.setInt(1,id );   
        rs=pstmt.executeQuery();   
        while(rs.next()){   
            for(int i=0;i<level-1;i++){   
                sbTree.append("&nbsp;&nbsp;&nbsp;");   
            }   
            if("N".equals(rs.getString("is_leaf"))){   
                sbTree.append("+"+rs.getString("name"))   
                      .append("<br>");   
            read(conn,rs.getInt("id"),level);   
            }else{   
                sbTree.append("-"+rs.getString("name"))   
                       .append("<br>");   
            }   
        }   
           
    } catch (SQLException e) {   
        e.printStackTrace();   
    }finally{   
        DB.close(rs);   
        DB.close(conn);   
    }   
    }   
       
}  


第二步:加上<div>嵌套,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
/**  
 * 递归读取分销商树  
 *   
 * 1.用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
 * 2.加上<div>嵌套,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
 * @param conn  
 * @param id   
 * @param level 控制层次的  
 * @throws SQLException   
 */  
private void read(Connection conn, int id, int level) throws SQLException {   
    level++;   
  String sql="select * from t_client where pid=?";   
    PreparedStatement pstmt=null;   
    ResultSet rs=null;   
  try {   
    pstmt=conn.prepareStatement(sql);   
    pstmt.setInt(1,id );   
    rs=pstmt.executeQuery();   
    while(rs.next()){   
        sbTree.append("<div>");   
        for(int i=0;i<level-1;i++){   
            sbTree.append("<img src=\"../images/white.gif\" />");   
        }   
        if("N".equals(rs.getString("is_leaf"))){   
            sbTree.append("<img src=\"../images/plus.gif\"/>")   
                   .append("<img src=\" ../images/closedfold.gif\"/>")   
                   .append(rs.getString("name"));   
             //递归       
             sbTree.append("<div>");   
                read(conn,rs.getInt("id"),level);   
             sbTree.append("</div>");   
  
        }else{   
            sbTree.append("<img src=\"../images/minus.gif\"/>")   
                  .append("<img src=\" ../images/openfold.gif\"/>")   
                  .append(rs.getString("name"));   
        }   
        sbTree.append("</div>");   
    }   
       
} finally{   
    DB.close(rs);   
    DB.close(pstmt);   
}   
}   
  
第三步:在图片"+"和"-"上添加鼠标事件,使树能实现收缩和关闭同时图片也做改变;在图片"打开的文件夹"和"关闭的文件夹"上添加鼠标事件;


/**  
     * 递归读取分销商树  
     *   
     * 1.用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
     * 2.加上<div>,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
     * 3.在图片"+"和"-"上添加鼠标事件,使树能实现收缩和关闭同时图片也做改变;在图片"打开的文件夹"和"关闭的文件夹"上添加鼠标事件;  
     *   
     * @param conn  
     * @param id   
     * @param level 控制层次的  
     * @throws SQLException   
     */  
    private void read(Connection conn, int id, int level) throws SQLException {   
        level++;   
      String sql="select * from t_client where pid=?";   
        PreparedStatement pstmt=null;   
        ResultSet rs=null;   
      try {   
        pstmt=conn.prepareStatement(sql);   
        pstmt.setInt(1,id );   
        rs=pstmt.executeQuery();   
        while(rs.next()){   
            sbTree.append("<div >");   
            for(int i=0;i<level-1;i++){   
                sbTree.append("<img src=\"../images/white.gif\" />");   
            }   
            if("N".equals(rs.getString("is_leaf"))){   
                sbTree.append("<img id=\"img"+rs.getInt("id")+"\" src=\"../images/plus.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                       .append("<img id=\"im"+rs.getInt("id")+"\" src=\" ../images/closedfold.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                       .append(rs.getString("name"));   
                 //递归       
                 sbTree.append("<div style=\"display:none;\" id=\"div"+rs.getInt("id")+"\">");   
                    read(conn,rs.getInt("id"),level);   
                 sbTree.append("</div>");   
  
            }else{   
                sbTree.append("<img src=\"../images/minus.gif\"/>")   
                      .append("<img src=\" ../images/openfold.gif\"/>")   
                      .append(rs.getString("name"));   
            }   
            sbTree.append("</div>");   
        }   
           
    } finally{   
        DB.close(rs);   
        DB.close(pstmt);   
    }   
    }   
      

/第四步:在文字上添加链接,使得在某个地方显示对应的内容  
    Java代码 
  /**  
 
 
 * 递归读取分销商树  
 *   
 * 1.用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
 * 2.加上<div>,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
 * 3.在图片"+"和"-"上添加鼠标事件,使树能实现收缩和关闭同时图片也做改变;在图片"打开的文件夹"和"关闭的文件夹"上添加鼠标事件;  
 * 4.在文字上添加链接,使得在某个地方显示对应的内容  
 *   
 * @param conn  
 * @param id   
 * @param level 控制层次的  
 * @throws SQLException   
 */  
private void read(Connection conn, int id, int level) throws SQLException {   
    level++;   
  String sql="select * from t_client where pid=?";   
    PreparedStatement pstmt=null;   
    ResultSet rs=null;   
  try {   
    pstmt=conn.prepareStatement(sql);   
    pstmt.setInt(1,id );   
    rs=pstmt.executeQuery();   
    while(rs.next()){   
        sbTree.append("<div >");   
        for(int i=0;i<level-1;i++){   
            sbTree.append("<img src=\"../images/white.gif\" />");   
        }   
        if("N".equals(rs.getString("is_leaf"))){   
            sbTree.append("<img id=\"img"+rs.getInt("id")+"\" src=\"../images/plus.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                   .append("<img id=\"im"+rs.getInt("id")+"\" src=\" ../images/closedfold.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                   .append("<a href=\"client_node_crud.html?id="+rs.getInt("id")+"\" target=\"clientDispAreaFrame\">"+rs.getString("name")+"</a>");   
               
             //递归       
             sbTree.append("<div style=\"display:none;\" id=\"div"+rs.getInt("id")+"\">");   
                read(conn,rs.getInt("id"),level);   
             sbTree.append("</div>");   
  
        }else{   
            sbTree.append("<img src=\"../images/minus.gif\"/>")   
                  .append("<img src=\" ../images/openfold.gif\"/>");   
            //叶子节点分2类:一类是分销商,一类是区域   
            if ("Y".equals(rs.getString("is_client"))) {   
                sbTree.append("<a href=\"client_crud.html?id=" + rs.getInt("id") + "\" target=\"clientDispAreaFrame\">" + rs.getString("name") + "</a>");   
            }else {   
                sbTree.append("<a href=\"client_node_crud.html?id=" + rs.getInt("id") +  "\" target=\"clientDispAreaFrame\">" + rs.getString("name") + "</a>");   
            }      
        }   
        sbTree.append("</div>");   
    }   
       
} finally{   
    DB.close(rs);   
    DB.close(pstmt);   
}   
}   




----------------v1.2---------------
1、树节点的查询
----------------v1.3---------------
添加分销商
添加区域
修改区域
删除区域(递归删除)
修改分销商
查看分销商
删除分销商(递归删除)



----遇到unable to load class xxx的错误时候,是jsp编译成的class文件不存在
   解决方法:重新启动web服务
----接收的字符串参数如果是为null,则无法进行格式转换:
例:--错 误: 
        int id = Integer.parseInt(request.getParameter("id"));//如果接收到的字符串为空字符串,则无法进行格式转换
    --正确修改:
	    int id = 0;
		if (request.getParameter("id") != null) { //非空判断
			id = Integer.parseInt(request.getParameter("id")); //进行格式转换
		}
----接收的字符串参数如果是为null,则无法进行equals判断:
例:client_modify.jsp	
    --错误: 
     
    List clientLevelList = DataDictManager.getInstance().getClientLevelList();
	for (Iterator iter = clientLevelList.iterator(); iter.hasNext();) {
		ClientLevel cl = (ClientLevel)iter.next();
		String selectStr = "";
		
		//cl是从数据字典查上来的分销商等级,不为空,但是client.getClientLevel().getId()可能为空,所以应该进行非空判断
		if ( cl.getId().equals(client.getClientLevel().getId())) {
			selectStr = "selected";
	     }
	 }
	--正确:
	      //非空判断client.getClientLevel().getId()!=null 

	   	if (client.getClientLevel().getId()!=null && cl.getId().equals(client.getClientLevel().getId())) {
			selectStr = "selected";
	     }	
----刷新框架:在删除分销商和区域之后刷新左边树形展示的框架,
    即在右边子框架clientDispAreaFrame所包含的页面中写代码,实现刷新左边clientTreeFrame所包含的页面client_tree.jsp
    <frameset rows="*" cols="267,*" framespacing="0" frameborder="yes" border="1">
		<frame src="client_tree.jsp" name="clientTreeFrame"scrolling="scroll" id="clientTreeFrame" />
		<frame src="client_display_area.html" name="clientDispAreaFrame" id="clientDispAreaFrame" />
	</frameset>	   							
  例如:删除区域页面client_node_crud.jsp,调用删除代码删除节点成功之后调用刷新代码刷新左边的树;
      备注:其实刷新的目的,就是重新查询数据库,重新展示这棵树,因为刚才做了删除节点操作
  <%
      	if (command != null && "delete".equals(command)) {
		ClientManager.getInstance().deleteTreeNodeById(id);//删除节点代码
		
		//输出刷新树的js
		out.print ("<script>");
        out.print("parent.clientTreeFrame.location.href='client_tree.jsp'");//刷新
        out.print("</script>");
		out.print("删除成功!");
	}
%>
   

----定时刷新某个页面,例如每一分钟刷新一个页面:
   setTimeout("self.location.reload();",1000);//将代码放到<script type="text/javascript">...</script>块内即可。

----刷新本页:
  out.print("<script>window.location.href=window.location.href;</script>")

----刷新父页:
out.print("<script>opener.location.href=opener.location.href;</script>")

----转到指定页:
out.print("<script>window.location.href='yourpage.jsp';</script>")



1. 添加分销商:
	   client_add.jsp 
	   DataDictManager.java (查分销商等级列表)
	   ClientIdValidateServlet.java(Ajax验证涉及的servlet)
2、添加区域:client_node_add.jsp
3、修改区域:client_node_modify.jsp
4. 删除区域:client_node_crud.jsp?command=delete&id=<%=id%>	
    删除区域节点时,得同时删除下面的分销商和区域等子节点;
    ==具体步骤:
	   a>.如果是mySQL,则需要将事务的自动提交设置为false ,conn.setAutoCommit(false);
	   b>.通过当前节点的id得到当前节点对象client,先递归删除子节点,然后删除该节点;
	   c>.提交设置为false,所以在执行删除节点的sql之后,没有真正删除节点,
	      --通过client.getPid(),然后得到父节点对象,检查该父亲是否还有孩子(也就是该节是否有兄弟节点);
	      --如果没有孩子节点,则将父节点的属性is_leaf设置为true;
	      --如果有孩子节点,则将父节点的属性is_leaf不变,还是false;
	   d>.事务提交:conn.commit();
	   
	   
	 /**
	 * 递归删除树节点
	 * @param conn
	 * @param id
	 * @throws SQLException
	 */
	private void recursionDeleteTreeNodeById(Connection conn, int id) 
	throws SQLException {
		String sql = "select * from t_client where pid=?";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, id);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				if ("N".equals(rs.getString("is_leaf"))) {
					recursionDeleteTreeNodeById(conn, rs.getInt("id"));
				}
				//删除子节点
				deleteTreeNodeById(conn, rs.getInt("id"));
			}
			//删除自身
			deleteTreeNodeById(conn, id);
		}finally {
			DB.close(rs);
			DB.close(pstmt);
		}
	}



1.修改分销商:client_modify.jsp
2.查看分销商:client_detail.jsp
3.删除分销商:client_crud.jsp?command=delete&id=<%=id%>

 ========drp1.4 递归删除子节点================

 删除区域节点时,得同时删除下面的分销商和区域等子节点;
    ==具体步骤:
	   a>.如果是mySQL,则需要将事务的自动提交设置为false ,conn.setAutoCommit(false);
	   b>.通过当前节点的id得到当前节点对象client,先递归删除子节点,然后删除该节点;
	   c>.提交设置为false,所以在执行删除节点的sql之后,没有真正删除节点,
	      --通过client.getPid(),然后得到父节点对象,检查该父亲是否还有孩子(也就是该节是否有兄弟节点);
	      --如果没有孩子节点,则将父节点的属性is_leaf设置为true;
	      --如果有孩子节点,则将父节点的属性is_leaf不变,还是false;
	   d>.事务提交:conn.commit();
	   
	   
	 /**
	 * 递归删除树节点
	 * @param conn
	 * @param id
	 * @throws SQLException
	 */
	private void recursionDeleteTreeNodeById(Connection conn, int id) 
	throws SQLException {
		String sql = "select * from t_client where pid=?";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, id);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				if ("N".equals(rs.getString("is_leaf"))) {
					recursionDeleteTreeNodeById(conn, rs.getInt("id"));
				}
				//删除子节点
				deleteTreeNodeById(conn, rs.getInt("id"));
			}
			//删除自身
			deleteTreeNodeById(conn, id);
		}finally {
			DB.close(rs);
			DB.close(pstmt);
		}
	}

----------------v1.5---------------

1、修改密码
	 a>.输入旧密码,当鼠标离开之后onblur,通过ajax验证输入的旧密码是否正确(其中需要从session中取出当前用户,得到当前用户的密码)
	 b>.提交输入的新密码
	 c>.调用业务逻辑方法对当前用户进行密码修改;
	 d>.移除session中user,
	 f>.修改User对象,然后再放入session中;
 
2、会计核算期间维护


  ----------------v1.6添加物料-------------
 1.添加代码
 2.添加物料后返回到初始化页面:out.println("<script type=\"text/javascript\">history.go(-2)</script>");


物料维护
步骤:
a.添加dao层:添加com.bjsxt.drp.database.dao 给出dao层接口,然后给出MySQL和Oracle的具体的实现;
b.添加工厂类:com.bjsxt.drp.database.factory.ItemDao4MySqlFactory 
			和com.bjsxt.drp.database.factory.ItemDao4OracleFactory
			分别生产ItemDao4MySqlImpl和ItemDao4OracleImpl
			
c.添加分页类:PageModel
   页面大小,pageSize
   当前页号,pageNo
   总页数,  getTotalPages()
   下一页, getNextPageNo()
   上一页, getNextPageNo()
   首  页, getTopPageNo()
   末  页, getBottomPageNo()
d.添加ItemManager.java物料管理
e.添加DataDictManager.java , ItemCategory.java
f.添加AppException.java

----------------v1.7---------------
1、根据id查询物料
 当查询框clientIdOrName内输入物料编号或者物料名称后,表单自身提交给自身,
  同时接收查询字符串queryStr,再次查询数据库得到相应的PageModel,然后展示页面即可!

--------v1.8-物料分页查询--------

a.添加分页类:PageModel

   页面大小,pageSize
   当前页号,pageNo
   总页数,  getTotalPages()
   下一页, getNextPageNo()
   上一页, getNextPageNo()
   首  页, getTopPageNo()
   末  页, getBottomPageNo()
b.ItemManager.java物料管理类
 --根据条件分页查询:
      PageModel pageModel = ItemManager.getInstance().findAllItem(pageNo, pageSize, queryStr);
       其中,页面编号pageNo,查询字符串queryStr是变化的,pageSize是可以不变的
      
  --重点查询语句:select a.item_no, a.item_name, a.spec, a.pattern, a.category as category_id, 
                (select b.name from t_data_dict b where a.category=b.id) as category_name,
                a.unit as unit_id, (select c.name from t_data_dict c where a.unit=c.id) as unit_name
          from t_items a 
          order by a.item_no
          limit 0,3
  
  
----------------v1.9---------------
1、采用动态代理为Dao层加入日志
 ItemDao4MySqlFactory.java 
 LogHandler.java
 
 
 ----------------v2.0文件上传---------------
1、通过<init-param>配置保存上传文件的目录,该目录也是加载图片的目录
   <servlet>
		<servlet-name>FileUpload</servlet-name>
		<servlet-class>com.bjsxt.drp.util.servlet.FileUpload</servlet-class>
		<init-param>
			<param-name>upload_path</param-name>
			<param-value>C:\\workspace\\drp2.7\\WebRoot\\images\\item\</param-value>
		</init-param>
	</servlet>  	
	
	<servlet-mapping>
		<servlet-name>FileUpload</servlet-name>
		<url-pattern>/servlet/FileUpload</url-pattern>
	</servlet-mapping>
	
2.上传代码,参考: FileUpLoad.java

----------------v2.1---------------
1、物料修改
 重点1:选中一条记录之后进行修改,如何用js判断选中了一条记录
   function modifyItem() {
	 var count=0;
	 var j=0;
	 for(var i=0;i<document.getElementsByName("selectFlag").length;i++){
		  if(document.getElementsByName("selectFlag")[i].checked){
		     j=i;  //最后一个被选中复选框的下标
		   count++; //选中的个数
		  }
	  
	 }
	 if(count==0){
	  alert("请选择需要修改的物料!");
	 return ;
	 }
	 
	 if(count>1){
	  alert("一次只能修改一个物料!");
	  return ;
	 }
	 window.self.location = "item_modify.jsp?itemNo=" + document.getElementsByName("selectFlag")[j].value;
	}
重点2:
  如果有下拉列表,则要有一个默认选中状态;
   <td>
	<select name="unit" class="select1" id="unit">
		<% 
		for(Iterator unitIter= itemUnitList.iterator();unitIter.hasNext();  ){
		   ItemUnit iu= (ItemUnit)unitIter.next();
		   String selected="";
		   if(iu.getId().equals(item.getUnit().getId() )){
		     selected="selected";
		   }
		%>
			<option value="盒" value="<%=iu.getId() %>" <%=selected%>><!--默认选中-->
				<%=iu.getName() %>
			</option>
		<%} %>	
	</select>
</td>

2、物料删除

	function deleteItem() {
	    var count=0;
		for(var i=0;i<document.getElementsByName("selectFlag").length;i++){
		  if(document.getElementsByName("selectFlag")[i].checked){
		   count++;
		  }
		 }
		  if(count<=0){
		   alert("请选择需要删除的物料!");
		   return;
		  }
		  if(window.confirm("确认删除吗?")){
		    with(document.getElementById("itemForm")){
		     action="item_maint.jsp?command=delete&clientIdOrName=<%=queryStr%>"
		     method="post";
		     submit();
		    
		    }
		  
		  
		  }
	  
	 }
	
	


3、物料详细信息
重点:查询SQL
 select a.item_no, a.item_name, a.spec, a.pattern, a.category as category_id,
      (select b.name from t_data_dict b where a.category=b.id) as category_name,
			a.unit as unit_id, 
			(select c.name from t_data_dict c where a.unit=c.id) as unit_name 
 from t_items a 
 where a.item_no=?



----------------v2.2---------------
1、流向单添加
2、重点:采用JDK动态代理为FlowCardManager接口添加事务管理,
         参考:FlowCardManagerFactory.java,TransactionHandler.java
3、流向单查询
4、流向单删除
5、流向单送审
6、流向单明细查询

---------------------------------------------------------------------------------------------------------
      采用 ThreadLocal封装Connection(解决线程安全)参见:ConnectionManager.java :
     DrpUtil.java 
     ErrorInfo.java
     TransactionHandler.java
1、流向单添加
  
   a.ClientManager.java添加查找所有分销商,返回分页模型PageModel:
       --public PageModel findAllClient(int pageNo, int pageSize, String queryStr);
       
   b.用js添加一行表格:flow_card_add.jsp
    function addOneLineOnClick() {
		var row=tblFlowCardDetail.insertRow(tblFlowCardDetail.rows.length);
		var col = row.insertCell(0);
		col.innerHTML = "<input readonly=\"true\" maxLength=6 size=6 name=aimId><input type=button  value =...   name=btnSelectAimClient index=\""+ rowIndex +"\" onclick=\"selectAimClient(this.index)\">";
		col = row.insertCell(1);
		col.innerHTML = "<tr><input id=aimName name=aimName size=25 maxlength=25 readonly=\"true\">";
		col = row.insertCell(2);
		col.innerHTML = "<input readonly=\"true\" maxLength=6 size=6 name=itemNo><input type=button  value =...   name=btnSelectItem index=\""+ rowIndex +"\" onclick=\"selectItem(this.index)\">";
		col = row.insertCell(3);
		col.innerHTML = "<input id=itemName name=itemName size=25 maxlength=25 readonly=\"true\">";		
		col = row.insertCell(4);
		col.innerHTML = "<input id=spec name=spec size=10 maxlength=10 readonly=\"true\">";
		col = row.insertCell(5);
		col.innerHTML = "<input id=pattern name=pattern size=10 maxlength=10 readonly=\"true\">";
		col = row.insertCell(6);
		col.innerHTML = "<input id=unit name=unit size=4 maxlength=4 readonly=\"true\">";
		col = row.insertCell(7);
		col.innerHTML = "<input id=qty name=qty size=6 maxlength=6>";
		col = row.insertCell(8);
		col.innerHTML = "<input type='button' value='删除' id=btnDeleteLine name=btnDeleteLine onclick=\"return DeleteRow('row" + rowIndex + "')\"></tr>";
		row.setAttribute("id", "row" + rowIndex);
		//row.setAttribute("name", "row" + rowIndex);
		rowIndex++;
	}
	--------------------------------------------------------------------------------
	//选择需方客户窗口:aim_client_select.jsp
	
	  function selectAimClient(index) {
		window.open('aim_client_select.jsp?index=' + index, '请选择需方客户', 'width=700, height=400, scrollbars=no');
    }   
    
   //在子窗口aim_client_select.jsp中选择需方客户后将其添加到父窗口flow_card_add.jsp中
    function doubleclick(aimId, aimName) {
		var rowLength = window.opener.document.all.tblFlowCardDetail.rows.length
		if (rowLength == 2) {
			window.opener.document.all.aimId.value = aimId;
			window.opener.document.all.aimName.value = aimName;
		} else {
			window.opener.document.all.aimId[<%=index%>].value = aimId;
			window.opener.document.all.aimName[<%=index%>].value = aimName;
		}
		window.close();
	}

   -----------------------------------------------------------
     //选择物料窗口
    function selectItem(index) {
		window.open('item_select.jsp?index=' + index, '请选择物料', 'width=700, height=400, scrollbars=no');
    } 
  
   //在子窗口item_select.jsp中选择一个物料之后将其添加到父窗口flow_card_add.jsp中
    function doubleclick(itemNo, itemName, spec, pattern, unit) {
		var rowLength = window.opener.document.all.tblFlowCardDetail.rows.length;
		if (rowLength == 2) {
			window.opener.document.all.itemNo.value = itemNo;
			window.opener.document.all.itemName.value = itemName;
			window.opener.document.all.spec.value = spec;
			window.opener.document.all.pattern.value = pattern;
			window.opener.document.all.unit.value = unit;
		}else {
			window.opener.document.all.itemNo[<%=index%>].value = itemNo;
			window.opener.document.all.itemName[<%=index%>].value = itemName;
			window.opener.document.all.spec[<%=index%>].value = spec;
			window.opener.document.all.pattern[<%=index%>].value = pattern;
			window.opener.document.all.unit[<%=index%>].value = unit;
		}
		window.close();
	}
    
   
   
2、DRP采用JDK动态代理为FlowCardManager接口添加事务管理 
   一个业务逻辑类ManagerImpl的方法A中可能要包含DAO层类DaoImpl中多个的方法B,C,...的调用;
   在业务逻辑类ManagerImpl上通过JDK动态代理添加事务,动态代理的职能如下:
    a. 假如在指定的add*,delete*,modify*,方法执行前打开连接;
    b. 将事务的自动提交设置为false;
    c. 业务逻辑方法执行(其中多次调用DAO层的方法B,C,....,)
    			多次调用DAO层的方法B,C,....,其中得注意2点:
    			 1.我们使用的ConnectionManager.getConnection();得到的是一个放入ThreadLocal的连接,也就是同一线程共同使用的一个连接,
    			   因为在A方法中调用方法B,C...所以B,C得到的数据库连接都是同一个连接
    			 2.Dao方法B,C...的执行只是执行SQL语句,并没有提交事务,也没有关闭连接...以及失败的回滚等,这些操作都由A方法执行完毕后,由动态代理来做;
    e. 出错的情况下,让事务回滚;
    f. 最后关闭连接;
    如果想理解上面的这些话,请这么做:
    1.在ConnectionManager.java 的方法public static Connection getConnection() 中的下面一句上设断点
         Connection conn = (Connection)connectionHolder.get();
    2.启动web服务;
    3.点击分销商库存管理中的流向单维护,会执行业务逻辑方法findAllFlowCard,
         其中包括2个DAO层方法的调用findAllFlowCard和addFlowCardDetail
    4.F6--可一观察到动态代理和业务逻辑方法和dao层方法的执行流程,以及ThreadLocal的Connection的创建次数(就一次)
    
     事务加入请参见:FlowCardManagerFactory.java
	     /**
		 * 创建FlowCardManager,动态加入事务
		 * @return
		 */
      public FlowCardManager createFlowCardManager() {
		FlowCardManager flowCardManager = new FlowCardManagerImpl(this.flowCardDao);
		TransactionHandler transactionHandler = new TransactionHandler();//动态加入事务
		return (FlowCardManager)transactionHandler.newProxyObject(flowCardManager);
	}
	
	
	
	
3、流向单查询
   a.双击子窗口窗口的某一行记录;将子窗口中某条记录的值传递到父窗口;然后关闭子窗口;父窗口显示刚才选择的信息;
    //双击单选钮
	function doubleclick(clientId, clientName) {
		window.opener.document.getElementById("clientId").value = clientId;	//给父窗口的元素赋值
		window.opener.document.getElementById("clientName").value = clientName;	//给父窗口的元素赋值
		window.close(); //关闭当前窗口
	}
   
4、流向单删除
5、流向单送审
6、流向单明细查询


----------------v2.4---------------
1、Jfreechart的使用
2、采用Ajax实现html下拉列表联动

----------------v2.5---------------
1、验证码的生成
----------------v2.6---------------
1、采用filter解决session为空

----------------v2.7---------------
1、<context-param>  测试test_context_param.jsp
2、taglib           测试test_tag.jsp
3、Listener
4、tomcat连接池配置   DB.java

5.web.xml配置错误处理:
  
 类型一:自定义异常处理
   <error-page>
   	<exception-type>com.bjsxt.drp.exceptions.AppException</exception-type>
   	<location>/error.jsp</location>
   </error-page>
    1.定义异常类AppException.java,通过super(msg);将异常信息传到父类RuntimeException中,
    public class AppException extends RuntimeException {
	
	private int errorCode;
	
	public AppException(String msg) {
		super(msg);
	}
	public AppException(int errorCode) {
		this.errorCode = errorCode;
	}
	public int getErrorCode() {
		return errorCode;
	}
	
}  
   2.在使用的地方向上抛出异常
     例如:
      try {
			..............
		} catch (SQLException e) {
			throw new AppException("删除物料失败");
		} finally {
			...............
		}
   3.根据web.xml文件配置,抛出异常com.bjsxt.drp.exceptions.AppException后转向error.jsp页面 
   4.在错误处理页面error.jsp中通过以下代码得到错误信息
     <%=exception.getMessage()%>
	(注意:错误页面开头部分要注明是错误页面:<%@ page isErrorPage="true" %> )
	
类型二:错误码处理
1.	<!--如果错误码是404或者500则转向error.jsp页面 ,做相应处理 -->
  <error-page>
  	<error-code>404</error-code>
  	<location>/http_error.jsp</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/http_error.jsp</location>
  </error-page>
  
  2.http_error.jsp
  
    <%
        //得到错误码request.getAttribute("javax.servlet.error.status_code")
		Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
		if (statusCode.intValue() == 404) {
			response.sendRedirect(request.getContextPath() + "/404.html");
		}else if (statusCode.intValue() == 500) {
			response.sendRedirect(request.getContextPath() + "/500.html");
		}		
	 %>
  
2009-04-12

浅谈SOA

关键字: 浅谈soa
1.SOA的定义
  SOA全名为面向服务的体系结构(Service-oriented architechture) 它是一种软件架构模型。SOA将应用程序的各个应用的各个功能单元间通过定义良好的接口和契约联系起来,而这种不同功能单元被作为服务。服务间接口是采用中立的方式定义的,它独立于实现服务的硬件平台,操作系统和编程语言等环境。这样,服务间将采用通用的,统一的和系统平台无关的方式进行交互。SOA的特性是“服务的封装”,“服务的重用”和“服务的互动”SOA系统的需求源自于业务应用系统需求,SOA系统可以根据业务的需要不断的将每一个独立的“服务”组合,以适应不断变化的环境,比如经常改变的合作伙伴关系,业务级别,业务重点,政策,行业地位以及其他与业务有关因素的更改,每一个服务都是一个独立的个体。

2.SOA的应用
  SOA并不是一种新的技术,它是一种应用架构模型,是不完全依赖于技术的应用架构模型,SOA的技术实现方式可以有多种,是多种技术的集合模型,其次,SOA是通常基于可扩展标记语言(xml),通过使用WSDL语言(称为web服务描述语言Web Service Definition Language,WSDL)来描述接口。再次WebService并不是实现SOA唯一方式,还有CORBA。SOA鼓励使用可替代的技术和消息机制,通过把服务联系在一起,来满足应用,而且SOA的系统并不排除,使用面向对象的设计来构建单个服务

3.SOA的商业应用思想
  SOA的一个中心思想就是企业应用彻底摆脱面向技术的解决方案的束缚,轻松自如的应付对企业商业服务的变化,发展的需要。企业IT架构环境中单个应用程序是无法包容用户的各种业务需求的,即使是一个大型的ERP的解决方案,仍然不能满足这个用户不断膨胀变化的业务需求。原来为了对市场快速做出反应,商业企业只能通过不断开发新应用,扩展现有应用来支撑其现有业务需求,今后商业企业采用SOA后,通过将注意力放在服务上,应用程序能够集中起来提供更加丰富,目的性更强的商业流程,其结果就是,基于SOA的企业应用会更加真实地反映出与业务模型的结合,SOA商业应用思想是为:“业务驱动服务,服务驱动技术 ”。服务是从业务流程的角度来看待技术的,这同一般的从可用技术所驱动的商业视角不同的,服务的优势已经清晰可见的,服务同业务流程结合在一起能够更加准确地表示业务模型,更好地支撑业务流程。

对于企业用户来说,SOA根本的目标是解决“信息孤岛”问题,并能提供随需应变的服务,SOA通过将原有的应用和资源转变为可共享的标准服务,打破了“信息孤岛”,企业决策者只需要根据企业的策列来定制流程把应用作为服务。“随需获得”而无需考虑底层集成,这样可以实现IT和企业业务之间的“业务驱动服务,服务驱动技术”。
2009-04-07

UML顺序图

关键字: uml顺序图
UML的顺序图:
  我们画顺序图只将正常情况下的执行路径画出来,例如我们判断用户是否存在,密码是否正确,我们只将用户存在和密码正确的流程画出来;至于不正确的情况都画出来,那是在活动图中才会这么做
  顺序图的作用是什么呢?
  我们通过画顺序图,我们要分析出实体模型类,各个实体的职责分明;此外最重要的是我们画完顺序图后可以给给业务逻辑类定下接口。在各个关联箭头上点击右键 选择<new operation>操作,此时所有的类,就有了方法列表;通过这种方法我们可以给业务逻辑类定下接口(包含的具体参数);
2009-04-06

ftp客户端

关键字: ftp客户端
ftp客户端ftp客户端ftp客户端ftp客户端
2009-03-27

权限管理

关键字: 权限管理
权限管理由三部分组成:
  授权、登录、认证

1.======================授权======================
 
 a.改变CRUD权限--
 	public void addOrUpdatePermission(String principalType, int principalId,
																		int moduleId, int permission, boolean yes);
 b.改变用户继承权限(是否是继承字角色)--
  public void addOrUpdateUserExtends(int userId, int moduleId, boolean yes);	
  													
2.=======================登录=========================
   a.loginAction中负责查看用户名密码是否正确,如果正确,则将用户名存入session管理,
   b.成功登陆,从session中拿到用户对象,查询用户拥有的角色,并按优先级从低到高排序
   c.依次查找角色的授权列表,放入map(key为moduleId,value为acl)
   d.针对用户查找有效的用户授权列表,放入同一个map;
   e.去除掉那些没有读取权限的授权记录
   f.根据最后map中的
     
		      public List searchModules(int userId) {
				
				//查询用户拥有的角色,并按优先级从低到高排序
				String hql = "select r.id from UsersRoles ur join ur.role r join ur.user u " +
				"where u.id = ? order by ur.orderNo desc";
				List roleIds = getHibernateTemplate().find(hql, userId);
				
				Map temp = new HashMap();
				
				//依次查找角色的授权列表
				for (Iterator iterator = roleIds.iterator(); iterator.hasNext();) {
					Integer rid = (Integer) iterator.next();
					List acls = findRoleAcls(rid);
					for (Iterator iterator2 = acls.iterator(); iterator2.hasNext();) {
						ACL acl = (ACL) iterator2.next();
						temp.put(acl.getModuleId(), acl);
					}
				}
				
				//针对用户查找有效的用户授权列表
				List acls = findUserAcls(userId);
				for (Iterator iterator = acls.iterator(); iterator.hasNext();) {
					ACL acl = (ACL) iterator.next();
					temp.put(acl.getModuleId(), acl);
				}
				
				//去除掉那些没有读取权限的授权记录
				Set entries = temp.entrySet();
				for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
					Map.Entry entry = (Map.Entry) iterator.next();
					ACL acl = (ACL)entry.getValue();
					if(acl.getPermission(Permission.READ) != ACL.ACL_YES){
						iterator.remove();
					}
				}
				
				if(temp.isEmpty()){
					return null;
				}
				
				String searchModules = "select m from Module m where m.id in (:ids) order by m.orderNo";
				return getSession().createQuery(searchModules)
						.setParameterList("ids", temp.keySet())
						.list();
			}
			
3.======================认证======================
   --用户界面的每个CRUD操作相关的按钮和链接,通过认证决定其显示与否。
   
     JSTL自定义函数:
		<c:if test="${my:hasPermission(login.id,'orgmgr',CREATE)}">
						 <a href="#" onclick="openWin('org.do?method=addInput&parentId=${orgForm.parentId }','addorg',600,200);">添加机构信息</a>
		</c:if>
2009-02-23

我的面试经历

关键字: 我的面试经历
近段时间想换份工作,原来的单位是一家工厂it部3个人包括我负责工厂的erp(其实也不知道是不是erp,只是一堆有点联系管理系统)开发和维护。做了1年了感觉在那里不是一个长远呆下去的地方因为我不想一背子对着一个系统。在网上看到一家hk电信上市的子公司开我们城市开了一个分公司请开发的(ssh+jsf+ajax+oracle+linux),象发现新大陆一样马上就发了简历,凭着5年的工作经验和对以上技术有点了解(现在做的就是ssh、ajax,oracle3年前也用过8i、9i,linux就比较生疏只配过几次开发环境)还有信心可以去面试。



结果简历发去出一个月了也没有回音想要放弃了,但是在第5周接到了面试通知,感觉机会来了。在预定的时候去了面试,见面的只是一个人事部的美女一看就有点hk人的味道。填了一份表格,连毕业证书也没叫我拿来看看就给了一份题目我做。一看题目全是english就有点傻了,幸好定下心来还是70%看得懂(题目都很短,都是选择题)。内容都是比较基础的问题,关于treeset、jsp内建对象的、oracle基础语句的、设计模型的、ajax的等等都是很基础的。做了几道一时间明白了什么叫“浅水淹死人”。做完之后只记得treeset的不懂、oracle的“||”符号忘记什么意思了、设计模型的不会没选。最后和hr小姐聊了几句,她只是问了我现在的工作情况。印象最深的是她问“你现在的公司是台资企业,人家都说台资制度最苛刻,你感觉怎么样?”我回答:“其实进去的时候就看过员工手册里面都有规定的,只要原来规定了不是随便莽加的自己就可以接受都可以遵守!”她点点头笑了一下,这样第一次面试结束了她说会在1周内给电话通知下一次hk派技术人员来面试。走的时候感觉希望不大了,因为感觉题目做得不好。





过了5天竟然接到了3天后面试的电话通知,一时间有点紧张了(我比较在乎这份工作,毕竟是上市公司想进去见识一下)。这几天就拼命的啃书,上网找面试题目。hibernate的1:n、n:n,spring的ioc、aop、struts的基础知识oracle基础语句等等都看了一下,终于到了面试的时候了。



[b]见面在一个会议室一老一少标准的hk人的味道尤其是那个年长的,一坐下就叫我自我介绍一下。我就把这几年做过的几家公司和我做过的一些项目的情况介绍了一遍。在我介绍的时候他们会不时提问我一些细节,例如在设计数据库的时候“你有用什么方法或者什么工具帮忙设计还是凭直觉?”。听了被他吓了一下想了想回答:“现在没有用到什么工具,但是我知道可以用user case、uml图之类的帮忙,只是我觉得自己在这些技术上掌握得还不是很好没用到。但是不能说凭直觉去设计应该是经验+直觉吧!毕竟现在做项目的时候很少一下就设计几十个表都是3、4个表累加起来的,经验+直觉可以应付得了而且效率也高。”。看了他的表情感觉他也满意我的回答。“在什么情况下你会对数据库添加表格?在什么情况下决定用存储过程?”,我回答“先看当前数据库里的数据是否满足新的应用如果满足就不加,没有的就加。尽量不添加表格,但是如果添加表格对系统的性能或者维护性有好处的也可以添加。至于是否使用存储过程主要看效率的要求吧,但是尽量不使用存储过程,因为他的可维护性没有java代码强。”他听了好象也满意。还问和很多问题例如你现在的工作流程是怎么样的?是怎么做需求分析?你现在做的系统的处理流程是怎么样的(其实就ssh的工作流程)?都是一些比较宏观的问题基本没有问到技术细节。[/b]说了一个多小时我每回答一个问题他们都回在我填写的简历上记录一些东西(很想看他们写了什么就是看不到)。临做的时候最后问了我两个问题也是最难的“如果日后办公都是english的办公环境例如公司内部的email都是用english和hk联系的,你认为你要用多长时间可以适应呢?你有毕业成绩单吗?”我傻了硬着头皮说“english的话可能要6个月到1年时间去适应(当年4级40多分的水平能用这个时间去适应我觉得我成功了。)。5年前的毕业成绩单可能找不到了只能回去找找看!”



这样面试结束了,如果没有最后的两个问题我感觉我一定可以被录取可惜.......前两天hr小姐真的给电话问我要成绩单了。但是我真的找不到只能直接回复说没有了,她说要告诉hk的同事看怎么处理了。我多问了两句她就回我说你笔试和面试都基本没有什么问题,就因为你不是计算机毕业的想了解一下你学过的计算机课程。听了半喜半悲,正常情况下笔试和面试过了应该就没问题了,但是没有成绩单也存在变数。有可能他们是新公司新团队想要成绩好的新人培养,总之一天没电话来说我被录取了就不安心。希望能有一个好的结果,好让老婆和快出生的孩子过上好一点的生活!

2009-02-22

JAVA面试题集

文章分类:Java编程
JAVA面试题集



海洋之心 发表于 2005-9-28 15:22:00

基础知识: 
1.C++或Java中的异常处理机制的简单原理和应用。 
当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发 NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用 throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。 
2. Java的接口和C++的虚类的相同和不同处。 
由于Java不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是 public static,所有方法默认情况下是public.一个类可以实现多个接口。 
3. 垃圾回收的优点和原理。并考虑2种回收机制。 
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。 
4. 请说出你所知道的线程同步的方法。 
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。 
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。 
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。 
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。 
5. 请讲一讲析构函数和虚函数的用法和作用。 
6. Error与Exception有什么区别? 
Error表示系统级的错误和程序不必处理的异常, 
Exception表示需要捕捉或者需要程序进行处理的异常。 
7. 在java中一个类被声明为final类型,表示了什么意思? 
表示该类不能被继承,是最终类。 
8. 描述一下你最常用的编程风格。 
9. heap和stack有什么区别。 
栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。 
堆是栈的一个组成元素 
10. 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算)。 
public class BigInt() 
{ 
int[] ArrOne = new ArrOne[1000]; 
String intString=""; 
public int[] Arr(String s) 
{ 
intString = s; 
for(int i=0;i<ArrOne.leght;i++) 
{ 
11. 如果要设计一个图形系统,请你设计基本的图形元件(Point,Line,Rectangle,Triangle)的简单实现 
12,谈谈final, finally, finalize的区别。 
  final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。 
  finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 
  finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。 
13,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 
  匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现。 
14,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。 
  Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&page=1 
  注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象 
第四,&和&&的区别。 
  &是位运算符。&&是布尔逻辑运算符。 
15,HashMap和Hashtable的区别。 
  都属于Map接口的类,实现了将惟一键映射到特定的值上。 
  HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。 
  Hashtable 类似于 HashMap,但是不允许 null 键和 null 值。它也比 HashMap 慢,因为它是同步的。 
16,Collection 和 Collections的区别。 
  Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。 
  Collection是个java.util下的接口,它是各种集合结构的父接口。 
17,什么时候用assert。 
  断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true。如果表达式计算为 false,那么系统会报告一个 Assertionerror。它用于调试目的: 
assert(a > 0); // throws an Assertionerror if a <= 0 
断言可以有两种形式: 
assert Expression1 ; 
assert Expression1 : Expression2 ; 
  Expression1 应该总是产生一个布尔值。 
  Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。 
  断言在默认情况下是禁用的。要在编译时启用断言,需要使用 source 1.4 标记: 
  javac -source 1.4 Test.java 
  要在运行时启用断言,可使用 -enableassertions 或者 -ea 标记。 
  要在运行时选择禁用断言,可使用 -da 或者 -disableassertions 标记。 
  要系统类中启用断言,可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。 
  可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。 
18,GC是什么? 为什么要有GC? (基础)。 
	GC是垃圾收集器。Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。
要请求垃圾收集,调用下面的方法之一: 
System.gc() 
Runtime.getRuntime().gc() 
19,String s = new String("xyz");创建了几个String Object? 
  两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。 
20,Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 
  Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11; 
21,short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 
	short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。 
注意:byte,short,char之间不会互相转换,他们三者在计算时首先回转换为int类型
容量大的数据类型转换为容量小的数据类型时,要加上强制转换符,但可能造成精度降低或溢出;使用时要格外注意。
	
22,sleep() 和 wait() 有什么区别? 搞线程的最爱 
  sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级 (b)正在运行的线程因为其它原因而阻塞。 
	wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。 

Wait时别的线程可以访问锁定对象
调用wait方法的时候必需锁定该对象
Object提供的方法
Sleep时别的线程也不可以访问锁定对象
Thread提供的方法
	
23,Java有没有goto? 
  Goto—java中的保留字,现在没有在java中使用。 
24,数组有没有length()这个方法? String有没有length()这个方法? 
  数组没有length()这个方法,有length的属性。 
  String有有length()这个方法。 
25,Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 
	方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。
	如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 
	
+26,Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 
  Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。 
  equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。 
27,给我一个你最常见到的runtime exception。 
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, 
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException 
28,error和exception有什么区别? 











 

 error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 
  exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。如被 0 除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。

29,List, Set, Map是否继承自Collection接口? 
List,Set是 (参考61题)
Map不是 
30,abstract class和interface有什么区别? 
	声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。
	不能创建abstract 类的实例。
	然而

  


  
分享到:
评论

相关推荐

    oa办公系统源码

    利用Struts2、Spring和Hibernate三大框架和json解析技术以及jQuery实现了用户的登录以及对数据的增删改查

    java开发oa办公系统源码-oa_system:OA自动化办公系统

    java开发oa办公系统源码 1. 项目介绍 本项目是一个OA办公自动化系统,使用Maven进行项目管理,基于Springboot框架开发的项目,MySQL底层数据库,前端采用Freemarker模板引擎,Bootstrap作为前端UI框架,集成了jpa、...

    java开发oa办公系统源码-CDBOO:创建

    java开发oa办公系统源码 展示机终端管理系统软件需求规格说明书V1.0 平台简介 JeeSite是基于多个优秀的开源项目,高度整合封装而成的高效,高性能,强安全性的开源Java EE快速开发平台。 JeeSite本身是以Spring ...

    oa源码java下载-biblio-glutton:高性能书目信息服务

    oa源码java下载书目饕餮 专用于书目信息的框架。 这包括: 书目参考匹配服务:从原始书目参考和/或关键元数据的组合等输入中,该服务将返回消歧的书目对象,特别是其 DOI 和从 CrossRef 和其他来源聚合的一组元数据...

    workflow实现的源代码

    一个完整OA/workflow实现的源代码

    java开发oa办公系统源码-oasys:绿洲

    java开发oa办公系统源码 oasys(OA自动化办公系统) 1.项目介绍 oasys是一个OA办公自动化系统,使用Maven进行项目管理,基于springboot框架开发的项目,mysql底层数据库,前端采用freemarker模板引擎,Bootstrap作为...

    力软Learun敏捷开发框架源码v7.0,开发手册,数据库备份、脚本

    力软.NET低代码快速开发...可以扩展开发OA、CRM、ERP、MES、人事管理、资源管理等各种管理系统,支持sqlserver、oracle、MySQL、redis、postgreSQL、达梦、人大金仓等数据库,提升90%的开发效率,降低80%的人工成本。

    java开发oa办公系统源码-bootdo-master:引导大师

    java开发oa办公系统源码 BootDo 面向学习型的开源框架 平台简介 BootDo是高效率,低封装,面向学习型,面向微服的开源Java EE开发框架。 BootDo是在SpringBoot基础上搭建的一个Java基础开发平台,MyBatis为数据访问...

    vc++ 应用源码包_3

    从fnMyDownload开始,程序首先解析输入的url,拆分为地址,路径,文件名等。然后获取文件头,得到文件大小,然后再下载。重点函数是ThreadDownLoad。下载完之后用FileCombine合并文件。Mydownload.cpp底端的...

    50个微信小程序源码.zip

    50个微信小程序源码: AppleMusic B站首页界面设计:附详细教程 cnode社区版 dribbble FlexLayout布局 gank HIapp IT-EBOOK leantodu LOL战绩查询 movecss效果 Railay:整体框架 redux绑定 TCP,IP长连接 todo list v2...

    vc++ 开发实例源码包

    内含(重启、图片操作、ip操作、键盘与鼠标、客户端以及服务端、文件传输等实例源码) 多个VC++加密解密算法库(CRYPT++) 详细讲解了Crypt++的加密解密的使用以及其它的加密解密方法(例如base64加解密、哈希加...

    vc++ 应用源码包_1

    从fnMyDownload开始,程序首先解析输入的url,拆分为地址,路径,文件名等。然后获取文件头,得到文件大小,然后再下载。重点函数是ThreadDownLoad。下载完之后用FileCombine合并文件。Mydownload.cpp底端的...

    vc++ 应用源码包_5

    从fnMyDownload开始,程序首先解析输入的url,拆分为地址,路径,文件名等。然后获取文件头,得到文件大小,然后再下载。重点函数是ThreadDownLoad。下载完之后用FileCombine合并文件。Mydownload.cpp底端的...

    vc++ 应用源码包_2

    从fnMyDownload开始,程序首先解析输入的url,拆分为地址,路径,文件名等。然后获取文件头,得到文件大小,然后再下载。重点函数是ThreadDownLoad。下载完之后用FileCombine合并文件。Mydownload.cpp底端的...

    vc++ 应用源码包_6

    从fnMyDownload开始,程序首先解析输入的url,拆分为地址,路径,文件名等。然后获取文件头,得到文件大小,然后再下载。重点函数是ThreadDownLoad。下载完之后用FileCombine合并文件。Mydownload.cpp底端的...

    thinkphp5框架路由原理与用法详解

    路由其实就是把真实的url地址隐藏起来,使用访问地址来访问应用(网站或OA等)。 通常这样定义:“访问地址”=》“真实地址”,这代表了一种映射关系。就好比用“1”代表去肯德基吃饭,用“0”代表去麦当劳吃饭,你...

    2000个小程序精选源码(包含49个行业)

    │ │ 企业OA系统小程序.zip │ │ │ ├─优惠券卡卷(1个) │ │ 优惠券卡卷小程序.zip │ │ │ ├─促销抽奖(2个) │ │ 幸运大抽奖.zip │ │ 购物节抽奖小程序.zip │ │ │ ├─保险行业(1个...

    java饿汉式的应用源码-beamtoolbox:按类别精选的BEAM语言库

    java饿汉式的应用源码梁工具箱 按类别精选 BEAM 语言库。 所有的杀手,没有填充物。 网站 (即将推出) 关于 BEAM 生态系统庞大且难以驾驭。 对于任何任务,您必须评估以下选项: Erlang stdlib (OTP) 长生不老药...

    java面试题及技巧4

    │ │ javascript资料(源码,教材,ppt).rar │ │ │ └─javascript资料(源码,教材,ppt) │ 00s.jpg │ 10fdada.gif │ 1102485678850.gif │ 1102513845804.gif │ 1102525271916.gif │ 1102554652413.gif ...

    如意通 RooyeeMessenger 企业即时通讯 Delphi源代码

    基于XMPP(IETF国际标准组织IM通讯标准)、DNS 集群通讯解析,实现S2S(服务器与服务器之间)的通讯服务器集群应用。解决目前企业即时通讯系统不能互联互通的难题,开拓分众即时通讯互联互通的先河,并提供软件插件...

Global site tag (gtag.js) - Google Analytics