yxhxj2006

          常用鏈接

          統計

          最新評論

          2016年6月17日 #

          jQuery 插件autocomplete 應用

          項目中有時會用到自動補全查詢,就像Google搜索框、淘寶商品搜索功能,輸入漢字或字母,則以該漢字或字母開頭的相關條目會顯示出來供用戶選擇, autocomplete插件就是完成這樣的功能。

            autocomplete官網 : http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ (可下載jQuery autocomplete插件)。

            淘寶商品搜索功能 效果:

            下面來使用 autocomplete插件來實現類似效果。

          1. 創建 AjaxPage.aspx 頁面,在其中定義 WebMethod 方法來返回 搜索頁面需要的輸入框所有提示條目。 后臺代碼如下:

          復制代碼
           1 using System.Collections.Generic;
          2 using System.IO;
          3 using System.Runtime.Serialization.Json;
          4 using System.Web.Services;
          5
          6 public partial class AjaxPage : System.Web.UI.Page
          7 {
          8 [WebMethod]
          9 public static string GetAllHints()
          10 {
          11 Dictionary<string, string> data = new Dictionary<string, string>();
          12 data.Add("蘋果4代iphone正品", "21782");
          13 data.Add("蘋果4代 手機套", "238061");
          14 data.Add("蘋果4", "838360");
          15 data.Add("蘋果皮", "242721");
          16 data.Add("蘋果筆記本", "63348");
          17 data.Add("蘋果4s", "24030");
          18 data.Add("戴爾筆記本", "110105");
          19 data.Add("戴爾手機", "18870");
          20 data.Add("戴爾鍵盤", "30367");
          21
          22 DataContractJsonSerializer serializer = new DataContractJsonSerializer(data.GetType());
          23
          24 using (MemoryStream ms = new MemoryStream())
          25 {
          26 serializer.WriteObject(ms, data);
          27 return System.Text.Encoding.UTF8.GetString(ms.ToArray());
          28 }
          29 }
          30 }
          復制代碼

            注:該方法返回的數據格式為json字符串。

          2. 創建搜索頁面 Index.aspx, 前臺代碼如下:

          復制代碼
           1 <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Index.aspx.cs" Inherits="_Default" %>
          2
          3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          4
          5 <html xmlns="http://www.w3.org/1999/xhtml">
          6 <head runat="server">
          7 <title></title>
          8 <link rel="Stylesheet" href="Styles/jquery.autocomplete.css" />
          9 <script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
          10 <script type="text/javascript" src="Scripts/jquery.autocomplete.js"></script>
          11 <script type="text/javascript">
          12 var v = 1;
          13 $(document).ready(function () {
          14 $.ajax({
          15 type: "POST",
          16 contentType: "application/json",
          17 url: "AjaxPage.aspx/GetAllHints",
          18 data: "{}",
          19 dataType: "json",
          20 success: function (msg) {
          21 var datas = eval('(' + msg.d + ')');
          22 $("#txtIput").autocomplete(datas, {
          23 formatItem: function (row, i, max) {
          24 return "<table width='400px'><tr><td align='left'>" + row.Key + "</td><td align='right'><font style='color: #009933; font-family: 黑體; font-style: italic'>約" + row.Value + "個寶貝</font>&nbsp;&nbsp;</td></tr></table>";
          25 },
          26 formatMatch: function(row, i, max){
          27 return row.Key;
          28 }
          29 });
          30 }
          31 });
          32 });
          33 </script>
          34 </head>
          35 <body>
          36 <form id="form1" runat="server">
          37 <div>
          38 <center>
          39 <asp:TextBox ID="txtIput" runat="server" Width="400px"></asp:TextBox>
          40 </center>
          41 </div>
          42 </form>
          43 </body>
          44 </html>
          復制代碼

            實現效果如下:

          3. autocomplete 參數說明

          * minChars (Number)
              在觸發autoComplete前用戶至少需要輸入的字符數.Default: 1,如果設為0,在輸入框內雙擊或者刪除輸入框內內容時顯示列表
          * width (Number)
              指定下拉框的寬度. Default: input元素的寬度
          * max (Number)
              autoComplete下拉顯示項目的個數.Default: 10
          * delay (Number)
              擊鍵后激活autoComplete的延遲時間(單位毫秒).Default: 遠程為400 本地10
          * autoFill (Boolean)
              要不要在用戶選擇時自動將用戶當前鼠標所在的值填入到input框. Default: false
          * mustMatch (Booolean)
              如果設置為true,autoComplete只會允許匹配的結果出現在輸入框,所有當用戶輸入的是非法字符時將會得不到下拉框.Default: false
          * matchContains (Boolean)
              決定比較時是否要在字符串內部查看匹配,如ba是否與foo bar中的ba匹配.使用緩存時比較重要.不要和autofill混用.Default: false
          * selectFirst (Boolean)
              如果設置成true,在用戶鍵入tab或return鍵時autoComplete下拉列表的第一個值將被自動選擇,盡管它沒被手工選中(用鍵盤或鼠標).當然如果用戶選中某個項目,那么就用用戶選中的值. Default: true
          * cacheLength (Number)
              緩存的長度.即對從數據庫中取到的結果集要緩存多少條記錄.設成1為不緩存.Default: 10
          * matchSubset (Boolean)
              autoComplete可不可以使用對服務器查詢的緩存,如果緩存對foo的查詢結果,那么如果用戶輸入foo就不需要再進行檢索了,直接使用緩存.通常是打開這個選項以減輕服務器的負擔以提高性能.只會在緩存長度大于1時有效.Default: true
          * matchCase (Boolean)
              比較是否開啟大小寫敏感開關.使用緩存時比較重要.如果你理解上一個選項,這個也就不難理解,就好比foot要不要到FOO的緩存中去找.Default: false
          * multiple (Boolean)
              是否允許輸入多個值即多次使用autoComplete以輸入多個值. Default: false
          * multipleSeparator (String)
              如果是多選時,用來分開各個選擇的字符. Default: ","
          * scroll (Boolean)
              當結果集大于默認高度時是否使用卷軸顯示 Default: true
          * scrollHeight (Number)
              自動完成提示的卷軸高度用像素大小表示 Default: 180  
          * formatItem (Function)
              為每個要顯示的項目使用高級標簽.即對結果中的每一行都會調用這個函數,返回值將用LI元素包含顯示在下拉列表中. Autocompleter會提供三個參數(row, i, max): 返回的結果數組, 當前處理的行數(即第幾個項目,是從1開始的自然數), 當前結果數組元素的個數即項目的個數. Default: none, 表示不指定自定義的處理函數,這樣下拉列表中的每一行只包含一個值.
          * formatResult (Function)
              和formatItem類似,但可以將將要輸入到input文本框內的值進行格式化.同樣有三個參數,和formatItem一樣.Default: none,表示要么是只有數據,要么是使用formatItem提供的值.
          * formatMatch (Function)
              對每一行數據使用此函數格式化需要查詢的數據格式. 返回值是給內部搜索算法使用的. 參數值row
          * extraParams (Object)
              為后臺(一般是服務端的腳本)提供更多的參數.和通常的作法一樣是使用一個鍵值對對象.如果傳過去的值是{ bar:4 },將會被autocompleter解析成my_autocomplete_backend.php?q=foo&bar=4 (假設當前用戶輸入了foo). Default: {}
          * result (handler)
              此事件會在用戶選中某一項后觸發,參數為:
              event: 事件對象. event.type為result.
              data: 選中的數據行.
              formatted:formatResult函數返回的值
              例如:
              $("#singleBirdRemote").result(function(event, data, formatted) {
                  //如選擇后給其他控件賦值,觸發別的事件等等
              });

           

          posted @ 2016-06-17 17:54 奮斗成就男人 閱讀(279) | 評論 (0)編輯 收藏

          2015年12月3日 #

          防止重復登錄請求

          過頁頭生成Token,進行請求驗證,解決Ajax請求安全問題。目前為止我做的最多的防止ajax請求攻擊的就是添加驗證碼、添加隨機Token,限制同一請求在規定時間內的最大請求數。

          下面重點說說添加隨機Token限制:
          token是為了防止表單重復提交,token 原理大致為:

          1:顯示表單的那個 action 中使用 createToken() 生成一個隨機的 token值,并存放在服務端(session或者cache中),并且傳遞一份到頁面中

          2:表單頁面使用一個隱藏表單域獲取后端傳過來的 token值,該表單頁面提交時會將此 token 值一同提交到后端

          3:在表單頁面提交到的 actioin 中使用 validateToken() 將服務端與表單隱藏域中的 token 值進行對比,如果服務端存在 token值并且與表單提交過來的值相等,證明是第一次提交。

          4:每次校驗過后服務端的 token 值會立即被清除,所以當用戶重復提交時,后面的提交校驗都再也無法通過。從而實現了防止重復提交的功能,validateToken 是在 synchronized 塊中執行的保障了多線程下的安全性。

              token 會優先存入 me.setTokenCache(ITokenCache) 指定的 TokenCache 中,如果未指定則默認使用 session 來存放

          但是這種機制是有問題的,比如我是用ajax提交表單,提交完成以后表單頁面并不刷新,然后我修改了部分數據以后再次提交頁面,那么token還是之前的那個token,后臺會以為這個為重復提交不能通過校驗,那么請求就不能完成,數據無法得到正確的處理。我認為合理的機制應該是這樣的:

          1:顯示表單的那個 action 中使用 createToken() 生成一個隨機的 token值,并且傳遞一份到頁面中

          2:表單頁面使用一個隱藏表單域獲取后端傳過來的 token值,該表單頁面提交時會將此 token 值一同提交到后端

          3:將提交過來的token值放入session或者cache中,然后執行controller中的代碼,代碼全部執行完以后,再把存入session或cache中的token值刪除掉;驗證用戶是否為重復提交只需要驗證提交過來的token是否存在于session或cache中,有則為重復提交,無則為正常提交。

          4:該邏輯應該可以寫成一個Interceptor,在需要的地方加上,或者直接設為全局攔截器都是可以的,簡單,快捷;

          posted @ 2015-12-03 16:03 奮斗成就男人 閱讀(493) | 評論 (0)編輯 收藏

          2015年11月19日 #

          在Java中直接調用js代碼

          JDK1.6版添加了新的ScriptEngine類,允許用戶直接執行js代碼。

          在Java中直接調用js代碼

          不能調用瀏覽器中定義的js函數,會拋出異常提示ReferenceError: “alert” is not defined。

           
          package com.sinaapp.manjushri; 
          import javax.script.ScriptEngine; 
          import javax.script.ScriptEngineManager;
          import javax.script.ScriptException;   /**  * 直接調用js代碼  */
          public class ScriptEngineTest {    
          public static void main(String[] args) { 
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("javascript");
               try{                engine.eval("var a=3; var b=4;print (a+b);");           // engine.eval("alert(\"js alert\");");    // 不能調用瀏覽器中定義的js函數 // 錯誤,會拋出alert引用不存在的異常
           }catch(ScriptException e){   e.printStackTrace();  }  }    }

          輸出結果:7

          在Java中綁定js變量

          在調用engine.get(key);時,如果key沒有定義,則返回null

           
          package com.sinaapp.manjushri;     import javax.script.Bindings;   import javax.script.ScriptContext;   import javax.script.ScriptEngine;   import javax.script.ScriptEngineManager;   import javax.script.ScriptException;     public class ScriptEngineTest2 {    public static void main(String[] args) {    ScriptEngineManager manager = new ScriptEngineManager();    ScriptEngine engine = manager.getEngineByName("javascript");    engine.put("a", 4);    engine.put("b", 3);    Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);   try {                          // 只能為Double,使用Float和Integer會拋出異常      Double result = (Double) engine.eval("a+b");         System.out.println("result = " + result);     engine.eval("c=a+b");      Double c = (Double)engine.get("c");      System.out.println("c = " + c);         } catch (ScriptException e) {     e.printStackTrace();         }      }   }

          輸出:
          result = 7.0
          c = 7.0

          在Java中調用js文件中的function,傳入調用參數,并獲取返回值

          js文件中的merge函數將兩個參數a,b相加,并返回c。

           
          // expression.js 
          function merge(a, b) { 
           c = a * b; 
           return c; 
          }

          在Java代碼中讀取js文件,并參數兩個參數,然后回去返回值。

           
          package com.sinaapp.manjushri;     import java.io.FileReader;    import javax.script.Invocable;   import javax.script.ScriptEngine;   import javax.script.ScriptEngineManager;    /**  * Java調用并執行js文件,傳遞參數,并活動返回值  *   * @author manjushri  */   public class ScriptEngineTest {      public static void main(String[] args) throws Exception {    ScriptEngineManager manager = new ScriptEngineManager();    ScriptEngine engine = manager.getEngineByName("javascript");       String jsFileName = "expression.js";   // 讀取js文件     FileReader reader = new FileReader(jsFileName);   // 執行指定腳本    engine.eval(reader);     if(engine instanceof Invocable) {     Invocable invoke = (Invocable)engine;    // 調用merge方法,并傳入兩個參數      // c = merge(2, 3);      Double c = (Double)invoke.invokeFunction("merge", 2, 3);      System.out.println("c = " + c);    }     reader.close();      } }

          輸出結果:
          c = 5.0


          java調用腳本語言筆記(jython,jruby,groovy)

           有兩種方法
          1.java se 6以后實現了jsr 223規范
          java代碼:

          [java]
          1. ScriptEngineManager factory = new ScriptEngineManager();  
          2. ScriptEngineManager scriptEngine = factory.getEngineByName("javascript");//或者"js"  
          3. scriptEngine.eval(code);//執行一段腳本,code是js代碼  


           很方便調用腳本

          2.可以使用腳本語方本身提供的與java的集成手段

          jython集成
          使用jsr223:
          前提下載jython的包,已實現jsr223
          (建議在官網上下載,在安裝目錄下有jython.jar,http://repo2.maven.org/maven2/org/python/jython/2.5.0/ 這里也有,但是這個包里沒有jsr223的實現,看包下存不存在org.python.jsr223)

          [java]
          1. ScriptEngineManager factory = new ScriptEngineManager();  
          2. ScriptEngineManager scriptEngine = factory.getEngineByName("python");//或者"jython"  
          3. scriptEngine.eval(code);  


          使用PythonInterpreter,可以調用exec(String code)方法:

          [java]
          1. PythonInterpreter interpreter = new PythonInterpreter();  
          2. interpreter.exec(code);  

          訪問數據庫
          使用jdbc:

          [python] 
          1. from oracle.jdbc.driver import OracleDriver  
          2. from java.sql import DriverManager  
          3.   
          4. username = 'hr'  
          5. password = '123456'  
          6. url = 'jdbc:oracle:thin:@localhost:1521:XE'  
          7. driver = OracleDriver()  
          8. DriverManager.registerDriver(driver)  
          9. conn = DriverManager.getConnection(url, username, password)  
          10. stmt = conn.createStatement()  
          11. sql = "select salary from EMPLOYEES t where t.salary<2300"  
          12. rs = stmt.executeQuery(sql)  
          13. while (rs.next()):  
          14.  print rs.getInt('salary')  
          15. rs.close()  
          16. stmt.close()  


           結果:
          2200
          2100
          2200

          使用zxJDBC :

          [python] 
          1. from com.ziclix.python.sql import zxJDBC  
          2.   
          3. url = 'jdbc:oracle:thin:@localhost:1521:XE'  
          4. username = 'hr'  
          5. password = '123456'  
          6. driverName = 'oracle.jdbc.driver.OracleDriver'  
          7. mysqlConn = zxJDBC.connect(url,username, password,driverName)  
          8. cursor = mysqlConn.cursor()       
          9. cursor.execute("select last_name from EMPLOYEES t where t.salary<2300");  
          10. #print cursor.fetchone()  
          11. list = cursor.fetchall()  
          12. for record in list:  
          13.     print "name:"+record[0]  
          14. #print cursor.description[0]  
          15. #print cursor.description[1]  


           結果:
          name:麥克
          name:Olson
          name:Philtanker

          從數據庫中查出的中文內容正常的。
          而在代碼里面的中文全部是亂碼或拋異常,未解決。

          與jruby集成
          使用jsr223:Java代碼

          [java]
          1. ScriptEngineManager factory = new ScriptEngineManager();  
          2. ScriptEngineManager scriptEngine = factory.getEngineByName("jruby");//或者"ruby"  
          3. scriptEngine.eval(code);  

           訪問數據庫

          Ruby代碼

          [ruby] 
          1. require 'java'  
          2.   
          3. module JavaLang  
          4.   include_package "java.lang"  
          5. end  
          6.   
          7. module JavaSql  
          8.   include_package 'java.sql'  
          9. end  
          10.   
          11. begin  
          12.  username = 'hr'  
          13.  password = '123456'  
          14.  url = 'jdbc:oracle:thin:@localhost:1521:XE'  
          15.  driverName = 'oracle.jdbc.driver.OracleDriver'  
          16.  JavaLang::Class.forName(driverName).newInstance  
          17.  conn = JavaSql::DriverManager.getConnection(url, username, password)  
          18.  stmt = conn.createStatement  
          19.  sql = "select last_name from EMPLOYEES t where t.salary<2300"  
          20.  rs = stmt.executeQuery(sql)  
          21.  while (rs.next) do  
          22.   puts "名字:"+rs.getString("last_name")  
          23.  end  
          24.  rs.close  
          25.  stmt.close  
          26.  conn.close()  
          27. rescue JavaLang::ClassNotFoundException  
          28.  puts "ClassNotFoundException"  
          29. rescue JavaSql::SQLException  
          30.  puts "SQLException"  
          31. end  


           

           結果:
          名字:楹﹀厠
          名字:Olson
          名字:Philtanker

           

          從數據庫中查出的中文內容為亂碼的。
          而在代碼里面的中文正常。

           

          與groovy集成
          使用jsr223:

          Java代碼

          [java] 
          1. ScriptEngineManager factory = new ScriptEngineManager();  
          2. ScriptEngineManager scriptEngine = factory.getEngineByName("groovy");//或者"Groovy"  
          3. scriptEngine.eval(code);  


           使用GroovyShell:

          Java代碼

          [java] 
          1. GroovyShell shell = new GroovyShell();  
          2. Script script = shell.parse(code);  
          3. Object result = script.run();  


          訪問數據庫

          Groovy代碼

           

          1. import groovy.sql.Sql  
          2.   
          3. def username = 'hr'  
          4. def password = '123456'  
          5. def url = 'jdbc:oracle:thin:@localhost:1521:XE'  
          6. def driverName = 'oracle.jdbc.driver.OracleDriver'  
          7. def sql = Sql.newInstance(url, username, password, driverName)  
          8.   
          9. sql.eachRow("select last_name from EMPLOYEES t where t.salary<2300") {  
          10.  println "名字:${it.last_name}"  
          11. }  

          結果:
          名字:麥克
          名字:Olson
          名字:Philtanker

           

          在使用groovy過程中碰到了一個異常
          Exception in thread "main" java.lang.VerifyError: (class: groovy/runtime/metaclass/java/util/ArrayListMetaClass, method: super$2$invokeMethod signature: (Ljava/lang/Class;Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;ZZ)Ljava/lang/Object;) Illegal use of nonvirtual function call
          這個異常解決花了很長時間
          是因為在原來項目中存在json-lib-2.1.jar(有可能名稱為json-lib-2.1-jdk15.jar),這個包是用來處理json的,與groovy1.7.5存在沖突,更新為json-lib-2.3.jar即可
          (json-lib里有一些groovy運行時處理的內容)

          posted @ 2015-11-19 00:25 奮斗成就男人 閱讀(2924) | 評論 (0)編輯 收藏

          2015年10月30日 #

          Java導入證書的問題(PKIX:unable to find valid certification path to requested target 的問題)

          這兩天Java服務器上忽然遇到這樣的異常:

          avax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

          問題的根本是:

          缺少安全證書時出現的異常。

          解決問題方法:

          將你要訪問的webservice/url....的安全認證證書導入到客戶端即可。


          以下是獲取安全證書的一種方法,通過以下程序獲取安全證書:

          /*
           * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
           *
           * Redistribution and use in source and binary forms, with or without
           * modification, are permitted provided that the following conditions
           * are met:
           *
           *   - Redistributions of source code must retain the above copyright
           *     notice, this list of conditions and the following disclaimer.
           *
           *   - Redistributions in binary form must reproduce the above copyright
           *     notice, this list of conditions and the following disclaimer in the
           *     documentation and/or other materials provided with the distribution.
           *
           *   - Neither the name of Sun Microsystems nor the names of its
           *     contributors may be used to endorse or promote products derived
           *     from this software without specific prior written permission.
           *
           * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
           * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
           * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
           * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
           * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
           * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
           * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
           * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
           * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
           * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
           * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
           
          */

          import java.io.BufferedReader;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.InputStream;
          import java.io.InputStreamReader;
          import java.io.OutputStream;
          import java.security.KeyStore;
          import java.security.MessageDigest;
          import java.security.cert.CertificateException;
          import java.security.cert.X509Certificate;

          import javax.net.ssl.SSLContext;
          import javax.net.ssl.SSLException;
          import javax.net.ssl.SSLSocket;
          import javax.net.ssl.SSLSocketFactory;
          import javax.net.ssl.TrustManager;
          import javax.net.ssl.TrustManagerFactory;
          import javax.net.ssl.X509TrustManager;

          public class InstallCert {

              public static void main(String[] args) throws Exception {
                  String host;
                  int port;
                  char[] passphrase;
                  if ((args.length == 1) || (args.length == 2)) {
                      String[] c = args[0].split(":");
                      host = c[0];
                      port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
                      String p = (args.length == 1) ? "changeit" : args[1];
                      passphrase = p.toCharArray();
                  } else {
                      System.out
                              .println("Usage: java InstallCert <host>[:port] [passphrase]");
                      return;
                  }

                  File file = new File("jssecacerts");
                  if (file.isFile() == false) {
                      char SEP = File.separatorChar;
                      File dir = new File(System.getProperty("java.home") + SEP + "lib"
                              + SEP + "security");
                      file = new File(dir, "jssecacerts");
                      if (file.isFile() == false) {
                          file = new File(dir, "cacerts");
                      }
                  }
                  System.out.println("Loading KeyStore " + file + "");
                  InputStream in = new FileInputStream(file);
                  KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
                  ks.load(in, passphrase);
                  in.close();

                  SSLContext context = SSLContext.getInstance("TLS");
                  TrustManagerFactory tmf = TrustManagerFactory
                          .getInstance(TrustManagerFactory.getDefaultAlgorithm());
                  tmf.init(ks);
                  X509TrustManager defaultTrustManager = (X509TrustManager) tmf
                          .getTrustManagers()[0];
                  SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
                  context.init(nullnew TrustManager[] { tm }, null);
                  SSLSocketFactory factory = context.getSocketFactory();

                  System.out
                          .println("Opening connection to " + host + ":" + port + "");
                  SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
                  socket.setSoTimeout(10000);
                  try {
                      System.out.println("Starting SSL handshake");
                      socket.startHandshake();
                      socket.close();
                      System.out.println();
                      System.out.println("No errors, certificate is already trusted");
                  } catch (SSLException e) {
                      System.out.println();
                      e.printStackTrace(System.out);
                  }

                  X509Certificate[] chain = tm.chain;
                  if (chain == null) {
                      System.out.println("Could not obtain server certificate chain");
                      return;
                  }

                  BufferedReader reader = new BufferedReader(new InputStreamReader(
                          System.in));

                  System.out.println();
                  System.out.println("Server sent " + chain.length + " certificate(s):");
                  System.out.println();
                  MessageDigest sha1 = MessageDigest.getInstance("SHA1");
                  MessageDigest md5 = MessageDigest.getInstance("MD5");
                  for (int i = 0; i < chain.length; i++) {
                      X509Certificate cert = chain[i];
                      System.out.println(" " + (i + 1) + " Subject "
                              + cert.getSubjectDN());
                      System.out.println("   Issuer  " + cert.getIssuerDN());
                      sha1.update(cert.getEncoded());
                      System.out.println("   sha1    " + toHexString(sha1.digest()));
                      md5.update(cert.getEncoded());
                      System.out.println("   md5     " + toHexString(md5.digest()));
                      System.out.println();
                  }

                  System.out
                          .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
                  String line = reader.readLine().trim();
                  int k;
                  try {
                      k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
                  } catch (NumberFormatException e) {
                      System.out.println("KeyStore not changed");
                      return;
                  }

                  X509Certificate cert = chain[k];
                  String alias = host + "-" + (k + 1);
                  ks.setCertificateEntry(alias, cert);

                  OutputStream out = new FileOutputStream("jssecacerts");
                  ks.store(out, passphrase);
                  out.close();

                  System.out.println();
                  System.out.println(cert);
                  System.out.println();
                  System.out
                          .println("Added certificate to keystore 'jssecacerts' using alias '"
                                  + alias + "'");
              }

              private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

              private static String toHexString(byte[] bytes) {
                  StringBuilder sb = new StringBuilder(bytes.length * 3);
                  for (int b : bytes) {
                      b &= 0xff;
                      sb.append(HEXDIGITS[b >> 4]);
                      sb.append(HEXDIGITS[b & 15]);
                      sb.append(' ');
                  }
                  return sb.toString();
              }

              private static class SavingTrustManager implements X509TrustManager {

                  private final X509TrustManager tm;
                  private X509Certificate[] chain;

                  SavingTrustManager(X509TrustManager tm) {
                      this.tm = tm;
                  }

                  public X509Certificate[] getAcceptedIssuers() {
                      throw new UnsupportedOperationException();
                  }

                  public void checkClientTrusted(X509Certificate[] chain, String authType)
                          throws CertificateException {
                      throw new UnsupportedOperationException();
                  }

                  public void checkServerTrusted(X509Certificate[] chain, String authType)
                          throws CertificateException {
                      this.chain = chain;
                      tm.checkServerTrusted(chain, authType);
                  }
              }

          }

          編譯InstallCert.java,然后執行:java InstallCert hostname,比如:
          java InstallCert www.twitter.com
          會看到如下信息:

          java InstallCert www.twitter.com
          Loading KeyStore /usr/java/jdk1.6.0_16/jre/lib/security/cacerts
          Opening connection to www.twitter.com:443
          Starting SSL handshake

          javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
              at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1476)
              at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
              at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
              at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:846)
              at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
              at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
              at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:815)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1025)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1038)
              at InstallCert.main(InstallCert.java:63)
          Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
              at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
              at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)
              at sun.security.validator.Validator.validate(Validator.java:203)
              at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
              at InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:158)
              at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
              at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:839)
               7 more
          Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
              at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
              at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
              at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
               13 more

          Server sent 2 certificate(s):

           1 Subject CN=www.twitter.com, O=example.com, C=US
             Issuer  CN=Certificate Shack, O=example.com, C=US
             sha1    2e 7f 76 9b 52 91 09 2e 5d 8f 6b 61 39 2d 5e 06 e4 d8 e9 c7 
             md5     dd d1 a8 03 d7 6c 4b 11 a7 3d 74 28 89 d0 67 54 

           2 Subject CN=Certificate Shack, O=example.com, C=US
             Issuer  CN=Certificate Shack, O=example.com, C=US
             sha1    fb 58 a7 03 c4 4e 3b 0e e3 2c 40 2f 87 64 13 4d df e1 a1 a6 
             md5     72 a0 95 43 7e 41 88 18 ae 2f 6d 98 01 2c 89 68 

          Enter certificate to add to trusted keystore or 'q' to quit: [1]


          輸入1,回車,然后會在當前的目錄下產生一個名為“ssecacerts”的證書。

          將證書拷貝到$JAVA_HOME/jre/lib/security目錄下,或者通過以下方式:
          System.setProperty("javax.net.ssl.trustStore", "你的jssecacerts證書路徑");



          注意:因為是靜態加載,所以要重新啟動你的Web Server,證書才能生效。


          試了以上的方法,后來發現還不行。最后突然心血來潮:我把Myeclipse關閉,直接啟動Tomcat,然后運行,居然就可以了。具體原因沒有找到。估計是
          我的Myeclipse引用的JDK引用不對。后來就沒有具體找原因了。

          posted @ 2015-10-30 15:06 奮斗成就男人 閱讀(1407) | 評論 (0)編輯 收藏

          2015年8月9日 #

          常用的MySQL語句寫法

          MySQLSQL語句寫法,除了那些基本的之外,還有一些也算比較常用的,這里記錄下來,以便以后查找。
              好記性不如爛筆頭,這話說的太有道理了,一段時間不寫它,還真容易忘記。大家不要糾結這些SQL語句包含的業務或是其它問題,本文只是一篇筆記而已。

              將數據從T1表導入到T2
          INSERT INTO T2 (C1,C2) SELECT C1,C2 FROM T1 [WHERE C1 = XX AND C2 = XX ORDER BY C1]

              使用T2表的NAME來更新T1表的NAME
          UPDATE T1 AS A, T2 AS B SET A.NAME = B.NAME WHERE A.TID = B.ID

              兩表的關聯更新
          UPDATE T_ROLE_USER AS A,
           (
              SELECT
                  ID
              FROM
                  T_USER
              WHERE
                  DEPARTID IN (
                      SELECT
                          ID
                      FROM
                          T_DEPART
                      WHERE
                          LENGTH(ORG_CODE) = 9
                  )
          AS B
          SET A.ROLEID = '123456'
          WHERE
              A.USERID = B.ID

              自己和自己關聯更新
          UPDATE T_DEPART AS A,
           (
              SELECT
                  ID,
                  SUBSTRING(ORG_CODE, 16) ORG_CODE
              FROM
                  T_DEPART
              WHERE
                  LENGTH(ORG_CODE) = 8
              AND PARENT_DEPART_ID IS NOT NULL
          AS B
          SET A.PARENT_DEPART_ID = B.ID
          WHERE
              SUBSTRING(A.ORG_CODE, 16= B.ORG_CODE

              兩表關聯刪除,將刪除兩表中有關聯ID并且T2NAME為空的兩表記錄
          DELETE A,B FROM T1 AS A LEFT JOIN T2 AS B ON A.TID = B.ID WHERE B.NAME IS NULL

              將統計結果插入到表
          INSERT INTO SE_STAT_ORG (
              RECORD_DATE,
              ORG_ID,
              ORG_NAME,
              SIGN_CONT_COUNT,
              SIGN_ARRI_CONT_COUNT,
              SIGN_CONT_MONEY,
              SIGN_ARRI_CONT_MONEY,
              TOTAL_ARRI_CONT_COUNT,
              TOTAL_ARRI_MONEY,
              PUBLISH_TOTAL_COUNT,
              PROJECT_COUNT
          SELECT
              *
          FROM
              (
                  SELECT
                      '2012-06-09' RECORD_DATE,
                      PARENT_ORG_ID,
                      PARENT_ORG_NAME,
                      SUM(SIGN_CONT_COUNT) SIGN_CONT_COUNT,
                      SUM(SIGN_ARRI_CONT_COUNT) SIGN_ARRI_CONT_COUNT,
                      SUM(SIGN_CONT_MONEY) SIGN_CONT_MONEY,
                      SUM(SIGN_ARRI_CONT_MONEY) SIGN_ARRI_CONT_MONEY,
                      SUM(TOTAL_ARRI_CONT_COUNT) TOTAL_ARRI_CONT_COUNT,
                      SUM(TOTAL_ARRI_MONEY) TOTAL_ARRI_MONEY,
                      SUM(PUBLISH_TOTAL_COUNT) PUBLISH_TOTAL_COUNT,
                      SUM(PROJECT_COUNT) PROJECT_COUNT,
                  FROM SE_STAT_USER
                  WHERE DATE_FORMAT(RECORD_DATE, '%Y-%m-%d'= '2012-06-09'
                  GROUP BY PARENT_ORG_ID
              ) M

              三表關聯更新
          UPDATE SE_STAT_USER A,
           (
              SELECT
                  USER_ID,
                  SUM(INVEST_ORG_COUNT + FINANCIAL_ORG_COUNT + INTERMEDIARY_ORG_COUNT + ENTERPRISE_COUNT) AS COMMON_COUNT
              FROM SE_STAT_USER
              WHERE DATE_FORMAT(RECORD_DATE, '%Y-%m-%d'= '2012-06-09'
              GROUP BY USER_ID
          ) B,
           (
              SELECT
                  USER_ID,
                  SUM(ESTABLISH_COUNT + STOCK_COUNT + MERGER_COUNT + ACHIEVE_COUNT) AS PROJECT_COUNT
              FROM SE_STAT_USER
              WHERE DATE_FORMAT(RECORD_DATE, '%Y-%m-%d'= '2012-06-09'
              GROUP BY USER_ID
          ) C
          SET A.COMMON_COUNT = B.COMMON_COUNT, A.PROJECT_COUNT = C.PROJECT_COUNT
          WHERE A.USER_ID = B.USER_ID
          AND A.USER_ID = C.USER_ID
          AND DATE_FORMAT(A.RECORD_DATE, '%Y-%m-%d'= '2012-06-09'

              帶條件的關聯更新
          UPDATE SE_STAT_USER A,
           (
              SELECT
                  P.CHANNEL,
                  COUNT(P.CONT_ID) AS CONT_COUNT,
                  C.CUST_MGR_ID
              FROM
                  (
                      SELECT
                          CHANNEL,
                          CONT_ID
                      FROM SK_PROJECT
                      WHERE PROJECT_STATUS = 6
                      AND DATE_FORMAT(AUDIT_TIME, '%Y-%m-%d'= '2012-06-11'
                  ) p
              INNER JOIN SE_CONTRACT C ON P.CONT_ID = C.CONT_ID
              GROUP BY P.CHANNEL, C.CUST_MGR_ID
          ) B
          SET
              A.STOCK_COUNT = CASE WHEN B.CHANNEL = 2 THEN B.CONT_COUNT ELSE 0 END,
              A.ESTABLISH_COUNT = CASE WHEN B.CHANNEL = 3 THEN B.CONT_COUNT ELSE 0 END,
              A.ACHIEVE_COUNT = CASE WHEN B.CHANNEL = 4 THEN B.CONT_COUNT ELSE 0 END
              A.BRAND_COUNT = CASE WHEN B.CHANNEL = 5 THEN B.CONT_COUNT ELSE 0 END,
              A.MERGER_COUNT = CASE WHEN B.CHANNEL = 6 THEN B.CONT_COUNT ELSE 0 END
          WHERE
              A.USER_ID = B.CUST_MGR_ID
          AND DATE_FORMAT(A.RECORD_DATE, '%Y-%m-%d'= '2012-06-11'

              加索引
          ALTER TABLE PROJECT ADD INDEX INDEX_USER_ID (USER_ID),
                  ADD INDEX INDEX_PROJECT_STATUS (PROJECT_STATUS);

              刪除列
          ALTER TABLE PROJECT DROP COLUMN PROJECT_STATUS,
                  DROP COLUMN EXPECT_RETURN,DROP COLUMN CURRENCY;

              增加列
          ALTER TABLE PROJECT 
                  ADD COLUMN DICT_ID INT DEFAULT NULL COMMENT 'xxx' AFTER PROJECT_SITE,
                  ADD COLUMN INTRODUCE TEXT DEFAULT NULL COMMENT 'xx' AFTER DICT_ID,
                  ADD COLUMN STAGE INT DEFAULT NULL COMMENT 'xx' AFTER ID,
                  ADD COLUMN ATTACH_URI VARCHAR(8DEFAULT NULL COMMENT 'xxx' AFTER INTRODUCE;

              修改列,一般用MODIFY修改數據類型,CHANGE修改列名
          ALTER TABLE PROJECT CHANGE DICT_ID DICT_ID1 INT NOT NULL,
                  MODIFY PROJECT_STATUS TINYINT NOT NULL COMMENT 'xxx';

          posted @ 2015-08-09 23:31 奮斗成就男人 閱讀(393) | 評論 (0)編輯 收藏

          2015年6月13日 #

          程序員必看的書

          做為一名程序員,如果你只顧得寫代碼,那是不行的,要抽出一下時間來豐富自己的知識,多看看書,在這里我將為程序員們推薦一些不錯的書。能夠給程序員們帶來幫助。

          大數據時代

          5487a5bd00010d2903120426

          《大數據時代》是國外大數據研究的先河之作,本書作者維克托•邁爾•舍恩伯格被譽為"大數據商業應用第一人",擁有在哈佛大學、牛津大學、耶魯大學和新加坡國立大學等多個互聯網研究重鎮任教的經歷,早在2010年就在《經濟學人》上發布了長達14頁對大數據應用的前瞻性研究。

          維克托•邁爾•舍恩伯格在書中前瞻性地指出,大數據帶來的信息風暴正在變革我們的生活、工作和思維,大數據開啟了一次重大的時代轉型,并用三個部分講述了大數據時代的思維變革、商業變革和管理變革。

          維克托最具洞見之處在于,他明確指出,大數據時代最大的轉變就是,放棄對因果關系的渴求,而取而代之關注相關關系。也就是說只要知道"是什么",而不需要知道"為什么"。這就顛覆了千百年來人類的思維慣例,對人類的認知和與世界交流的方式提出了全新的挑戰。

           淘寶技術這十年

          5487a5c800013dae03030438

          《淘寶技術這十年》內容簡介:任何網站的發展都不是一蹴而就的。它在發展過程中會遇到各種各樣的問題和業務帶來的壓力。正是這些問題和壓力推動著技術的進步和發展,而技術的發展反過來又會促進業務的更大提升。如今淘寶網的流量排名已是全球前15名、國內前3名,其系統服務器也從一臺發展到萬臺以上。

          《淘寶技術這十年》從工程師的角度講述淘寶這個超大規模互聯網系統的成長歷程,及其所有主動和被動的技術變革的前因后果。書中有幕后故事、產品經驗、架構演進、技術啟蒙,也有大牛成長、業內八卦、失敗案例、勵志故事。《淘寶技術這十年》文風流暢,有技術人員特有的幽默感;內容積極正面,有現場感,全部是作者親身經歷。

          白帽子講Web安全

          5487a7b90001fa2303030438

          《白帽子講Web安全》內容簡介:在互聯網時代,數據安全與個人隱私受到了前所未有的挑戰,各種新奇的攻擊技術層出不窮。如何才能更好地保護我們的數據?《白帽子講Web安全》將帶你走進Web安全的世界,讓你了解Web安全的方方面面。黑客不再變得神秘,攻擊技術原來我也可以會,小網站主自己也能找到正確的安全道路。大公司是怎么做安全的,為什么要選擇這樣的方案呢?你能在《白帽子講Web安全》中找到答案。詳細的剖析,讓你不僅能"知其然",更能"知其所以然"。

          重構:改善既有代碼的設計

          5487a7c400010cce04000400

          《重構:改善既有代碼的設計》清晰地揭示了重構的過程,解釋了重構的原理和最佳實踐方式,并給出了何時以及何地應該開始挖掘代碼以求改善。書中給出了70多個可行的重構,每個重構都介紹了一種經過驗證的代碼變換手法的動機和技術。《重構:改善既有代碼的設計》提出的重構準則將幫助你一次一小步地修改你的代碼,從而減少了開發過程中的風險。

          《重構:改善既有代碼的設計》適合軟件開發人員、項目管理人員等閱讀,也可作為高等院校計算機及相關專業師生的參考讀物。

          代碼整潔之道

          5487a7cf000167fd03240408

          軟件質量,不但依賴于架構及項目管理,而且與代碼質量緊密相關。這一點,無論是敏捷開發流派還是傳統開發流派,都不得不承認。《代碼整潔之道》提出一種觀念:代碼質量與其整潔度成正比。干凈的代碼,既在質量上較為可靠,也為后期維護、升級奠定了良好基礎。

          作為編程領域的佼佼者,《代碼整潔之道》作者給出了一系列行之有效的整潔代碼操作實踐。這些實踐在《代碼整潔之道》中體現為一條條規則(或稱"啟示"),并輔以來自現實項目的正、反兩面的范例。只要遵循這些規則,就能編寫出干凈的代碼,從而有效提升代碼質量。

          《代碼整潔之道》閱讀對象為一切有志于改善代碼質量的程序員及技術經理。書中介紹的規則均來自作者多年的實踐經驗,涵蓋從命名到重構的多個編程方面,雖為一"家"之言,然誠有可資借鑒的價值。

          設計模式之禪 (第2版)


          549ccdfa00018b6503630363

            本書是設計模式領域公認的3本經典著作之一,"極具趣味,容易理解,但講解又極為嚴謹和透徹"是本書的寫作風格和方法的最大特點。第1版2010年出版,暢銷至今,廣受好評,是該領域的里程碑著作。深刻解讀6大設計原則和28種設計模式的準確定義、應用方法和最佳實踐,全方位比較各種同類模式之間的異同,詳細講解將不同的模式組合使用的方法。第2版在第1版的基礎上有兩方面的改進,一方面結合讀者的意見和建議對原有內容中的瑕疵進行了修正和完善,另一方面增加了4種新的設計模式,希望這一版能為廣大程序員們奉上一場更加完美的設計模式盛宴!

          程序員修煉之道

          549cce040001ee3b03150420

            《程序員修煉之道》由一系列的獨立的部分組成,涵蓋的主題從個人責任、職業發展,直到用于使代碼保持靈活、并且易于改編和復用的各種架構技術。利用許多富有娛樂性的奇聞軼事、有思想性的例子以及有趣的類比,全面闡釋了軟件開發的許多不同方面的最佳實踐和重大陷阱。無論你是初學者,是有經驗的程序員,還是軟件項目經理,本書都適合你閱讀。

          平臺戰略:正在席卷全球的商業模式革命

          549cce0e00012ad003120426

          《平臺戰略:正在席卷全球的商業模式革命》內容簡介:平臺商業模式的精髓,在于打造一個完善的、成長潛能強大的"生態圈"。它擁有獨樹一幟的精密規范和機制系統,能有效激勵多方群體之間互動,達成平臺企業的愿景。縱觀全球許多重新定義產業架構的企業,我們往往就會發現它們成功的關鍵——建立起良好的"平臺生態圈",連接兩個以上群體,彎曲、打碎了既有的產業鏈。

          平臺生態圈里的一方群體,一旦因為需求增加而壯大,另一方群體的需求也會隨之增長。如此一來,一個良性循環機制便建立了,通過此平臺交流的各方也會促進對方無限增長。而通過平臺模式達到戰略目的,包括規模的壯大和生態圈的完善,乃至對抗競爭者,甚至是拆解產業現狀、重塑市場格局。

          互聯網創業啟示錄

          549cce170001475203030438

          《互聯網創業啟示錄》是一部互聯網公司的創業指南,內容涉及網站創業的現狀和機遇、創業公司價值、平臺選擇、工具和群組、資金的籌集、管理和盈利、社會化媒體環境、行動執行管理、開發人員方法論和工作效率、創始人的角色等方面,既有綱領和指導性理論,又有具體操作方法。書中大量對互聯網創業成功人士的訪談介紹,以及創業公司的成功案例,更可以作為初次創業者的良好借鑒。

          《互聯網創業啟示錄》主要寫給想自己創業的程序員,但同樣適合非技術人員,適合網絡創業者、大學生創業者、網絡營銷人員及一切有志創業者。做網絡不一定要懂技術,互聯網的成功是可以借鑒和延伸的!

          程序員健康指南

          549cce2600015a5003600369

          本書是為程序員量身制作的健康指南,針對頭痛、眼部疲勞、背部疼痛和手腕疼痛等常見的問題,簡要介紹了其成因、測試方法,并列出了每天的行動計劃,從運動、飲食等方面給出詳細指導,幫助程序員在不改變工作方式的情況下輕松擁有健康。

          本書適合程序員、長期伏案工作的其他人群以及所有關心健康的人士閱讀。

          結網@改變世界的互聯網產品經理

          54aa4f680001268603060435

          本書以如何創建、發布、推廣互聯網產品為主線,介紹了互聯網產品經理的工作內容以及應對每一部分工作所需的方法和工具。為用戶創造價值是產品經理的第一要務,產品經理的工作是圍繞用戶及具體任務展開的,本書豐富的案例和透徹的分析道出了從發現用戶到最終滿足用戶這一過程背后的玄機。

          本書面向現在正在從事及未來將要從事互聯網相關工作的創業者和產品經理,也可以作為互聯網產品策劃人員或相關專業學生的參考書。新版完善了各章節,增加了優雅降級等內容,讀者也可從中更深地去感受一名產品經理的感悟。

          程序員面試邏輯題解析

          54aa4f7800016ca403240408

          程序員面試邏輯題解析》共分為3個部分。第一部分從有趣且鍛煉頭腦的謎題入手,繼而給出解題思路和詳細答案,更有"熱身問題"給大家提供充分的思考空間。第二部分綜合了不同類型的謎題,如數獨、調度問題及概率題等。神秘的第三部分帶領大家不斷歷險,開動腦筋,解決大量密碼及銀行賬戶等方面的問題。幾十道簡潔的小謎題不僅充分鍛煉了我們的思維方式,更為提高面試成功率奠定了基礎。

              《程序員面試邏輯題解析》不僅適合程序員閱讀,更是謎題愛好者的饕餮盛宴。

          程序員,你傷不起

          54aa4f8d000171b703060435

          本書是作者博客文章的精選集。是作者作為老牌程序員、現在的IT 創業者15 年軟件開發生涯的心路歷程和經驗總結。涉及程序人生、開發經驗、職業規劃、創業心得。對任何的軟件開發者和IT 從業人員都有借鑒價值。作者語言風趣幽默,讀起來津津有味。字里行間充滿了不屈不撓的碼農正能量。

          像程序員一樣思考

          54aa4f9800013e1e03270405

          編程的真正挑戰不是學習一種語言的語法,而是學習創造性地解決問題,從而構建美妙的應用。《像程序員一樣思考》分析了程序員解決問題的方法,并且教授你其他圖書所忽略的一種能力,即如何像程序員一樣思考。

          全書分為8章。第1章通對幾個經典的算法問題切入,概括了問題解決的基本技巧和步驟。第2章通過實際編寫C++代碼來解決幾個簡單的問題,從而讓讀者進一步體會到問題解決的思路和應用。第3到7章是書中的主體部分,分別探討了用數組、指針和動態內存、類、遞歸和代碼復用來解決問題的途徑和實際應用。最后,第8章從培養程序員思維的角度,進行了總結和概括,告訴讀者如何才能像程序員一樣思考。

          編寫可讀代碼的藝術

          54aa4fbf0001a7c103180417

          細節決定成敗,思路清晰、言簡意賅的代碼讓程序員一目了然;而格式凌亂、拖沓冗長的代碼讓程序員一頭霧水。除了可以正確運行以外,優秀的代碼必須具備良好的可讀性,編寫的代碼要使其他人能在最短的時間內理解才行。本書旨在強調代碼對人的友好性和可讀性。

          本書關注編碼的細節,總結了很多提高代碼可讀性的小技巧,看似都微不足道,但是對于整個軟件系統的開發而言,它們與宏觀的架構決策、設計思想、指導原則同樣重要。編碼不僅僅只是一種技術,也是一門藝術,編寫可讀性高的代碼尤其如此。如果你要成為一位優秀的程序員,要想開發出高質量的軟件系統,必須從細處著手,做到內外兼修,本書將為你提供有效的指導。

          posted @ 2015-06-13 00:03 奮斗成就男人 閱讀(427) | 評論 (0)編輯 收藏

          2015年5月13日 #

          Oracle分析函數入門

          一、Oracle分析函數入門

          分析函數是什么?
          分析函數是Oracle專門用于解決復雜報表統計需求的功能強大的函數,它可以在數據中進行分組然后計算基于組的某種統計值,并且每一組的每一行都可以返回一個統計值。

                    

          分析函數和聚合函數的不同之處是什么?
          普通的聚合函數用group by分組,每個分組返回一個統計值,而分析函數采用partition by分組,并且每組每行都可以返回一個統計值。

                        

          分析函數的形式
          分析函數帶有一個開窗函數over(),包含三個分析子句:分組(partition by), 排序(order by), 窗口(rows) ,他們的使用形式如下:over(partition by xxx order by yyy rows between zzz)。
          注:窗口子句在這里我只說rows方式的窗口,range方式和滑動窗口也不提

              

          分析函數例子(在scott用戶下模擬)

          示例目的:顯示各部門員工的工資,并附帶顯示該部分的最高工資。

          復制代碼
          --顯示各部門員工的工資,并附帶顯示該部分的最高工資。
          SELECT E.DEPTNO,
          E.EMPNO,
          E.ENAME,
          E.SAL,
          LAST_VALUE(E.SAL)
          OVER(PARTITION BY E.DEPTNO
          ORDER BY E.SAL ROWS
          --unbounded preceding and unbouned following針對當前所有記錄的前一條、后一條記錄,也就是表中的所有記錄
          --unbounded:不受控制的,無限的
          --preceding:在...之前
          --following:在...之后
          BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL
          FROM EMP E;
          復制代碼

          運行結果:

                         

          示例目的:按照deptno分組,然后計算每組值的總和

          SELECT EMPNO,
          ENAME,
          DEPTNO,
          SAL,
          SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY ENAME) max_sal
          FROM SCOTT.EMP;

          運行結果:

               

          示例目的:對各部門進行分組,并附帶顯示第一行至當前行的匯總

          復制代碼
          SELECT EMPNO,
          ENAME,
          DEPTNO,
          SAL,
          --注意ROWS BETWEEN unbounded preceding AND current row 是指第一行至當前行的匯總
          SUM(SAL) OVER(PARTITION BY DEPTNO
          ORDER BY ENAME
          ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) max_sal
          FROM SCOTT.EMP;
          復制代碼

          運行結果:

             

          示例目標:當前行至最后一行的匯總

          復制代碼
          SELECT EMPNO,
          ENAME,
          DEPTNO,
          SAL,
          --注意ROWS BETWEEN current row AND unbounded following 指當前行到最后一行的匯總
          SUM(SAL) OVER(PARTITION BY DEPTNO
          ORDER BY ENAME
          ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) max_sal
          FROM SCOTT.EMP;
          復制代碼

          運行結果:

             

           示例目標:當前行的上一行(rownum-1)到當前行的匯總

          復制代碼
          SELECT EMPNO,
          ENAME,
          DEPTNO,
          SAL,
          --注意ROWS BETWEEN 1 preceding AND current row 是指當前行的上一行(rownum-1)到當前行的匯總
          SUM(SAL) OVER(PARTITION BY DEPTNO
          ORDER BY ENAME ROWS
          BETWEEN 1 PRECEDING AND CURRENT ROW) max_sal
          FROM SCOTT.EMP;
          復制代碼

          運行結果:

              

          示例目標:   當前行的上一行(rownum-1)到當前行的下輛行(rownum+2)的匯總     

          復制代碼
          SELECT EMPNO,
          ENAME,
          DEPTNO,
          SAL,
          --注意ROWS BETWEEN 1 preceding AND 1 following 是指當前行的上一行(rownum-1)到當前行的下輛行(rownum+2)的匯總
          SUM(SAL) OVER(PARTITION BY DEPTNO
          ORDER BY ENAME
          ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING) max_sal
          FROM SCOTT.EMP;
          復制代碼

          運行結果:


          posted @ 2015-05-13 00:46 奮斗成就男人 閱讀(369) | 評論 (0)編輯 收藏

          常見分析函數詳解

               摘要: 三、常見分析函數詳解為了方便進行實踐,特將演示表和數據羅列如下:一、創建表create table t( bill_month varchar2(12) , area_code number, net_type varchar(2), local_fare number );      二、插入數據insert i...  閱讀全文

          posted @ 2015-05-13 00:46 奮斗成就男人 閱讀(405) | 評論 (0)編輯 收藏

          ORACLE 常用函數

            這個系列我將整理一些日常我們經常使用到的ORACLE函數,鑒于篇幅太長,我大體會按下面分類來整理、匯總這些常用的ORACLE函數,如果有些常用函數沒有被整理進來,也希望大家指點一二。

           1: 聚合函數

          2: 日期函數
          3: 字符串函數
          4: 格式化函數
          5: 類型轉換函數
          6: 加密函數
          7: 控制流函數
          8: 數學函數
          9: 系統信息函數
          10:分析函數

          ------------------------------------------聚合函數---------------------------------------------
          --1:   AVG(DISTINCT|ALL)

          ALL表示對所有的值求平均值,DISTINCT只對不同的值求平均值
          SELECT AVG(SAL) FROM SCOTT.EMP;
          SELECT AVG(DISTINCT SAL) FROM SCOTT.EMP;
          --2:   MAX(DISTINCT|ALL)

          求最大值,ALL表示對所有的值求最大值,DISTINCT表示對不同的值求最大值,相同的只取一次

          (加不加查詢結果一致,不知DISTINCT有什么用途,不同于AVG等聚合函數)
          SELECT MAX(DISTINCT SAL) FROM SCOTT.EMP;
          SELECT MAX(SAL) FROM SCOTT.EMP
          --3:   MIN(DISTINCT|ALL)
          求最小值,ALL表示對所有的值求最小值,DISTINCT表示對不同的值求最小值,相同的只取一次
          SELECT MIN(SAL) FROM SCOTT.EMP;
          SELECT MIN(DISTINCT SAL) FROM SCOTT.EMP;

          --4:  STDDEV(distinct|all)
          求標準差,ALL表示對所有的值求標準差,DISTINCT表示只對不同的值求標準差
          SELECT STDDEV(SAL) FROM SCOTT.EMP;
          SELECT STDDEV(DISTINCT SAL) FROM SCOTT.EMP;

          --5:   VARIANCE(DISTINCT|ALL)
          求協方差  ALL表示對所有的值求協方差,DISTINCT表示只對不同的值求協方差
          SELECT VARIANCE(SAL) FROM SCOTT.EMP;
          SELECT VARIANCE(DISTINCT SAL) FROM SCOTT.EMP;

          --6:  SUM(DISTINCT|ALL)
          求和  ALL表示對所有值求和,DISTINCT表示只對不同值求和(相同值只取一次)
          SELECT SUM(SAL) FROM SCOTT.EMP;
          SELECT SUM(DISTINCT SAL) FROM SCOTT.EMP;


          --7:COUNT(DISTINCT|ALL)
          求記錄、數據個數。 ALL對所有記錄,數組做統計, DISTINCT只對不同值統計(相同值只取一次)
          SELECT COUNT(SAL) FROM SCOTT.EMP;
          SELECT COUNT(DISTINCT SAL) FROM SCOTT.EMP;  
           
          ----8: MEDIAN
          求中位數
          SELECT MEDIAN(SAL) FROM SCOTT.EMP;
          SELECT MEDIAN(DISTINCT SAL) FROM SCOTT.EMP;  --錯誤:DISTINCT 選項在此函數中禁用。
          ----------------------------------------------------------------------------------------------

          posted @ 2015-05-13 00:37 奮斗成就男人 閱讀(336) | 評論 (0)編輯 收藏

          2015年4月22日 #

          如何判斷PHP空間是否支持curl, gzip等功能

          在使用PHP時,我們需要將自己寫好的php文件上傳到已申請的php空間。由于租用或申請的php空間是不允許用戶進行配置的,那么對于php的一些功能是否開啟,如curl, allow_url_fopen, gzip,就需要提前判斷,而不是等寫完代碼后發現不能使用時,那樣改動就大了。

          方法/步驟

          1. 其實判斷功能是否開啟,很簡單,我們只需要寫一個php文件上傳之php空間服務器中。v.php的源代碼如圖。

            如何判斷PHP空間是否支持curl, gzip等功能
          2. 其含義很簡單,就是傳入一個函數的名字,服務器判斷是否存在這個函數,如果存在則表示支持該函數對應的功能,輸出“支持”,反之輸出“不支持”。將文件上傳至php空間中。

            如何判斷PHP空間是否支持curl, gzip等功能
          3. 再通過訪問空間,地址+v.php?f=+要測試的功能所包括的函數,比如curl功能可以是v.php?f=curl_init,allow_url_fopen功能可以用v.php?f=fopen來測試。

          posted @ 2015-04-22 00:04 奮斗成就男人 閱讀(304) | 評論 (0)編輯 收藏

          僅列出標題  下一頁
          主站蜘蛛池模板: 莱西市| 龙江县| 沛县| 浦北县| 重庆市| 三亚市| 宁武县| 万全县| 梧州市| 庆城县| 濮阳县| 浠水县| 太白县| 甘德县| 林芝县| 基隆市| 景谷| 沧源| 军事| 洪雅县| 自治县| 大邑县| 宜城市| 双辽市| 河东区| 潮州市| 芜湖市| 三河市| 肇庆市| 翼城县| 曲靖市| 巨野县| 孝义市| 石狮市| 喀什市| 容城县| 古田县| 兖州市| 泾川县| 定边县| 延长县|