简答题:
1.IOC容器:
IOC(Inversion of Control,控制反转)。这是spring的核心。
IOC容器具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装。
2. 静态代理
为什么需要代理?
因为我们可以在代理的时候做一些属于我们自己的操作。
3. 工厂模式
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
4. Servlet生命周期
Seevlet的生命周期由Servlet容器管理。(Tomcat是一种)
- 加载和实例化Servlet
- 初始化init()
- 执行sevice()处理请求
- 执行destroy()销毁
假如我们在代码里面把Service的方法改写了,那么这个时候的service就不是用来转向了,就是变成处理逻辑了。
5. Sevlet 时序图
6. 分层领域模型规约
一、分层领域模型规约
- DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
- DTO(Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。
- BO(Business Object):业务对象。由Service层输出的封装业务逻辑的对象。
- AO(Application Object):应用对象。在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
- VO(View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
- Query:数据查询对象,各层接收上层的查询请求。注意超过2个参数的查询封装,禁止使用Map类来传输。
二、领域模型命名规约
- 1) 数据对象:xxxDO,xxx即为数据表名。
- 2) 数据传输对象:xxxDTO,xxx为业务领域相关的名称。
- 3) 展示对象:xxxVO,xxx一般为网页名称。
- 4) POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。
7. 网络编程模型
8. MVC 框架
虚线是事件,实现是方法调用
- 视图:JSP,HTML,XML(解释模型,模型更新请求)
- 模型:bean,enity,VO,formbean(应用程序功能,封装应用程序状态)
- 控制器:Servlet,Spring(定义应用程序行为,映射用户动作,选择响应的视图)
视图和数据模型的分离:使用不同的视图对相同的数据进行展示;分离可视和不可视的组件,能够对模型进行独立测试。
视图和表现逻辑(Controller)的分离:Controller是一个表现逻辑的组件,并非一个业务逻辑组件。MVC可以作为表现模式也可以作为建构模式,意味这Controller也可以是业务逻辑。分离逻辑和具体展示,能够对逻辑进行独立测试。
- 优点:耦合性低;重用性高;生命周期成本低;部署快;可维护性高;有利软件工程化管理。
- 缺点:没有明确的定义;不适合小型,中等规模的应用程序;增加系统结构和实现的复用性;视图与控制器间的过于紧密的连接;视图对模型数据的低效率访问;一般高级的界面工具或构造器不支持模式。
编程题
1. 多线程排序
import java.util.Arrays;
import java.util.concurrent.*;
//----App Class
public App() throws InterruptedException {
int data[]={
12,434,54,6,7,0,123,4,65,23,34,1,234242,324234,232,23,23425,52};
ForkJoinTask sort = new SortWorker(data);
ForkJoinPool pool = new ForkJoinPool();
pool.submit(sort);
pool.shutdown();
pool.awaitTermination(30, TimeUnit.SECONDS);
print(data);
}
//----App Class
//----SortWorker
class SortWorker extends RecursiveAction{
private int[] data;
private int start;
private int end;
private int THRESHOLD = 0;
public SortWorker(int[] data){
this.data = data;
this.start = 0;
this.end = data.length-1;
}
public SortWorker(int[] data, int start, int end){
this.data = data;
this.start = start;
this.end = end;
}
private void swap(int[] data,int j,int j1){
int temp = data[j];
data[j] = data[j1];
data[j1] = temp;
}
private void seqSort(int[] data, int start, int end){
Arrays.sort(data, start, end+1);
}
private int partition(int[] data, int start, int end){
int x = data[end];
int i = start - 1;
for(int j = start; j< end;j++){
if (data[j]<=x){
i++;
swap(data, i, j);
}
}
swap(data, i+1, end);
return i+1;
}
protected void compute(){
if (end - start < THRESHOLD){
seqSort(data, start, end); //假如数组长度小于阈值则直接排序
}else{
//否则则使用递归拆分排序
int pivot = partition(data, start, end);
RecursiveAction.invokeAll(new SortWorker(data,start,pivot-1), new SortWorker(data, pivot+1, end));
}
}
}
2. 多线程求最大值
//----App.class
public App() throws InterruptedException {
int data[]={
12,434,54,6,7,0,123,4,65,23,34,1,234242,324234,232,23,23425,52};
ForkJoinTask<Integer> findMax = new MaxWorker(data);
ForkJoinPool pool = new ForkJoinPool(4);
Integer re = pool.invoke(findMax);
pool.shutdown();
pool.awaitTermination(30, TimeUnit.SECONDS);
System.out.println(re);
}
//---
class MaxWorker extends RecursiveTask<Integer>{
private int[] data;
private int start;
private int end;
private int THRESHOLD = 4; // 限制每个小任务的大小
public MaxWorker(int[] data){
this.data = data;
this.start = 0;
this.end = data.length;
}
public MaxWorker(int[] data, int start, int end){
this.data = data;
this.start = start;
this.end = end;
}
private Integer seqFindMax(int[] data, int start, int end){
int max = Integer.MIN_VALUE;
for(int i = start; i< end ; i++){
if(max<data[i]){
max = data[i];
}
}
return max;
}
@Override
protected Integer compute(){
Integer result = null;
if (end - start < THRESHOLD){
result = seqFindMax(data, start, end); //假如数组长度小于阈值则执行任务并且把结果返回到上层
}else{
//否则则使用递归拆分排序
int middle = (start + end) / 2;
MaxWorker left = new MaxWorker(data, start, middle);
MaxWorker right = new MaxWorker(data, middle, end);
// 拆分并并行执行两个小任务
left.fork();
right.fork();
result = Math.max(left.join(),right.join());
}
return result;
}
}
3. Web服务器:
Server.class
@Override
public void run() {
super.run();
@SuppressWarnings("resource") // Warnings iggnore
ServerSocket serverSocket = new ServerSocket(watchPort);
while (true) {
// Waitting for clients
Socket socket = serverSocket.accept();// Thread Join here
new httpServer(socket).start();// If connected, start a new server thread
}
}
httpServer.class
class httpServer extends Thread {
Socket currentSocket = null; //Client Socket
InputStream inputStream = null;//Use for get header
OutputStream outputStream = null;//Use for response
public httpServer(Socket socket) {
currentSocket = socket; //Get socket bridge
//log.info(socket.getInetAddress().toString()); //Show ip address
inputStream = socket.getInputStream(); // Get inputstream
outputStream = socket.getOutputStream(); // Get outputstream
}
@Override
public void run() {
String rawString = read(); // Get raw header
String resultString = process(rawString); // Process command
String rawResultString = response(resultString); // Pack the result
currentSocket.close();// CLose the client socket
}
read:
String[] split = rawString.split(" ");
if (split.length != 3) {
//@example as: GET /index.html HTTP/1.1
return null;
}
return split[1]; // Get path
process:
File file = new File("src/"+commandString);
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while((line = bufferedReader.readLine())!=null){
stringBuffer.append(line+"\r\n");
}
String result = stringBuffer.toString();
response:
StringBuffer responseInfo = new StringBuffer();
responseInfo.append("HTTP/1.1 200 ok \r\n");
responseInfo.append("Content-Type:text/html \r\n");
responseInfo.append("Content-Length:"+Long.toString(responseLength)+" \r\n\r\n");
responseInfo.append(resultString);
outputStream.write(rawResultString.getBytes());
outputStream.flush();
outputStream.close();
可能的客户端:
Socket client = new Socket("localhost", 9999); // 定义服务端的连接信息
// 现在的客户端需要有输入与输出的操作支持,所以依然要准备出Scanner与PrintWriter
Scanner scan = new Scanner(client.getInputStream()); // 接收服务端输入内容
scan.useDelimiter("\n");
PrintStream out = new PrintStream(client.getOutputStream()); // 向服务器端发送内容
boolean flag = true; // 循环标记
while (flag) {
// 循环处理
String input = getString("请输入要发送的内容:").trim(); // 获取键盘输入数据
out.println(input); // 加换行
if (scan.hasNext()) {
// 服务器端有回应
System.out.println(scan.next()); // 输出回应信息
}
if ("byebye".equalsIgnoreCase(input)) {
// 结束判断
flag = false; // 修改循环标记
}
}
scan.close(); // 关闭输入流
out.close(); // 关闭输 出流
client.close(); // 关闭客户端
4. JSP+Servlet+JDBC
bean-DAO-Servlet-JSP
DAO:
private static InitialContext context = null;
private DataSource dataSource = null;
if (context == null) {
context = new InitialContext();
}
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/bookDS");
执行逻辑:
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rst = null;
BookBean book = new BookBean();
try {
conn = dataSource.getConnection();
//pstmt = conn.prepareStatement("INSERT INTO books VALUES(?,?,?,?,?)");
pstmt = conn.prepareStatement("SELECT * FROM books WHERE bookid=?");
pstmt.setString(1, bookid);
rst = pstmt.executeQuery();
if (rst.next()) {
book.setBookid(rst.getString("bookid"));
book.setTitle(rst.getString("title"));
book.setAuthor(rst.getString("author"));
book.setPublisher(rst.getString("publisher"));
book.setPrice(rst.getFloat("price"));
return book;
} else {
return null;
}
Servlet:
public class BookInsertServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("gb2312");
String message = null;
BookBean book = new BookBean(request.getParameter("bookid"), request.getParameter("title"),
request.getParameter("author"), request.getParameter("publisher"),
Float.parseFloat(request.getParameter("price")));
BookDAO bookdao = new BookDAO();
boolean success = bookdao.insertBook(book);
if (success) {
message = "成功插入一条记录!";
} else {
message = "插入记录错误!";
}
request.setAttribute("result", message);
RequestDispatcher view = request.getRequestDispatcher("/bookInsert.jsp");
view.forward(request, response);
}
}
JSP:
<%@ page contentType="text/html; charset=gb2312" %>
<html>
<head>
<title>Book Query</title>
</head>
<body>
请输入一个书号:<br>
<form action="bookquery.do" method="post">
<input type="text" name="bookid"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
Web.xml:
servlet
- name
- class
mapping
- name
- url-pattern
<servlet>
<servlet-name>bookQuery</servlet-name>
<servlet-class>com.control.BookQueryServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>bookInsert</servlet-name>
<servlet-class>com.control.BookInsertServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>bookQuery</servlet-name>
<url-pattern>/bookquery.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>bookInsert</servlet-name>
<url-pattern>/bookinsert.do</url-pattern>
</servlet-mapping>
选择填空判断
jsp的九大对象:
- request 请求对象 类型 javax.servlet.ServletRequest 作用域 Request
- response 响应对象 类型 javax.servlet.SrvletResponse 作用域 Page
- pageContext 页面上下文对象 类型 javax.servlet.jsp.PageContext 作用域 Page
- session 会话对象 类型 javax.servlet.http.HttpSession 作用域 Session
- application 应用程序对象 类型 javax.servlet.ServletContext 作用域 Application
- out 输出对象 类型 javax.servlet.jsp.JspWriter 作用域 Page
- config 配置对象 类型 javax.servlet.ServletConfig 作用域 Page
- page 页面对象 类型 javax.lang.Object 作用域 Page
- exception 意外对象 类型 javax.lang.Throwable 作用域 page
servlet的典型方法:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
PrintWriter out = response.getWriter();
out.println(xxx);
转发和重定向:
request.setAttribute("test","hello");
request.getRequestDispatcher("/test.jsp").forword(request,response);
response.sendRedirect("test.jsp");
html 标签
<form action="demo-form.jsp" id="form1">
First name: <input type="text" name="fname"><br>
<input type="submit" value="提交">
线程同步
synchronized 同步锁
JDBC常用几个类
Connection conn = DriverManager.getConnection("jdbc:odbc:数据源名称","user name","password");
pstmt = conn.prepareStatement("SELECT * FROM books WHERE bookid=?");
pstmt.setString(1, bookid);
rst = pstmt.executeQuery();
io字节流和字符流
枚举,Java常用类
interface IMessage {
public String getMessage(); // 获取信息
}
enum Color implements IMessage {
// 枚举类实现接口
RED("红色"), GREEN("绿色"), BLUE("蓝色"); // 枚举对象要写在首行
private String title; // 成员属性
private Color(String title) {
// 构造方法初始化属性
this.title = title;
}
}
函数式接口
@FunctionalInterface
public interface MyFunc<T>{
public T getValue(T t);
}
泛型
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
反射,class类及对象
Class<?> cls = Class.forName("mldn.Student");
Object obj = cls.newInstance();//实例化对象,jdk1.9后被废除
list,set map
List<String> all = new ArrayList<String>(); // 为List父接口进行实例化
all.add("Java"); // 保存数据
Set<String> all = new TreeSet<String>(); // 为Set父接口进行实例化
all.add("java"); // 保存数据
Map<String, Integer> map = new HashMap<String, Integer>(); // 创建Map集合
map.put("one", 1); // 保存数据
List<String> all = new ArrayList<String>(); // 为List父接口进行实例化
all.add("小李老师"); // 保存数据
ListIterator<String> iter = all.listIterator() ;// 获取ListIterator接口实例
System.out.print("由前向后输出:");
while(iter.hasNext()) {
// 由前向后迭代
转载:https://blog.csdn.net/rizero/article/details/112741737