1.程序題,當輸入type=4時,寫出以下代碼的輸出:
switch (type) { default: System.out.print(4); case 1: System.out.print(1); case 2: System.out.print(2); case 3: System.out.print(3); }
輸出:4 3 2 1 說明,如果第一個匹配成功,則后面的都會執行,除非遇到break;type類型: switch表達式后面的數據類型只能是byte,short,char,int四種整形類型,枚舉類型和java.lang.String類型(從java 7才允許),不能是boolean類型。 在網上看到好多文章,說switch還支持byte,short,char,int 的包裝類,首先可以肯定說switch不支持這些包裝類,但是如下的代碼又是正確的: public static void main(String[] args) { switch (new Integer(45)) { case 40: System.out.println("40"); break; case 45: System.out.println("45");//將會打印這句 break; default: System.out.println("?"); break; } } 可以打印正確的結果,在挨着挨着試完Byte,Short,Character,Integer后發現都可以正確打印,於是便說switch也支持byte,short,char,int的包裝類。這種說法不完全正確,之所以switch能夠支持他們的包裝類,是因為自動拆箱(從JDK1.5開始支持自動拆箱和自動裝箱,自動拆箱就是自動將引用數據類型轉化為基本數據類型,自動裝箱就是自動將基本數據類型轉化為引用數據類型)的原因,下面使用jclasslib軟件打開上面的.class文件, 0 new #2 <java/lang/Integer> 創建一個Integer類的對象 3 dup 將對象的標識壓入棧頂部 4 bipush 45 將整形45壓入棧中 6 invokespecial #3 <java/lang/Integer.<init>> 調用Integer類型的構造方法 9 invokervirtual #4 <java/lang/Integer.intValue> 調用intValue()方法 12 lookupswitch 2 40:40(+28) 45:51(+39) defalut:62(+50) 40 getstatic #5 <java/lang/System.out> 獲得標准輸出流 43 ldc #6 <40> 從常量池中將40的索引壓入棧中 45 invokevirtual #7 <java/io/PrintStream.println> 調用println()方法 48 goto 70 (+22) 51 gestatic #5 <java/lang/System.out> 54 ldc #8 <45> 56 invokevirtual #7 <java/io/PrintStream.println> 59 goto 70 (+11) 62 getstatic #5 <java/lang/System.out> 65 ldc #9<?> 67 invokevirtual #7 <java/io/PrintStream.println> 70 return 從上面的第5行我們可以看出編譯器自動調用了intValue()方法,如果是使用Byte會自動調用byteValue()方法,如果是Short會自動調用shortValue()方法,如果是Integer會自動調用intValue()方法。switch 的查找原理是使用key-offset在目標表格中查找的,lookupswitch后面的數字和goto后面的數字都是有規律的,關於更多信息可以查看The Java® Virtual Machine Specification 因此switch表達式后面的數據類型只支持byte,short,char,int四種整形類型、枚舉類型和java.lang.String類型。 轉載:https://www.cnblogs.com/HDK2016/p/6854671.html
2.程序題,以下代碼最后會拋出一個異常,是第幾行拋出的:
try{
throw new Exception("1");
}catch (IOException e){
throw new Exception("2");
}catch (Exception e) {
throw new Exception("3");
}finally {
throw new Exception("4");
}
解析: 4 有待研究 拋出最后new的exception異常
try{ throw new Exception("1"); }catch (IOException e){ throw new Exception("2"); }catch (Exception e) { throw e; // throw new Exception("3"); } finally { throw new Exception("4"); }
try{ throw new Exception("1"); }catch (IOException e){ throw new Exception("2"); }catch (Exception e) { // throw e; throw new Exception("3"); } finally { // throw new Exception("4"); } }
try{ throw new Exception("1"); }catch (IOException e){ throw new Exception("2"); }catch (Exception e) { throw e; // throw new Exception("3"); } finally { // throw new Exception("4"); }
3、web容器有幾種作用域?如何防止SQL注入?
一、SQL注入簡介 SQL注入是比較常見的網絡攻擊方式之一,它不是利用操作系統的BUG來實現攻擊,而是針對程序員編程時的疏忽,通過SQL語句,實現無帳號登錄,甚至篡改數據庫。 二、SQL注入攻擊的總體思路 1.尋找到SQL注入的位置 2.判斷服務器類型和后台數據庫類型 3.針對不通的服務器和數據庫特點進行SQL注入攻擊 三、SQL注入攻擊實例 比如在一個登錄界面,要求輸入用戶名和密碼: 可以這樣輸入實現免帳號登錄: 用戶名: ‘or 1 = 1 – 密 碼: 點登陸,如若沒有做特殊處理,那么這個非法用戶就很得意的登陸進去了.(當然現在的有些語言的數據庫API已經處理了這些問題) 這是為什么呢? 下面我們分析一下 從理論上說,后台認證程序中會有如下的SQL語句: String sql = "select * from user_table where username=' "+userName+" ' and password=' "+password+" '"; 當輸入了上面的用戶名和密碼,上面的SQL語句變成: SELECT * FROM user_table WHERE username='’or 1 = 1 -- and password='’ 分析SQL語句: 條件后面username=”or 1=1 用戶名等於 ” 或1=1 那么這個條件一定會成功; 然后后面加兩個-,這意味着注釋,它將后面的語句注釋,讓他們不起作用,這樣語句永遠都能正確執行,用戶輕易騙過系統,獲取合法身份。 這還是比較溫柔的,如果是執行 SELECT * FROM user_table WHERE username='' ;DROP DATABASE (DB Name) --' and password='' ….其后果可想而知… 四、應對方法 下面我針對JSP,說一下應對方法: 1.(簡單又有效的方法)PreparedStatement 采用預編譯語句集,它內置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。 使用好處: (1).代碼的可讀性和可維護性. (2).PreparedStatement盡最大可能提高性能. (3).最重要的一點是極大地提高了安全性. 原理: sql注入只對sql語句的准備(編譯)過程有破壞作用 而PreparedStatement已經准備好了,執行階段只是把輸入串作為數據處理, 而不再對sql語句進行解析,准備,因此也就避免了sql注入問題. 2.使用正則表達式過濾傳入的參數 要引入的包: import java.util.regex.*; 正則表達式: private String CHECKSQL = “^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”; 判斷是否匹配: Pattern.matches(CHECKSQL,targerStr); 下面是具體的正則表達式: 檢測SQL meta-characters的正則表達式 :/(\%27)|(\’)|(\-\-)|(\%23)|(#)/ix 修正檢測SQL meta-characters的正則表達式 :/((\%3D)|(=))[^\n]*((\%27)|(\’)|(\-\-)|(\%3B)|(:))/i 典型的SQL 注入攻擊的正則表達式 :/\w*((\%27)|(\’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix 檢測SQL注入,UNION查詢關鍵字的正則表達式 :/((\%27)|(\’))union/ix(\%27)|(\’) 檢測MS SQL Server SQL注入攻擊的正則表達式:/exec(\s|\+)+(s|x)p\w+/ix 等等….. 3.字符串過濾 比較通用的一個方法: (||之間的參數可以根據自己程序的需要添加) 復制代碼 public static boolean sql_inj(String str) { String inj_str = "'|and|exec|insert|select|delete|update| count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; String inj_stra[] = split(inj_str,"|"); for (int i=0 ; i < inj_stra.length ; i++ ) { if (str.indexOf(inj_stra[i])>=0) { return true; } } return false; } 復制代碼 4.jsp中調用該函數檢查是否包函非法字符 防止SQL從URL注入: sql_inj.java代碼: 復制代碼 package sql_inj; import java.net.*; import java.io.*; import java.sql.*; import java.text.*; import java.lang.String; public class sql_inj{ public static boolean sql_inj(String str) { String inj_str = "'|and|exec|insert|select|delete|update| count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; //這里的東西還可以自己添加 String[] inj_stra=inj_str.split("\\|"); for (int i=0 ; i < inj_stra.length ; i++ ) { if (str.indexOf(inj_stra[i])>=0) { return true; } } return false; } } 復制代碼 5.JSP頁面判斷代碼: 使用javascript在客戶端進行不安全字符屏蔽 功能介紹:檢查是否含有”‘”,”\\”,”/” 參數說明:要檢查的字符串 返回值:0:是1:不是 函數名是 復制代碼 function check(a) { return 1; fibdn = new Array (”‘” ,”\\”,”/”); i=fibdn.length; j=a.length; for (ii=0; ii<i; ii++) { for (jj=0; jj<j; jj++) { temp1=a.charAt(jj); temp2=fibdn[ii]; if (tem’; p1==temp2) { return 0; } } } return 1; } 復制代碼 總的說來,防范一般的SQL注入只要在代碼規范上下點功夫就可以了。 凡涉及到執行的SQL中有變量時,用JDBC(或者其他數據持久層)提供的如:PreparedStatement就可以 ,切記不要用拼接字符串的方法就可以了。 轉載:https://www.cnblogs.com/EasonJim/p/6223216.html
Web開發中的四個域對象(范圍由小到大): page(jsp有效) request(一次請求) session(一次會話) application(當前web應用) page域指的是pageContext. request域指的是HttpServletRequest session 域指的是HTTPSession application 域指的是ServletContext 之所以他們是域對象,原因就是他們都內置了map集合,都有setAttribute getAttribute方法。而且他們的name都是String類型,而value都是Object類型。 他們都有自己固定的生命周期和作用域。 這四個對象的生命周期(生命周期就是值對象的創建到銷毀的期間): page:jsp頁面被執行,生命周期開始,jsp頁面執行完畢,聲明周期結束。 request:用戶發送一個請求,開始,服務器返回響應,請求結束,生命周期結束。 session:用戶打開瀏覽器訪問,創建session(開始),session超時或被聲明失效,該對象生命周期結束。 application:web應用加載的時候創建。Web應用被移除或服務器關閉,對象銷毀。[結束]。 ------------------------------------------------------------------------------------------------------------------------------------------------------------- 注意: 1.Page只在當前jsp有效,每次請求分別對應不同的request. 2.Request,只在當前請求有效,每次請求分別對應不同的request域 【Request域】可以調用request這個隱含對象的getAttribute()方法來訪問具有這種范圍類型的對象。也可以使用getParameter(String name) return String來獲取XML里傳遞給它的參數。 String data = "XBY request"; request.setAttribute("data4",data); request.getRequestDispatcher("/1.jsp").forward(request, response); Request可以用於Forward String data = (String)request.getAttribute("data"); out.write(data); 【如果在forward前將在Servlet程序中寫入的部分內容已經被真正地傳送到客戶端,forward方法將拋出IllegalStateException異常。】關鍵在跳轉后要return. 如果在調用Forward方法前向servlet引擎的緩沖區(response)中寫入內容,只要寫入到緩沖區的內容還沒有真正輸出到客戶端,forward方法將可以被正常執行,原來寫入到緩沖區的內容 會被清空,但是,已經寫入到HttpServletResponse對象的響應字段信息保持有效。 Forward請求轉發特點: 1.客戶端只發出了一次請求,而服務器端有多個資源調用 2.客戶端瀏覽器端RUL不會變化。 ------------------------------------------------------------------------------------------------------------------------------------------------------------- 3.Session只在一次會話中有效,會話結束就無法取到數據了。getAttribute(String name) return Object HttpSession session = request.getSession(); session.setAttribute("name", "電視"); response.setCharacterEncoding("UTF-8");//處理中文亂碼問題 response.setContentType("text/html;charset=UTF-8");//處理中文亂碼問題 PrintWriter out = response.getWriter();//處理中文亂碼問題 HttpSession session = request.getSession(); String product = (String)session.getAttribute("name"); out.write(product); 只有當getSession()時,服務器才會為該瀏覽器創建session,他的生命周期默認為30min。 <session-config> <session-timeout>10</session-timeout> </session-config> 當使用request.getSession(false);時,就是查看session,不生成session.例如在查看已購買東西時,會使用。//ie8的話,開2個瀏覽器還是共享一個session,ie7是服務器把sessionid寫進了瀏覽器的進程中,而ie8是服務器實現了多個同一款瀏覽器的session共享。 【cookie】如果沒有指定Cookies對象的有效期,則Cookies對象只存在於客戶端的內存。當瀏覽器關閉時,Cookies就會失效。 HttpSession session = request.getSession(); String sessionid = session.getId(); Cookie cookie = new Cookie("JSESSIONID", sessionid); cookie.setPath("/servlet"); cookie.setMaxAge(30*60); response.addCookie(cookie); session.setAttribute("name", "電視");//重新寫cookie。設置時間。 如果禁用cookie,就是使用利用URL重寫技術讓瀏覽器的URL帶上SESSIONID。 -------------------------------------------------------------------------------------------------------------------------------------------------------------- 4.application:在JSP自動生成的Servlet文件中,是這樣定義的:final javax.servlet.ServletContext application; ServletContext域: 1.這是一個容器 2.說明這個容器的作用范圍是整個應用程序范圍 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data="xby ok"; this.getServletContext().setAttribute("data", data); System.out.println("write ok!"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String value = (String)this.getServletContext().getAttribute("data"); System.out.println(value); } 【補】ServletContext可以轉發Servlet,但是Servlet不方便顯示。 forward: String data="xby yes!"; this.getServletContext().setAttribute("data", data); RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/1.jsp"); rd.forward(request, response); 這樣不好,因為涉及到多線程問題,ServletContext會被同一應用中的所有Servlet所共享】 通過ServletContext讀取web資源: InputStream in= this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties props = new Properties(); props.load(in); String username = props.getProperty("username"); String passwd = props.getProperty("passwd"); 獲得資源文件路徑(用於上傳下載): String path= this.getServletContext().getRealPath("/WEB-INF/classes/db.properties"); FileInputStream in = new FileInputStream(path);】 使用ServletContext管理相關的資源。webapp都是在jvm下執行的,所以絕對路徑就是在jvm的路徑。 ServletContext會在服務器啟動時創建,目錄在webapps中;服務器停止時會銷毀這個ServletContext.------------------------------------------------------------------------------------------------------------------------------------------------------------- - 四個域對象在選擇的時候,能用范圍小的絕不用范圍大的: page:數據只是暫時存在集合,在jsp頁面的其他地方要用,用page(頁面中自定義的map) (什么時候需要用map了,就用page) Request:【程序產生數據,數據顯示完后就沒有用了】 數據只是做顯示的,看完了就沒用了。就存request域,請求轉發,Servlet產生的處理結果(數據)交給jsp顯示。數據轉發可以帶數據。 Session:【程序產生數據,顯示后等會還需要使用】 數據給用戶看完了,一定還要用,會話結束了就沒用了 用戶登錄,用戶信息發給客戶端看,看完了,一會訪問別的頁面還要看用戶信息。 購物車,購物車成功了,給用戶看購物車,待會隨時間可以查看購物車 請求重定向,因為是兩次請求,每一次請求的數據,第二次請求還要看。 application:【ServletContext在jsp中另一個名字就是application,數據顯示后,等會還需要用,還需要給別人用,例如聊天室】 數據給一個用戶用完了,別人還要用; 聊天室,聊天記錄,需要給所有的用戶看;統計網站在線人數,所有看到的應該是一個數 【總結】:四個域對象在選擇的時候,能用范圍小的絕不用范圍大的。 1.需要定義Map時不如用page, 2.請求Servlet,轉發給jsp的數據存request, 3.請求重定向帶過去的數據存Session, 4.全局的數據存application。 4.ServletContext:WEB容器在啟動時,他會為每一個【WEB應用程序】都創建一個對應的ServletContext對象,它代表【當前WEB應用】,駐留在服務器的內存里。 在一個contex中的數據都是共享的,它是web應用的配置信息和配置參數。 轉載:https://www.cnblogs.com/whytohow/p/5015340.html
4、MySQL樂觀鎖和悲觀鎖的概念?原理機制?
悲觀鎖與樂觀鎖是兩種常見的資源並發鎖設計思路,也是並發編程中一個非常基礎的概念。本文將對這兩種常見的鎖機制在數據庫數據上的實現進行比較系統的介紹。
悲觀鎖(Pessimistic Lock)
悲觀鎖的特點是先獲取鎖,再進行業務操作,即“悲觀”的認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業務操作。通常所說的“一鎖二查三更新”即指的是使用悲觀鎖。通常來講在數據庫上的悲觀鎖需要數據庫本身提供支持,即通過常用的select … for update操作來實現悲觀鎖。當數據庫執行select for update時會獲取被select中的數據行的行鎖,因此其他並發執行的select for update如果試圖選中同一行則會發生排斥(需要等待行鎖被釋放),因此達到鎖的效果。select for update獲取的行鎖會在當前事務結束時自動釋放,因此必須在事務中使用。
這里需要注意的一點是不同的數據庫對select for update的實現和支持都是有所區別的,例如oracle支持select for update no wait,表示如果拿不到鎖立刻報錯,而不是等待,mysql就沒有no wait這個選項。另外mysql還有個問題是select for update語句執行中所有掃描過的行都會被鎖上,這一點很容易造成問題。因此如果在mysql中用悲觀鎖務必要確定走了索引,而不是全表掃描。
樂觀鎖(Optimistic Lock)
樂觀鎖的特點先進行業務操作,不到萬不得已不去拿鎖。即“樂觀”的認為拿鎖多半是會成功的,因此在進行完業務操作需要實際更新數據的最后一步再去拿一下鎖就好。
樂觀鎖在數據庫上的實現完全是邏輯的,不需要數據庫提供特殊的支持。一般的做法是在需要鎖的數據上增加一個版本號,或者時間戳,然后按照如下方式實現:
復制代碼
1. SELECT data AS old_data, version AS old_version FROM …;
2. 根據獲取的數據進行業務操作,得到new_data和new_version
3. UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
// 樂觀鎖獲取成功,操作完成
} else {
// 樂觀鎖獲取失敗,回滾並重試
}
復制代碼
樂觀鎖是否在事務中其實都是無所謂的,其底層機制是這樣:在數據庫內部update同一行的時候是不允許並發的,即數據庫每次執行一條update語句時會獲取被update行的寫鎖,直到這一行被成功更新后才釋放。因此在業務操作進行前獲取需要鎖的數據的當前版本號,然后實際更新數據時再次對比版本號確認與之前獲取的相同,並更新版本號,即可確認這之間沒有發生並發的修改。如果更新失敗即可認為老版本的數據已經被並發修改掉而不存在了,此時認為獲取鎖失敗,需要回滾整個業務操作並可根據需要重試整個過程。
總結
樂觀鎖在不發生取鎖失敗的情況下開銷比悲觀鎖小,但是一旦發生失敗回滾開銷則比較大,因此適合用在取鎖失敗概率比較小的場景,可以提升系統並發性能
樂觀鎖還適用於一些比較特殊的場景,例如在業務操作過程中無法和數據庫保持連接等悲觀鎖無法適用的地方
轉載:https://www.cnblogs.com/zhiqian-ali/p/6200874.html
5、jQuery獲取元素的方法,至少寫出3種。
eq() 返回帶有被選元素的指定索引號的元素
first() 返回被選元素的第一個元素
last() 返回被選元素的最后一個元素
next() 返回被選元素的后一個同級元素
prev() 返回被選元素的前一個同級元素
parent() 獲取被選元素的父級元素
摘要:https://www.cnblogs.com/wenJiaQi/p/6136050.html
例子:http://blog.csdn.net/u012102536/article/details/72902175
6、寫出SQL的左連接、右連接、內連接、執行查詢過程的關鍵字。
左連接:left join
右連接:right join
內連接:inner join
執行查詢過程:exec procName;
摘要:http://blog.csdn.net/seanb/article/details/51594234
存儲過程摘要:https://www.cnblogs.com/hoojo/archive/2011/07/19/2110862.html
7、Linux命令行。有一個日志文件a.log,計算包含"jd.com"的行數;將文件中的"jd.com"替換成"360buy.com";
有一個日志文件a.log,計算包含"jd.com"的行數;
grep -o 'jd.com' a.log | wc -l
將文件中的"jd.com"替換成"360buy.com";
sed -i "s/jd.com/360buy.com/g" `grepjd.com -rl /home` 目錄文件所有文件替換
sed -i "s/jd.com/360buy.com/g" 1.txt
摘要:https://www.cnblogs.com/fullhouse/archive/2011/07/17/2108786.html
http://blog.sina.com.cn/s/blog_69f80ee601016rq1.html
https://www.cnblogs.com/end/archive/2012/05/24/2517131.html
8、程序題,實現二分法查找。
<span style="font-size:18px;">#include <stdio.h> #include <stdlib.h> void main(){ int doubleCheck(int a, int b, int c, int d[]); int d[] = { 1, 2, 3, 4, 5, 6 }; doubleCheck(0,5,5,d); getchar(); } void doubleCheck(int a,int b,int c,int d []){//a為數組的下界,b為數組的上界,c為匹配目標,d為查找的范圍數組。 int x = (a + b) / 2; //遞歸的結束條件一定要寫在判斷條件之前。 if (d[x] == c) { printf("%d",x); } if (d[x] > c)//說明在d[a]-d[x]范圍之中 { doubleCheck(a, x-1, c, d); } if (d[x] < c) { doubleCheck(x+1, b, c, d); } }</span>
9、我們負責的一個站點出現無法訪問的問題,列舉可能導致該問題的原因,並說明如何證明,越多越好。
1、您訪問的域名未綁定至主機;
2、您正在使用IP訪問;
3、該站點已被網站管理員停止;
4、確認域名是否正確解析
5、萬網主機(虛擬機)有時候更改了ip 所以去看看主機ip是否更改
