1、使用fastjson框架進行序列化時,若莫個參數爲Boolean類型,而json裏的值是其它類型時,框架如何處理?html
一、true, false,正常賦值
二、int類型,若爲1,則爲true,不然爲false
三、number類型,若強轉int爲1,則爲true,不然爲false
四、string類型,若爲空串、"null"、"NULL"則爲null;若爲"true","1"則爲true;若爲"false","0"則爲false
四、其它狀況拋錯can not cast to booleanmysql
2、關於CURRENT_TIMESTAMP的問題:
執行如下SQL報錯:git
CREATE TABLE `test` ( `id` bigint(19) NOT NULL AUTO_INCREMENT, `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=INNODB;
錯誤:there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
緣由:MYSQL 5.6如下的版本只支持一個字段將當前時間戳爲默認值
四種處理方法:
一、當更新數據時,用觸發器去設置 update_time 爲當前時間
二、當插入數據時,用觸發器去設置 create_time 爲當前時間
三、create_time 設爲 CURRENT_TIMESTAMP,update_time設爲 '0000-00-00 00:00:00',更新、插入時去從新設置更新時間
四、更新MYSQL版本到5.6github
3、什麼是DDL,什麼是ONLINE DDL, 什麼是pt-online-schema-change?
DDL:數據定義語言DDL,用來建立數據庫中的各類對象-----表、視圖、索引、同義詞、聚簇
DML: insert, update, delete
DQL: select
DCL: 授予或回收訪問數據庫的某種特權,並控制數據庫操縱事務發生的時間及效果,對數據庫實行監視sql
MYSQL 5.1的DDL(添加索引):
建新表(包括新加的索引),鎖舊錶,拷數據到新表,改表名,刪舊錶數據庫
MYSQL 5.5,引入FIC(Fast Index Creation):
支持在新增刪除二級索引時,不去新建表,但仍需鎖表json
MYSQL 5.6引入ONLINE DDL:
支持在修改表結構的同時,依然容許DML操做,不是全部DDL操做都支持,具體需參考MYSQL官方文檔:https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html服務器
ONLINE DDL的一些限制:
一、不管是涉及到copy table仍是添加索引,都須要保證有足夠的磁盤大小
二、主從結構,主庫在DDL時,會同時執行DML操做,可是從庫因爲是單個SQL THREAD按順序應用log,因此得等ALTER語句執行完,才能夠執行下一條,這時會有主從延遲。
三、在進行 DDL 操做時會保存操做時間內產生的日誌,這與 facebook OSC 的臨時表,可是其保存在內存中,而該內存的大小由參數 innodb_online_alter_log_max_size 定義,默認大小爲 128M,若請求比較頻繁,須要進行調整。
四、ONLINE DDL執行期間,仍會有短期的排它鎖,如準備階段,提交階段。框架
pt-online-schema-change:
第三方工具,支持ONLINE DDLide
pt-online-schema-change 工做過程:
一、建新表
二、新表進行DDL操做
三、原表建立三種觸發器對應insert,update,delete
三、從原表拷貝數據到新表,期間的DML操做,經過觸發器更新到新表
四、鎖原表,改表名
五、刪舊錶
pt-online-schema-change的一些限制:
一、原表不容許有觸發器
二、原表必須有主鍵
參考博客:
https://cloud.tencent.com/developer/article/1005177
http://seanlook.com/2016/05/24/mysql-online-ddl-concept/
http://keithlan.github.io/2018/11/23/mysql_online_ddl_inside/
4、關於getBytes方法
背景:
使用第三方SDK,出現中文亂碼,依賴的SDK,有如下代碼:
headers.put(key, Base64Utils.encodeAsString(value.getBytes()));
出錯緣由:
vlaue.getBytes方法,在沒有設置字符集時,會默認以JVM默認的字符集(默認操做系統的字符集)進行處理。而服務器上,操做系統的字符集默認爲US-ASCII,而value其實是UTF-8的,這時候就出現了亂碼狀況。
解決方案:
配置JVM參數,設置JVM默認的字符集爲UTF-8:-Dfile.encoding=UTF-8
分析源碼:
public byte[] getBytes() { return StringCoding.encode(value, 0, value.length); } static byte[] encode(char[] ca, int off, int len) { String csn = Charset.defaultCharset().name(); try { // use charset name encode() variant which provides caching. return encode(csn, ca, off, len); } catch (UnsupportedEncodingException x) { warnUnsupportedCharset(csn); } try { return encode("ISO-8859-1", ca, off, len); } catch (UnsupportedEncodingException x) { // If this code is hit during VM initialization, MessageUtils is // the only way we will be able to get any kind of error message. MessageUtils.err("ISO-8859-1 charset not available: " + x.toString()); // If we can not find ISO-8859-1 (a required encoding) then things // are seriously wrong with the installation. System.exit(1); return null; } }
能夠發如今使用getBytes方法時,默認取使用Charset.defaultCharset()方法來得到字符集
而後再看defaultCharset()方法的源碼
private static volatile Charset defaultCharset; public static Charset defaultCharset() { if (defaultCharset == null) { synchronized (Charset.class) { String csn = AccessController.doPrivileged(new GetPropertyAction("file.encoding")); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; else defaultCharset = forName("UTF-8"); } } return defaultCharset; }
defaultCharset實際上是個單例,JVM啓動後,只會取加載一次file.encoding。而file.encoding在沒有配置的狀況,取的是操做系統的字符集。若想改變默認字符集,則能夠設置JVM參數:-Dfile.encoding=UTF-8