diff --git a/css/main.css b/css/main.css
index 7b73cf2d7b..e07e1b10ba 100644
--- a/css/main.css
+++ b/css/main.css
@@ -1,3 +1,3 @@
-/* build time:Mon Jun 19 2023 18:25:04 GMT+0800 (China Standard Time)*/
-html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}::selection{background:#262a30;color:#fff}body{position:relative;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif;font-size:14px;line-height:2;color:#555;background:#fff}@media (max-width:767px){body{padding-right:0!important}}@media (min-width:768px) and (max-width:991px){body{padding-right:0!important}}@media (min-width:1600px){body{font-size:16px}}h1,h2,h3,h4,h5,h6{margin:0;padding:0;font-weight:700;line-height:1.5;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif}h2,h3,h4,h5,h6{margin:20px 0 15px}h1{font-size:24px}@media (max-width:767px){h1{font-size:20px}}h2{font-size:22px}@media (max-width:767px){h2{font-size:18px}}h3{font-size:20px}@media (max-width:767px){h3{font-size:16px}}h4{font-size:18px}@media (max-width:767px){h4{font-size:14px}}h5{font-size:16px}@media (max-width:767px){h5{font-size:12px}}h6{font-size:14px}@media (max-width:767px){h6{font-size:10px}}p{margin:0 0 25px 0}a{color:#555;text-decoration:none;border-bottom:1px solid #999;word-wrap:break-word}a:hover{color:#222;border-bottom-color:#222}ul{list-style:none}blockquote{margin:0;padding:0}img{display:block;margin:auto;max-width:100%;height:auto}hr{margin:40px 0;height:3px;border:none;background-color:#ddd;background-image:repeating-linear-gradient(-45deg,#fff,#fff 4px,transparent 4px,transparent 8px)}blockquote{padding:0 15px;color:#666;border-left:4px solid #ddd}blockquote cite::before{content:"-";padding:0 5px}dt{font-weight:700}dd{margin:0;padding:0}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.center-block{display:block;margin-left:auto;margin-right:auto}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.pullquote{width:45%}.pullquote.left{float:left;margin-left:5px;margin-right:10px}.pullquote.right{float:right;margin-left:10px;margin-right:5px}.affix.affix.affix{position:fixed}.translation{margin-top:-20px;font-size:14px;color:#999}.scrollbar-measure{width:100px;height:100px;overflow:scroll;position:absolute;top:-9999px}.use-motion .motion-element{opacity:0}#local-search-input{padding:3px;border:none;text-indent:14px;border-radius:0;width:140px;outline:0;border-bottom:1px solid #999;background:inherit;opacity:.5}#local-search-input:focus{opacity:1}.search-icon{position:absolute;top:9px}table{margin:20px 0;width:100%;border-collapse:collapse;border-spacing:0;border:1px solid #ddd;font-size:14px;table-layout:fixed;word-wrap:break-all}table>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}table>tbody>tr:hover{background-color:#f5f5f5}caption,td,th{padding:8px;text-align:left;vertical-align:middle;font-weight:400}td,th{border-bottom:3px solid #ddd;border-right:1px solid #eee}th{padding-bottom:10px;font-weight:700}td{border-bottom-width:1px}body,html{height:100%}.container{position:relative;min-height:100%}.header-inner{margin:0 auto;padding:100px 0 70px;width:700px}@media (min-width:1600px){.container .header-inner{width:900px}}.main{padding-bottom:150px}.main-inner{margin:0 auto;width:700px}@media (min-width:1600px){.container .main-inner{width:900px}}.footer{position:absolute;left:0;bottom:0;width:100%;min-height:50px}.footer-inner{box-sizing:border-box;margin:20px auto;width:700px}@media (min-width:1600px){.container .footer-inner{width:900px}}.highlight,pre{overflow:auto;margin:20px 0;padding:0;font-size:13px;color:#c5c8c6;background:#1d1f21;line-height:1.6}code,pre{font-family:consolas,Menlo,"PingFang SC","Microsoft YaHei",monospace}code{padding:2px 4px;word-wrap:break-word;color:#c5c8c6;background:#1d1f21;border-radius:3px;font-size:13px}pre code{padding:0;color:#c5c8c6;background:0 0;text-shadow:none}.highlight{border-radius:1px}.highlight pre{border:none;margin:0;padding:10px 0}.highlight table{margin:0;width:auto;border:none}.highlight td{border:none;padding:0}.highlight figcaption{font-size:1em;color:#c5c8c6;line-height:1em;margin-bottom:1em}.highlight figcaption:after,.highlight figcaption:before{content:" ";display:table}.highlight figcaption:after{clear:both}.highlight figcaption a{float:right;color:#c5c8c6}.highlight figcaption a:hover{border-bottom-color:#c5c8c6}.highlight .gutter pre{padding-left:10px;padding-right:10px;color:#888f96;text-align:right;background-color:#000}.highlight .code pre{padding-left:10px;padding-right:10px;background-color:#1d1f21}.highlight .line{height:20px}.gutter{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.gist table{width:auto}.gist table td{border:none}pre .deletion{background:green}pre .addition{background:maroon}pre .meta{color:#b294bb}pre .comment{color:#969896}pre .attribute,pre .css .class,pre .css .id,pre .css .pseudo,pre .html .doctype,pre .regexp,pre .ruby .constant,pre .tag,pre .variable,pre .xml .doctype,pre .xml .pi,pre .xml .tag .title{color:#c66}pre .built_in,pre .command,pre .constant,pre .literal,pre .number,pre .params,pre .preprocessor{color:#de935f}pre .css .rules .attribute,pre .formula,pre .header,pre .inheritance,pre .number,pre .ruby .class .title,pre .ruby .symbol,pre .special,pre .string,pre .value,pre .xml .cdata{color:#b5bd68}pre .css .hexcolor,pre .title{color:#8abeb7}pre .coffeescript .title,pre .function,pre .javascript .title,pre .perl .sub,pre .python .decorator,pre .python .title,pre .ruby .function .title,pre .ruby .title .keyword{color:#81a2be}pre .javascript .function,pre .keyword{color:#b294bb}.full-image.full-image.full-image{border:none;max-width:100%;width:auto;margin:20px auto}@media (min-width:992px){.full-image.full-image.full-image{max-width:none;width:110%;margin:25px -5%}}.blockquote-center,.page-home .post-type-quote blockquote,.page-post-detail .post-type-quote blockquote{position:relative;margin:40px 0;padding:0;border-left:none;text-align:center}.blockquote-center::after,.blockquote-center::before,.page-home .post-type-quote blockquote::after,.page-home .post-type-quote blockquote::before,.page-post-detail .post-type-quote blockquote::after,.page-post-detail .post-type-quote blockquote::before{position:absolute;content:' ';display:block;width:100%;height:24px;opacity:.2;background-repeat:no-repeat;background-position:0 -6px;background-size:22px 22px}.blockquote-center::before,.page-home .post-type-quote blockquote::before,.page-post-detail .post-type-quote blockquote::before{top:-20px;background-image:url(../images/quote-l.svg);border-top:1px solid #ccc}.blockquote-center::after,.page-home .post-type-quote blockquote::after,.page-post-detail .post-type-quote blockquote::after{bottom:-20px;background-image:url(../images/quote-r.svg);border-bottom:1px solid #ccc;background-position:100% 8px}.blockquote-center div,.blockquote-center p,.page-home .post-type-quote blockquote div,.page-home .post-type-quote blockquote p,.page-post-detail .post-type-quote blockquote div,.page-post-detail .post-type-quote blockquote p{text-align:center}.post .post-body .group-picture img{box-sizing:border-box;padding:0 3px;border:none}.post .group-picture-row{overflow:hidden;margin-top:6px}.post .group-picture-row:first-child{margin-top:0}.post .group-picture-column{float:left}.page-post-detail .post-body .group-picture-column{float:none;margin-top:10px;width:auto!important}.page-post-detail .post-body .group-picture-column img{margin:0 auto}.page-archive .group-picture-container{overflow:hidden}.page-archive .group-picture-row{float:left}.page-archive .group-picture-row:first-child{margin-top:6px}.page-archive .group-picture-column{max-width:150px;max-height:150px}.note{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px}.note h2,.note h3,.note h4,.note h5,.note h6{margin-top:0;margin-bottom:5px}.note p:last-child{margin-bottom:0}.note code{border-radius:3px}.note+.note{margin-top:-5px}.default{border-left-color:#777}.default h2,.default h3,.default h4,.default h5,.default h6{color:#777}.primary{border-left-color:#428bca}.primary h2,.primary h3,.primary h4,.primary h5,.primary h6{color:#428bca}.success{border-left-color:#5cb85c}.success h2,.success h3,.success h4,.success h5,.success h6{color:#5cb85c}.danger{border-left-color:#d9534f}.danger h2,.danger h3,.danger h4,.danger h5,.danger h6{color:#d9534f}.warning{border-left-color:#f0ad4e}.warning h2,.warning h3,.warning h4,.warning h5,.warning h6{color:#f0ad4e}.info{border-left-color:#5bc0de}.info h2,.info h3,.info h4,.info h5,.info h6{color:#5bc0de}.btn{display:inline-block;padding:0 20px;font-size:14px;color:#fff;background:#222;border:2px solid #222;text-decoration:none;border-radius:0;transition-property:background-color;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.btn:hover,.post-button .btn:hover{border-color:#222;color:#222;background:#fff}.btn-bar{display:block;width:22px;height:2px;background:#555;border-radius:1px}.btn-bar+.btn-bar{margin-top:4px}.pagination{margin:120px 0 40px;text-align:center;border-top:1px solid #eee}.page-number-basic,.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{display:inline-block;position:relative;top:-1px;margin:0 10px;padding:0 10px;line-height:30px}@media (max-width:767px){.page-number-basic,.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{margin:0 5px}}.pagination .next,.pagination .page-number,.pagination .prev{border-bottom:0;border-top:1px solid #eee;transition-property:border-color;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-top-color:#222}.pagination .space{padding:0;margin:0}.pagination .prev{margin-left:0}.pagination .next{margin-right:0}.pagination .page-number.current{color:#fff;background:#ccc;border-top-color:#ccc}@media (max-width:767px){.pagination{border-top:none}.pagination .next,.pagination .page-number,.pagination .prev{margin-bottom:10px;border-top:0;border-bottom:1px solid #eee}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-bottom-color:#222}}.comments{margin:60px 20px 0}.tag-cloud{text-align:center}.tag-cloud a{display:inline-block;margin:10px}.back-to-top{box-sizing:border-box;position:fixed;bottom:-100px;right:50px;z-index:1050;padding:0 6px;width:25px;background:#222;font-size:12px;opacity:1;color:#fff;cursor:pointer;text-align:center;-webkit-transform:translateZ(0);transition-property:bottom;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}@media (max-width:767px){.back-to-top{display:none}}@media (min-width:768px) and (max-width:991px){.back-to-top{display:none}}.back-to-top.back-to-top-on{bottom:19px}.header{background:#fff}.header-inner{position:relative}.headband{height:3px;background:#222}.site-meta{margin:0;text-align:left}@media (max-width:767px){.site-meta{text-align:center}}.brand{position:relative;display:inline-block;padding:0 40px;color:#222;background:#222;border-bottom:none}.brand:hover{color:#222}.logo{display:inline-block;margin-right:5px;line-height:36px;vertical-align:top}.site-title{display:inline-block;vertical-align:top;line-height:36px;font-size:20px;font-weight:400;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif}.site-subtitle{margin-top:10px;font-size:13px;color:#999}.use-motion .brand{opacity:0}.use-motion .logo,.use-motion .site-subtitle,.use-motion .site-title{opacity:0;position:relative;top:-10px}.site-nav-toggle{display:none;position:absolute;top:10px;left:10px}@media (max-width:767px){.site-nav-toggle{display:block}}.site-nav-toggle button{margin-top:2px;padding:9px 10px;background:0 0;border:none}@media (max-width:767px){.site-nav{display:none;margin:0 -10px;padding:0 10px;clear:both;border-top:1px solid #ddd}}@media (min-width:768px) and (max-width:991px){.site-nav{display:block!important}}@media (min-width:992px){.site-nav{display:block!important}}.menu{margin-top:20px;padding-left:0;text-align:center}.menu .menu-item{display:inline-block;margin:0 10px}@media screen and (max-width:767px){.menu .menu-item{margin-top:10px}}.menu .menu-item a{display:block;font-size:13px;text-transform:capitalize;line-height:inherit;border-bottom:1px solid transparent;transition-property:border-color;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.menu .menu-item a:hover{border-bottom-color:#222}.menu .menu-item .fa{margin-right:5px}.use-motion .menu-item{opacity:0}.post-body{font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif}@media (max-width:767px){.post-body{word-break:break-word}}.post-body .fancybox img{display:block!important;margin:0 auto;cursor:pointer;cursor:zoom-in;cursor:-webkit-zoom-in}.post-body .figure .caption,.post-body .image-caption{margin:10px auto 15px;text-align:center;font-size:14px;color:#999;font-weight:700;line-height:1}.post-sticky-flag{display:inline-block;font-size:16px;-ms-transform:rotate(30deg);-webkit-transform:rotate(30deg);-moz-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}.posts-expand{padding-top:40px}@media (max-width:767px){.posts-expand{margin:0 20px}.post-body .highlight,.post-body pre{padding:10px}.post-body .highlight .gutter pre,.post-body pre .gutter pre{padding-right:10px}}@media (min-width:992px){.posts-expand .post-body{text-align:justify}}.posts-expand .post-body h2,.posts-expand .post-body h3,.posts-expand .post-body h4,.posts-expand .post-body h5,.posts-expand .post-body h6{padding-top:10px}.posts-expand .post-body h2 .header-anchor,.posts-expand .post-body h3 .header-anchor,.posts-expand .post-body h4 .header-anchor,.posts-expand .post-body h5 .header-anchor,.posts-expand .post-body h6 .header-anchor{float:right;margin-left:10px;color:#ccc;border-bottom-style:none;visibility:hidden}.posts-expand .post-body h2 .header-anchor:hover,.posts-expand .post-body h3 .header-anchor:hover,.posts-expand .post-body h4 .header-anchor:hover,.posts-expand .post-body h5 .header-anchor:hover,.posts-expand .post-body h6 .header-anchor:hover{color:inherit}.posts-expand .post-body h2:hover .header-anchor,.posts-expand .post-body h3:hover .header-anchor,.posts-expand .post-body h4:hover .header-anchor,.posts-expand .post-body h5:hover .header-anchor,.posts-expand .post-body h6:hover .header-anchor{visibility:visible}.posts-expand .post-body ul li{list-style:circle}.posts-expand .post-body img{box-sizing:border-box;margin:auto;padding:3px;border:1px solid #ddd}.posts-expand .fancybox img{margin:0 auto}@media (max-width:767px){.posts-collapse{margin:0 20px}.posts-collapse .post-meta,.posts-collapse .post-title{display:block;width:auto;text-align:left}}.posts-collapse{position:relative;z-index:1010;margin-left:0}.posts-collapse::after{content:" ";position:absolute;top:20px;left:0;margin-left:-2px;width:4px;height:100%;background:#f5f5f5;z-index:-1}@media (max-width:767px){.posts-collapse{margin:0 20px}}.posts-collapse .collection-title{position:relative;margin:60px 0}.posts-collapse .collection-title h2{margin-left:20px}.posts-collapse .collection-title small{color:#bbb}.posts-collapse .collection-title::before{content:" ";position:absolute;left:0;top:50%;margin-left:-4px;margin-top:-4px;width:8px;height:8px;background:#bbb;border-radius:50%}.posts-collapse .post{margin:30px 0}.posts-collapse .post-header{position:relative;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s;transition-property:border;border-bottom:1px dashed #ccc}.posts-collapse .post-header::before{content:" ";position:absolute;left:0;top:12px;width:6px;height:6px;margin-left:-4px;background:#bbb;border-radius:50%;border:1px solid #fff;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s;transition-property:background}.posts-collapse .post-header:hover{border-bottom-color:#666}.posts-collapse .post-header:hover::before{background:#222}.posts-collapse .post-meta{position:absolute;font-size:12px;left:20px;top:5px}.posts-collapse .post-comments-count{display:none}.posts-collapse .post-title{margin-left:60px;font-size:16px;font-weight:400;line-height:inherit}.posts-collapse .post-title::after{margin-left:3px;opacity:.6}.posts-collapse .post-title a{color:#666;border-bottom:none}.page-home .post-type-quote .post-header,.page-home .post-type-quote .post-tags,.page-post-detail .post-type-quote .post-header,.page-post-detail .post-type-quote .post-tags{display:none}.posts-expand .post-title{font-size:26px;text-align:center;word-break:break-word;font-weight:400}@media (max-width:767px){.posts-expand .post-title{font-size:22px}}.posts-expand .post-title-link{display:inline-block;position:relative;color:#555;border-bottom:none;line-height:1.2;vertical-align:top}.posts-expand .post-title-link::before{content:"";position:absolute;width:100%;height:2px;bottom:0;left:0;background-color:#000;visibility:hidden;-webkit-transform:scaleX(0);-moz-transform:scaleX(0);-ms-transform:scaleX(0);-o-transform:scaleX(0);transform:scaleX(0);transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.posts-expand .post-title-link:hover::before{visibility:visible;-webkit-transform:scaleX(1);-moz-transform:scaleX(1);-ms-transform:scaleX(1);-o-transform:scaleX(1);transform:scaleX(1)}.posts-expand .post-title-link .fa{font-size:16px}.posts-expand .post-meta{margin:3px 0 60px 0;color:#999;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif;font-size:12px;text-align:center}.posts-expand .post-meta .post-category-list{display:inline-block;margin:0;padding:3px}.posts-expand .post-meta .post-category-list-link{color:#999}.posts-expand .post-meta .post-description{font-size:14px;margin-top:2px}.post-meta-divider{margin:0 .5em}.post-meta-item-icon{margin-right:3px}@media (min-width:768px) and (max-width:991px){.post-meta-item-icon{display:inline-block}}@media (max-width:767px){.post-meta-item-icon{display:inline-block}}@media (min-width:768px) and (max-width:991px){.post-meta-item-text{display:none}}@media (max-width:767px){.post-meta-item-text{display:none}}@media (max-width:767px){.posts-expand .post-comments-count{display:none}}.social-like{font-size:14px;height:20px;text-align:center;border-top:1px solid #eee;padding-top:9px;margin-top:45px;display:flex;justify-content:center}.vk_like{width:85px;height:21px;padding-top:7px;align-self:center}.fb_like{height:30px;align-self:center}.post-button{margin-top:50px}.post-button .btn{color:#555;font-size:14px;background:0 0;border-radius:0;line-height:2;margin:0 4px 8px 4px}.post-button .fa-fw{width:1.285714285714286em;text-align:left}.posts-expand .post-tags{margin-top:40px;text-align:center}.posts-expand .post-tags a{display:inline-block;margin-right:10px;font-size:13px}.post-nav{display:table;margin-top:15px;width:100%;border-top:1px solid #eee}.post-nav-divider{display:table-cell;width:10%}.post-nav-item{display:table-cell;padding:10px 0 0 0;width:45%;vertical-align:top}.post-nav-item a{position:relative;display:block;line-height:25px;font-size:14px;color:#555;border-bottom:none}.post-nav-item a:hover{color:#222;border-bottom:none}.post-nav-item a:active{top:2px}.post-nav-item .fa{position:absolute;top:8px;left:0;font-size:12px}.post-nav-next a{padding-left:15px}.post-nav-prev{text-align:right}.post-nav-prev a{padding-right:15px}.post-nav-prev .fa{right:0;left:auto}.posts-expand .post-eof{display:block;margin:80px auto 60px;width:8%;height:1px;background:#ccc;text-align:center}.post:last-child .post-eof.post-eof.post-eof{display:none}.post-gallery{display:table;table-layout:fixed;width:100%;border-collapse:separate}.post-gallery-row{display:table-row}.post-gallery .post-gallery-img{display:table-cell;text-align:center;vertical-align:middle;border:none}.post-gallery .post-gallery-img img{max-width:100%;max-height:100%;border:none}.fancybox-close,.fancybox-close:hover{border:none}.sidebar{position:fixed;right:0;top:0;bottom:0;width:0;z-index:1040;box-shadow:inset 0 2px 6px #000;background:#222;-webkit-transform:translateZ(0)}.sidebar a{color:#999;border-bottom-color:#555}.sidebar a:hover{color:#eee}@media (min-width:768px) and (max-width:991px){.sidebar{display:none!important}}@media (max-width:767px){.sidebar{display:none!important}}.sidebar-inner{position:relative;padding:20px 10px;color:#999;text-align:center}.sidebar-toggle{position:fixed;right:50px;bottom:45px;width:15px;height:15px;padding:5px;background:#222;line-height:0;z-index:1050;cursor:pointer;-webkit-transform:translateZ(0)}@media (min-width:768px) and (max-width:991px){.sidebar-toggle{display:none}}@media (max-width:767px){.sidebar-toggle{display:none}}.sidebar-toggle-line{position:relative;display:inline-block;vertical-align:top;height:2px;width:100%;background:#fff;margin-top:3px}.sidebar-toggle-line:first-child{margin-top:0}.site-author-image{display:block;margin:0 auto;padding:2px;max-width:96px;height:auto;border:2px solid #333}.site-author-name{margin:5px 0 0;text-align:center;color:#f5f5f5;font-weight:400}.site-description{margin-top:5px;text-align:center;font-size:14px;color:#999}.site-state{overflow:hidden;line-height:1.4;white-space:nowrap;text-align:center}.site-state-item{display:inline-block;padding:0 15px;border-left:1px solid #333}.site-state-item:first-child{border-left:none}.site-state-item a{border-bottom:none}.site-state-item-count{display:block;text-align:center;color:inherit;font-weight:600;font-size:18px}.site-state-item-name{font-size:13px;color:inherit}.feed-link{margin-top:20px}.feed-link a{display:inline-block;padding:0 15px;color:#fc6423;border:1px solid #fc6423;border-radius:4px}.feed-link a i{color:#fc6423;font-size:14px}.feed-link a:hover{color:#fff;background:#fc6423}.feed-link a:hover i{color:#fff}.links-of-author{margin-top:20px}.links-of-author a{display:inline-block;vertical-align:middle;margin-right:10px;margin-bottom:10px;border-bottom-color:#555;font-size:13px}.links-of-author a:before{display:inline-block;vertical-align:middle;margin-right:3px;content:" ";width:4px;height:4px;border-radius:50%;background:#53c778}.links-of-blogroll{font-size:13px}.links-of-blogroll-title{margin-top:20px;font-size:14px;font-weight:600}.links-of-blogroll-list{margin:0;padding:0}.links-of-blogroll-item{padding:2px 10px}.sidebar-nav{margin:0 0 20px;padding-left:0}.sidebar-nav li{display:inline-block;cursor:pointer;border-bottom:1px solid transparent;font-size:14px;color:#555}.sidebar-nav li:hover{color:#f5f5f5}.page-post-detail .sidebar-nav-toc{padding:0 5px}.page-post-detail .sidebar-nav-overview{margin-left:10px}.sidebar-nav .sidebar-nav-active{color:#87daff;border-bottom-color:#87daff}.sidebar-nav .sidebar-nav-active:hover{color:#87daff}.sidebar-panel{display:none}.sidebar-panel-active{display:block}.post-toc-empty{font-size:14px;color:#666}.post-toc-wrap{overflow:hidden}.post-toc{overflow:auto}.post-toc ol{margin:0;padding:0 2px 5px 10px;text-align:left;list-style:none;font-size:14px}.post-toc ol>ol{padding-left:0}.post-toc ol a{transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s;transition-property:all;color:#999;border-bottom-color:#555}.post-toc ol a:hover{color:#ccc;border-bottom-color:#ccc}.post-toc .nav-item{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.8}.post-toc .nav .nav-child{display:none}.post-toc .nav .active>.nav-child{display:block}.post-toc .nav .active-current>.nav-child{display:block}.post-toc .nav .active-current>.nav-child>.nav-item{display:block}.post-toc .nav .active>a{color:#87daff;border-bottom-color:#87daff}.post-toc .nav .active-current>a{color:#87daff}.post-toc .nav .active-current>a:hover{color:#87daff}.footer{font-size:14px;color:#999}.footer img{border:none}.footer-inner{text-align:center}.with-love{display:inline-block;margin:0 5px}.powered-by,.theme-info{display:inline-block}.powered-by{margin-right:10px}.powered-by::after{content:"|";padding-left:10px}.cc-license{margin-top:10px;text-align:center}.cc-license .cc-opacity{opacity:.7;border-bottom:none}.cc-license .cc-opacity:hover{opacity:.9}.cc-license img{display:inline-block}.cloud-tie-wrapper img{display:inline-block}.cloud-tie-wrapper .total-txt{font-size:1em!important}.cloud-tie-join-count .join-count{color:#555!important;font-size:inherit!important;margin:0!important}.post-spread{margin-top:20px;text-align:center}.jiathis_style{display:inline-block}.jiathis_style a{border:none}.post-spread{margin-top:20px;text-align:center}.bdshare-slide-button-box a{border:none}.bdsharebuttonbox{display:inline-block}.bdsharebuttonbox a{border:none}ul.search-result-list{padding-left:0;margin:0 5px 0 8px}p.search-result{border-bottom:1px dashed #ccc;padding:5px 0}a.search-result-title{font-weight:700}a.search-result{border-bottom:transparent;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.search-keyword{border-bottom:1px dashed red;font-size:14px;font-weight:700;color:red}#local-search-result{height:88%;overflow:auto}.popup{display:none;position:fixed;top:10%;left:50%;width:700px;height:80%;margin-left:-350px;padding:3px 0 0 10px;background:#fff;color:#333;z-index:9999;border-radius:5px}@media (max-width:767px){.popup{padding:3px;top:0;left:0;margin:0;width:100%;height:100%;border-radius:0}}.popoverlay{position:fixed;width:100%;height:100%;top:0;left:0;z-index:2080;background-color:rgba(0,0,0,.3)}#local-search-input{margin-bottom:10px;padding:10px;width:97%;font-size:18px}.popup .fa-search{padding-top:8px}.popup-btn-close{position:absolute;top:6px;right:14px;color:#4ebd79;font-size:14px;font-weight:700;text-transform:uppercase;cursor:pointer}#no-result{position:absolute;left:44%;top:42%;color:#ccc}.use-motion .post{opacity:0}.page-archive .archive-page-counter{position:relative;top:3px;left:20px}@media (max-width:767px){.page-archive .archive-page-counter{top:5px}}.page-archive .posts-collapse .archive-move-on{position:absolute;top:11px;left:0;margin-left:-6px;width:10px;height:10px;opacity:.5;background:#555;border:1px solid #fff;border-radius:50%}.category-all-page .category-all-title{text-align:center}.category-all-page .category-all{margin-top:20px}.category-all-page .category-list{margin:0;padding:0;list-style:none}.category-all-page .category-list-item{margin:5px 10px}.category-all-page .category-list-count{color:#bbb}.category-all-page .category-list-count:before{display:inline;content:" ("}.category-all-page .category-list-count:after{display:inline;content:") "}.category-all-page .category-list-child{padding-left:10px}#schedule ul#event-list{padding-left:30px}#schedule ul#event-list hr{margin:20px 0 45px 0!important;background:#222}#schedule ul#event-list hr:after{display:inline-block;content:'NOW';background:#222;color:#fff;font-weight:700;text-align:right;padding:0 5px}#schedule ul#event-list li.event{margin:20px 0;background:#f9f9f9;padding-left:10px;min-height:40px}#schedule ul#event-list li.event h2.event-summary{margin:0;padding-bottom:3px}#schedule ul#event-list li.event h2.event-summary:before{display:inline-block;font-family:FontAwesome;font-size:8px;content:'\f111';vertical-align:middle;margin-right:25px;color:#bbb}#schedule ul#event-list li.event span.event-relative-time{display:inline-block;font-size:12px;font-weight:400;padding-left:12px;color:#bbb}#schedule ul#event-list li.event span.event-details{display:block;color:#bbb;margin-left:56px;padding-top:3px;padding-bottom:6px;text-indent:-24px;line-height:18px}#schedule ul#event-list li.event span.event-details:before{text-indent:0;display:inline-block;width:14px;font-family:FontAwesome;text-align:center;margin-right:9px;color:#bbb}#schedule ul#event-list li.event span.event-details.event-location:before{content:'\f041'}#schedule ul#event-list li.event span.event-details.event-duration:before{content:'\f017'}#schedule ul#event-list li.event-past{background:#fcfcfc}#schedule ul#event-list li.event-past>*{opacity:.6}#schedule ul#event-list li.event-past h2.event-summary{color:#bbb}#schedule ul#event-list li.event-past h2.event-summary:before{color:#dfdfdf}#schedule ul#event-list li.event-now{background:#222;color:#fff;padding:15px 0 15px 10px}#schedule ul#event-list li.event-now h2.event-summary:before{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2);color:#fff;animation:dot-flash 1s alternate infinite ease-in-out}#schedule ul#event-list li.event-now *{color:#fff!important}@-moz-keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-webkit-keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-o-keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}.page-post-detail .sidebar-toggle-line{background:#87daff}.page-post-detail .comments{overflow:hidden}h1,h2,h3,h4,h5,h6{margin:20px 0 10px}p{margin:0 0 25px 0}a{border-bottom-color:#ccc}hr{margin:20px 0;height:2px}.main-inner{margin-top:80px}.header{background:#f5f5f5}.header-inner{padding:25px 0 20px}.header-inner:after,.header-inner:before{content:" ";display:table}.header-inner:after{clear:both}@media (max-width:767px){.header-inner{width:auto;margin-bottom:50px;padding:10px}}.site-meta{float:left;margin-left:-20px;line-height:normal}@media (max-width:767px){.site-meta{margin-left:10px}}.site-meta .brand{padding:2px 1px;background:0 0}@media (max-width:767px){.site-meta .brand{display:block}}.site-meta .logo{display:none}.site-meta .site-title{font-size:22px;font-weight:bolder}@media (max-width:767px){.site-meta .site-title{line-height:34px}}.logo-line-after,.logo-line-before{display:block;overflow:hidden;margin:0 auto;width:75%}@media (max-width:767px){.logo-line-after,.logo-line-before{display:none}}.logo-line-after i,.logo-line-before i{position:relative;display:block;height:2px;background:#222}@media (max-width:767px){.logo-line-after i,.logo-line-before i{height:3px}}.use-motion .logo-line-before i{left:-100%}.use-motion .logo-line-after i{right:-100%}.site-subtitle{display:none}.site-nav-toggle{position:static;float:right}.menu{float:right;margin:8px 0 0 0}@media (max-width:767px){.menu{margin:20px 0 0 0;padding:0}}.menu br{display:none}.menu .menu-item{margin:0}@media (max-width:767px){.menu .menu-item{display:block}}.menu .menu-item a{padding:0 10px;background:0 0;border:none;border-radius:2px;transition-property:background}@media (max-width:767px){.menu .menu-item a{text-align:left}}.menu .menu-item a:hover{background:#e1e1e1}.menu a::before{display:none}@media (max-width:767px){.menu a::before{display:block}}@media (max-width:767px){.menu{float:none}}.site-search form{display:none}.posts-expand{padding-top:0}.posts-expand .post-meta,.posts-expand .post-title{text-align:left}@media (max-width:767px){.posts-expand .post-meta,.posts-expand .post-title{text-align:center}}.posts-expand .post-eof{display:none}.posts-expand .post{margin-top:120px}.posts-expand .post:first-child{margin-top:0}.posts-expand .post-meta{margin-top:5px;margin-bottom:20px}.posts-expand .post-title{position:relative;font-size:26px;font-weight:400}@media (max-width:767px){.posts-expand .post-title{font-size:20px}}@media (min-width:1600px){.posts-expand .post-title{font-size:26px}}.posts-expand .post-title:hover:before{background:#222}.posts-expand .post-body img{margin:0}.posts-expand .post-tags{text-align:left}.posts-expand .post-tags a{padding:1px 5px;background:#f5f5f5;border-bottom:none}.posts-expand .post-tags a:hover{background:#ccc}.posts-expand .post-nav{margin-top:40px}.post-button{margin-top:20px;text-align:left}.post-button a{margin:0 8px 8px 0!important;padding:0;font-size:14px;color:#666;background:0 0;border:none;border-bottom:2px solid #666;transition-property:border}@media (max-width:767px){.post-button a{font-size:12px}}@media (min-width:1600px){.post-button a{font-size:16px}}.post-button a:hover{border-bottom-color:#222}.links-of-blogroll-inline .links-of-blogroll-item{display:inline-block}.btn{padding:0 10px;border-width:2px;border-radius:0}.headband{display:none}.site-search{position:relative;float:right;margin-top:5px;padding-top:3px}@media (max-width:767px){.site-search{float:none;padding:0 10px}}@media (max-width:767px){.container .main-inner{width:auto}}.page-post-detail .post-meta,.page-post-detail .post-title{text-align:center}.page-post-detail .post-title:before{display:none}.page-post-detail .post-meta{margin-bottom:60px}.pagination{margin:120px 0 0;text-align:left}@media (max-width:767px){.pagination{margin:80px 10px 0;text-align:center}}.footer{margin-top:80px;padding:10px 0;background:#f5f5f5;color:#666}.footer-inner{margin:0 auto;text-align:left}@media (max-width:767px){.footer-inner{width:auto;text-align:center}}
+/* build time:Thu Aug 10 2023 15:47:26 GMT+0800 (China Standard Time)*/
+html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}::selection{background:#262a30;color:#fff}body{position:relative;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif;font-size:14px;line-height:2;color:#555;background:#fff}@media (max-width:767px){body{padding-right:0!important}}@media (min-width:768px) and (max-width:991px){body{padding-right:0!important}}@media (min-width:1600px){body{font-size:16px}}h1,h2,h3,h4,h5,h6{margin:0;padding:0;font-weight:700;line-height:1.5;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif}h2,h3,h4,h5,h6{margin:20px 0 15px}h1{font-size:24px}@media (max-width:767px){h1{font-size:20px}}h2{font-size:22px}@media (max-width:767px){h2{font-size:18px}}h3{font-size:20px}@media (max-width:767px){h3{font-size:16px}}h4{font-size:18px}@media (max-width:767px){h4{font-size:14px}}h5{font-size:16px}@media (max-width:767px){h5{font-size:12px}}h6{font-size:14px}@media (max-width:767px){h6{font-size:10px}}p{margin:0 0 25px 0}a{color:#555;text-decoration:none;border-bottom:1px solid #999;word-wrap:break-word}a:hover{color:#222;border-bottom-color:#222}ul{list-style:none}blockquote{margin:0;padding:0}img{display:block;margin:auto;max-width:100%;height:auto}hr{margin:40px 0;height:3px;border:none;background-color:#ddd;background-image:repeating-linear-gradient(-45deg,#fff,#fff 4px,transparent 4px,transparent 8px)}blockquote{padding:0 15px;color:#666;border-left:4px solid #ddd}blockquote cite::before{content:"-";padding:0 5px}dt{font-weight:700}dd{margin:0;padding:0}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.center-block{display:block;margin-left:auto;margin-right:auto}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.pullquote{width:45%}.pullquote.left{float:left;margin-left:5px;margin-right:10px}.pullquote.right{float:right;margin-left:10px;margin-right:5px}.affix.affix.affix{position:fixed}.translation{margin-top:-20px;font-size:14px;color:#999}.scrollbar-measure{width:100px;height:100px;overflow:scroll;position:absolute;top:-9999px}.use-motion .motion-element{opacity:0}#local-search-input{padding:3px;border:none;text-indent:14px;border-radius:0;width:140px;outline:0;border-bottom:1px solid #999;background:inherit;opacity:.5}#local-search-input:focus{opacity:1}.search-icon{position:absolute;top:9px}table{margin:20px 0;width:100%;border-collapse:collapse;border-spacing:0;border:1px solid #ddd;font-size:14px;table-layout:fixed;word-wrap:break-all}table>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}table>tbody>tr:hover{background-color:#f5f5f5}caption,td,th{padding:8px;text-align:left;vertical-align:middle;font-weight:400}td,th{border-bottom:3px solid #ddd;border-right:1px solid #eee}th{padding-bottom:10px;font-weight:700}td{border-bottom-width:1px}body,html{height:100%}.container{position:relative;min-height:100%}.header-inner{margin:0 auto;padding:100px 0 70px;width:700px}@media (min-width:1600px){.container .header-inner{width:900px}}.main{padding-bottom:150px}.main-inner{margin:0 auto;width:700px}@media (min-width:1600px){.container .main-inner{width:900px}}.footer{position:absolute;left:0;bottom:0;width:100%;min-height:50px}.footer-inner{box-sizing:border-box;margin:20px auto;width:700px}@media (min-width:1600px){.container .footer-inner{width:900px}}.highlight,pre{overflow:auto;margin:20px 0;padding:0;font-size:13px;color:#c5c8c6;background:#1d1f21;line-height:1.6}code,pre{font-family:consolas,Menlo,"PingFang SC","Microsoft YaHei",monospace}code{padding:2px 4px;word-wrap:break-word;color:#c5c8c6;background:#1d1f21;border-radius:3px;font-size:13px}pre code{padding:0;color:#c5c8c6;background:0 0;text-shadow:none}.highlight{border-radius:1px}.highlight pre{border:none;margin:0;padding:10px 0}.highlight table{margin:0;width:auto;border:none}.highlight td{border:none;padding:0}.highlight figcaption{font-size:1em;color:#c5c8c6;line-height:1em;margin-bottom:1em}.highlight figcaption:after,.highlight figcaption:before{content:" ";display:table}.highlight figcaption:after{clear:both}.highlight figcaption a{float:right;color:#c5c8c6}.highlight figcaption a:hover{border-bottom-color:#c5c8c6}.highlight .gutter pre{padding-left:10px;padding-right:10px;color:#888f96;text-align:right;background-color:#000}.highlight .code pre{padding-left:10px;padding-right:10px;background-color:#1d1f21}.highlight .line{height:20px}.gutter{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.gist table{width:auto}.gist table td{border:none}pre .deletion{background:green}pre .addition{background:maroon}pre .meta{color:#b294bb}pre .comment{color:#969896}pre .attribute,pre .css .class,pre .css .id,pre .css .pseudo,pre .html .doctype,pre .regexp,pre .ruby .constant,pre .tag,pre .variable,pre .xml .doctype,pre .xml .pi,pre .xml .tag .title{color:#c66}pre .built_in,pre .command,pre .constant,pre .literal,pre .number,pre .params,pre .preprocessor{color:#de935f}pre .css .rules .attribute,pre .formula,pre .header,pre .inheritance,pre .number,pre .ruby .class .title,pre .ruby .symbol,pre .special,pre .string,pre .value,pre .xml .cdata{color:#b5bd68}pre .css .hexcolor,pre .title{color:#8abeb7}pre .coffeescript .title,pre .function,pre .javascript .title,pre .perl .sub,pre .python .decorator,pre .python .title,pre .ruby .function .title,pre .ruby .title .keyword{color:#81a2be}pre .javascript .function,pre .keyword{color:#b294bb}.full-image.full-image.full-image{border:none;max-width:100%;width:auto;margin:20px auto}@media (min-width:992px){.full-image.full-image.full-image{max-width:none;width:110%;margin:25px -5%}}.blockquote-center,.page-home .post-type-quote blockquote,.page-post-detail .post-type-quote blockquote{position:relative;margin:40px 0;padding:0;border-left:none;text-align:center}.blockquote-center::after,.blockquote-center::before,.page-home .post-type-quote blockquote::after,.page-home .post-type-quote blockquote::before,.page-post-detail .post-type-quote blockquote::after,.page-post-detail .post-type-quote blockquote::before{position:absolute;content:' ';display:block;width:100%;height:24px;opacity:.2;background-repeat:no-repeat;background-position:0 -6px;background-size:22px 22px}.blockquote-center::before,.page-home .post-type-quote blockquote::before,.page-post-detail .post-type-quote blockquote::before{top:-20px;background-image:url(../images/quote-l.svg);border-top:1px solid #ccc}.blockquote-center::after,.page-home .post-type-quote blockquote::after,.page-post-detail .post-type-quote blockquote::after{bottom:-20px;background-image:url(../images/quote-r.svg);border-bottom:1px solid #ccc;background-position:100% 8px}.blockquote-center div,.blockquote-center p,.page-home .post-type-quote blockquote div,.page-home .post-type-quote blockquote p,.page-post-detail .post-type-quote blockquote div,.page-post-detail .post-type-quote blockquote p{text-align:center}.post .post-body .group-picture img{box-sizing:border-box;padding:0 3px;border:none}.post .group-picture-row{overflow:hidden;margin-top:6px}.post .group-picture-row:first-child{margin-top:0}.post .group-picture-column{float:left}.page-post-detail .post-body .group-picture-column{float:none;margin-top:10px;width:auto!important}.page-post-detail .post-body .group-picture-column img{margin:0 auto}.page-archive .group-picture-container{overflow:hidden}.page-archive .group-picture-row{float:left}.page-archive .group-picture-row:first-child{margin-top:6px}.page-archive .group-picture-column{max-width:150px;max-height:150px}.note{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px}.note h2,.note h3,.note h4,.note h5,.note h6{margin-top:0;margin-bottom:5px}.note p:last-child{margin-bottom:0}.note code{border-radius:3px}.note+.note{margin-top:-5px}.default{border-left-color:#777}.default h2,.default h3,.default h4,.default h5,.default h6{color:#777}.primary{border-left-color:#428bca}.primary h2,.primary h3,.primary h4,.primary h5,.primary h6{color:#428bca}.success{border-left-color:#5cb85c}.success h2,.success h3,.success h4,.success h5,.success h6{color:#5cb85c}.danger{border-left-color:#d9534f}.danger h2,.danger h3,.danger h4,.danger h5,.danger h6{color:#d9534f}.warning{border-left-color:#f0ad4e}.warning h2,.warning h3,.warning h4,.warning h5,.warning h6{color:#f0ad4e}.info{border-left-color:#5bc0de}.info h2,.info h3,.info h4,.info h5,.info h6{color:#5bc0de}.btn{display:inline-block;padding:0 20px;font-size:14px;color:#fff;background:#222;border:2px solid #222;text-decoration:none;border-radius:0;transition-property:background-color;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.btn:hover,.post-button .btn:hover{border-color:#222;color:#222;background:#fff}.btn-bar{display:block;width:22px;height:2px;background:#555;border-radius:1px}.btn-bar+.btn-bar{margin-top:4px}.pagination{margin:120px 0 40px;text-align:center;border-top:1px solid #eee}.page-number-basic,.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{display:inline-block;position:relative;top:-1px;margin:0 10px;padding:0 10px;line-height:30px}@media (max-width:767px){.page-number-basic,.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{margin:0 5px}}.pagination .next,.pagination .page-number,.pagination .prev{border-bottom:0;border-top:1px solid #eee;transition-property:border-color;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-top-color:#222}.pagination .space{padding:0;margin:0}.pagination .prev{margin-left:0}.pagination .next{margin-right:0}.pagination .page-number.current{color:#fff;background:#ccc;border-top-color:#ccc}@media (max-width:767px){.pagination{border-top:none}.pagination .next,.pagination .page-number,.pagination .prev{margin-bottom:10px;border-top:0;border-bottom:1px solid #eee}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-bottom-color:#222}}.comments{margin:60px 20px 0}.tag-cloud{text-align:center}.tag-cloud a{display:inline-block;margin:10px}.back-to-top{box-sizing:border-box;position:fixed;bottom:-100px;right:50px;z-index:1050;padding:0 6px;width:25px;background:#222;font-size:12px;opacity:1;color:#fff;cursor:pointer;text-align:center;-webkit-transform:translateZ(0);transition-property:bottom;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}@media (max-width:767px){.back-to-top{display:none}}@media (min-width:768px) and (max-width:991px){.back-to-top{display:none}}.back-to-top.back-to-top-on{bottom:19px}.header{background:#fff}.header-inner{position:relative}.headband{height:3px;background:#222}.site-meta{margin:0;text-align:left}@media (max-width:767px){.site-meta{text-align:center}}.brand{position:relative;display:inline-block;padding:0 40px;color:#222;background:#222;border-bottom:none}.brand:hover{color:#222}.logo{display:inline-block;margin-right:5px;line-height:36px;vertical-align:top}.site-title{display:inline-block;vertical-align:top;line-height:36px;font-size:20px;font-weight:400;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif}.site-subtitle{margin-top:10px;font-size:13px;color:#999}.use-motion .brand{opacity:0}.use-motion .logo,.use-motion .site-subtitle,.use-motion .site-title{opacity:0;position:relative;top:-10px}.site-nav-toggle{display:none;position:absolute;top:10px;left:10px}@media (max-width:767px){.site-nav-toggle{display:block}}.site-nav-toggle button{margin-top:2px;padding:9px 10px;background:0 0;border:none}@media (max-width:767px){.site-nav{display:none;margin:0 -10px;padding:0 10px;clear:both;border-top:1px solid #ddd}}@media (min-width:768px) and (max-width:991px){.site-nav{display:block!important}}@media (min-width:992px){.site-nav{display:block!important}}.menu{margin-top:20px;padding-left:0;text-align:center}.menu .menu-item{display:inline-block;margin:0 10px}@media screen and (max-width:767px){.menu .menu-item{margin-top:10px}}.menu .menu-item a{display:block;font-size:13px;text-transform:capitalize;line-height:inherit;border-bottom:1px solid transparent;transition-property:border-color;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.menu .menu-item a:hover{border-bottom-color:#222}.menu .menu-item .fa{margin-right:5px}.use-motion .menu-item{opacity:0}.post-body{font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif}@media (max-width:767px){.post-body{word-break:break-word}}.post-body .fancybox img{display:block!important;margin:0 auto;cursor:pointer;cursor:zoom-in;cursor:-webkit-zoom-in}.post-body .figure .caption,.post-body .image-caption{margin:10px auto 15px;text-align:center;font-size:14px;color:#999;font-weight:700;line-height:1}.post-sticky-flag{display:inline-block;font-size:16px;-ms-transform:rotate(30deg);-webkit-transform:rotate(30deg);-moz-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}.posts-expand{padding-top:40px}@media (max-width:767px){.posts-expand{margin:0 20px}.post-body .highlight,.post-body pre{padding:10px}.post-body .highlight .gutter pre,.post-body pre .gutter pre{padding-right:10px}}@media (min-width:992px){.posts-expand .post-body{text-align:justify}}.posts-expand .post-body h2,.posts-expand .post-body h3,.posts-expand .post-body h4,.posts-expand .post-body h5,.posts-expand .post-body h6{padding-top:10px}.posts-expand .post-body h2 .header-anchor,.posts-expand .post-body h3 .header-anchor,.posts-expand .post-body h4 .header-anchor,.posts-expand .post-body h5 .header-anchor,.posts-expand .post-body h6 .header-anchor{float:right;margin-left:10px;color:#ccc;border-bottom-style:none;visibility:hidden}.posts-expand .post-body h2 .header-anchor:hover,.posts-expand .post-body h3 .header-anchor:hover,.posts-expand .post-body h4 .header-anchor:hover,.posts-expand .post-body h5 .header-anchor:hover,.posts-expand .post-body h6 .header-anchor:hover{color:inherit}.posts-expand .post-body h2:hover .header-anchor,.posts-expand .post-body h3:hover .header-anchor,.posts-expand .post-body h4:hover .header-anchor,.posts-expand .post-body h5:hover .header-anchor,.posts-expand .post-body h6:hover .header-anchor{visibility:visible}.posts-expand .post-body ul li{list-style:circle}.posts-expand .post-body img{box-sizing:border-box;margin:auto;padding:3px;border:1px solid #ddd}.posts-expand .fancybox img{margin:0 auto}@media (max-width:767px){.posts-collapse{margin:0 20px}.posts-collapse .post-meta,.posts-collapse .post-title{display:block;width:auto;text-align:left}}.posts-collapse{position:relative;z-index:1010;margin-left:0}.posts-collapse::after{content:" ";position:absolute;top:20px;left:0;margin-left:-2px;width:4px;height:100%;background:#f5f5f5;z-index:-1}@media (max-width:767px){.posts-collapse{margin:0 20px}}.posts-collapse .collection-title{position:relative;margin:60px 0}.posts-collapse .collection-title h2{margin-left:20px}.posts-collapse .collection-title small{color:#bbb}.posts-collapse .collection-title::before{content:" ";position:absolute;left:0;top:50%;margin-left:-4px;margin-top:-4px;width:8px;height:8px;background:#bbb;border-radius:50%}.posts-collapse .post{margin:30px 0}.posts-collapse .post-header{position:relative;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s;transition-property:border;border-bottom:1px dashed #ccc}.posts-collapse .post-header::before{content:" ";position:absolute;left:0;top:12px;width:6px;height:6px;margin-left:-4px;background:#bbb;border-radius:50%;border:1px solid #fff;transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s;transition-property:background}.posts-collapse .post-header:hover{border-bottom-color:#666}.posts-collapse .post-header:hover::before{background:#222}.posts-collapse .post-meta{position:absolute;font-size:12px;left:20px;top:5px}.posts-collapse .post-comments-count{display:none}.posts-collapse .post-title{margin-left:60px;font-size:16px;font-weight:400;line-height:inherit}.posts-collapse .post-title::after{margin-left:3px;opacity:.6}.posts-collapse .post-title a{color:#666;border-bottom:none}.page-home .post-type-quote .post-header,.page-home .post-type-quote .post-tags,.page-post-detail .post-type-quote .post-header,.page-post-detail .post-type-quote .post-tags{display:none}.posts-expand .post-title{font-size:26px;text-align:center;word-break:break-word;font-weight:400}@media (max-width:767px){.posts-expand .post-title{font-size:22px}}.posts-expand .post-title-link{display:inline-block;position:relative;color:#555;border-bottom:none;line-height:1.2;vertical-align:top}.posts-expand .post-title-link::before{content:"";position:absolute;width:100%;height:2px;bottom:0;left:0;background-color:#000;visibility:hidden;-webkit-transform:scaleX(0);-moz-transform:scaleX(0);-ms-transform:scaleX(0);-o-transform:scaleX(0);transform:scaleX(0);transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s}.posts-expand .post-title-link:hover::before{visibility:visible;-webkit-transform:scaleX(1);-moz-transform:scaleX(1);-ms-transform:scaleX(1);-o-transform:scaleX(1);transform:scaleX(1)}.posts-expand .post-title-link .fa{font-size:16px}.posts-expand .post-meta{margin:3px 0 60px 0;color:#999;font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serif;font-size:12px;text-align:center}.posts-expand .post-meta .post-category-list{display:inline-block;margin:0;padding:3px}.posts-expand .post-meta .post-category-list-link{color:#999}.posts-expand .post-meta .post-description{font-size:14px;margin-top:2px}.post-meta-divider{margin:0 .5em}.post-meta-item-icon{margin-right:3px}@media (min-width:768px) and (max-width:991px){.post-meta-item-icon{display:inline-block}}@media (max-width:767px){.post-meta-item-icon{display:inline-block}}@media (min-width:768px) and (max-width:991px){.post-meta-item-text{display:none}}@media (max-width:767px){.post-meta-item-text{display:none}}@media (max-width:767px){.posts-expand .post-comments-count{display:none}}.social-like{font-size:14px;height:20px;text-align:center;border-top:1px solid #eee;padding-top:9px;margin-top:45px;display:flex;justify-content:center}.vk_like{width:85px;height:21px;padding-top:7px;align-self:center}.fb_like{height:30px;align-self:center}.post-button{margin-top:50px}.post-button .btn{color:#555;font-size:14px;background:0 0;border-radius:0;line-height:2;margin:0 4px 8px 4px}.post-button .fa-fw{width:1.285714285714286em;text-align:left}.posts-expand .post-tags{margin-top:40px;text-align:center}.posts-expand .post-tags a{display:inline-block;margin-right:10px;font-size:13px}.post-nav{display:table;margin-top:15px;width:100%;border-top:1px solid #eee}.post-nav-divider{display:table-cell;width:10%}.post-nav-item{display:table-cell;padding:10px 0 0 0;width:45%;vertical-align:top}.post-nav-item a{position:relative;display:block;line-height:25px;font-size:14px;color:#555;border-bottom:none}.post-nav-item a:hover{color:#222;border-bottom:none}.post-nav-item a:active{top:2px}.post-nav-item .fa{position:absolute;top:8px;left:0;font-size:12px}.post-nav-next a{padding-left:15px}.post-nav-prev{text-align:right}.post-nav-prev a{padding-right:15px}.post-nav-prev .fa{right:0;left:auto}.posts-expand .post-eof{display:block;margin:80px auto 60px;width:8%;height:1px;background:#ccc;text-align:center}.post:last-child .post-eof.post-eof.post-eof{display:none}.post-gallery{display:table;table-layout:fixed;width:100%;border-collapse:separate}.post-gallery-row{display:table-row}.post-gallery .post-gallery-img{display:table-cell;text-align:center;vertical-align:middle;border:none}.post-gallery .post-gallery-img img{max-width:100%;max-height:100%;border:none}.fancybox-close,.fancybox-close:hover{border:none}.sidebar{position:fixed;right:0;top:0;bottom:0;width:0;z-index:1040;box-shadow:inset 0 2px 6px #000;background:#222;-webkit-transform:translateZ(0)}.sidebar a{color:#999;border-bottom-color:#555}.sidebar a:hover{color:#eee}@media (min-width:768px) and (max-width:991px){.sidebar{display:none!important}}@media (max-width:767px){.sidebar{display:none!important}}.sidebar-inner{position:relative;padding:20px 10px;color:#999;text-align:center}.sidebar-toggle{position:fixed;right:50px;bottom:45px;width:15px;height:15px;padding:5px;background:#222;line-height:0;z-index:1050;cursor:pointer;-webkit-transform:translateZ(0)}@media (min-width:768px) and (max-width:991px){.sidebar-toggle{display:none}}@media (max-width:767px){.sidebar-toggle{display:none}}.sidebar-toggle-line{position:relative;display:inline-block;vertical-align:top;height:2px;width:100%;background:#fff;margin-top:3px}.sidebar-toggle-line:first-child{margin-top:0}.site-author-image{display:block;margin:0 auto;padding:2px;max-width:96px;height:auto;border:2px solid #333}.site-author-name{margin:5px 0 0;text-align:center;color:#f5f5f5;font-weight:400}.site-description{margin-top:5px;text-align:center;font-size:14px;color:#999}.site-state{overflow:hidden;line-height:1.4;white-space:nowrap;text-align:center}.site-state-item{display:inline-block;padding:0 15px;border-left:1px solid #333}.site-state-item:first-child{border-left:none}.site-state-item a{border-bottom:none}.site-state-item-count{display:block;text-align:center;color:inherit;font-weight:600;font-size:18px}.site-state-item-name{font-size:13px;color:inherit}.feed-link{margin-top:20px}.feed-link a{display:inline-block;padding:0 15px;color:#fc6423;border:1px solid #fc6423;border-radius:4px}.feed-link a i{color:#fc6423;font-size:14px}.feed-link a:hover{color:#fff;background:#fc6423}.feed-link a:hover i{color:#fff}.links-of-author{margin-top:20px}.links-of-author a{display:inline-block;vertical-align:middle;margin-right:10px;margin-bottom:10px;border-bottom-color:#555;font-size:13px}.links-of-author a:before{display:inline-block;vertical-align:middle;margin-right:3px;content:" ";width:4px;height:4px;border-radius:50%;background:#4260ff}.links-of-blogroll{font-size:13px}.links-of-blogroll-title{margin-top:20px;font-size:14px;font-weight:600}.links-of-blogroll-list{margin:0;padding:0}.links-of-blogroll-item{padding:2px 10px}.sidebar-nav{margin:0 0 20px;padding-left:0}.sidebar-nav li{display:inline-block;cursor:pointer;border-bottom:1px solid transparent;font-size:14px;color:#555}.sidebar-nav li:hover{color:#f5f5f5}.page-post-detail .sidebar-nav-toc{padding:0 5px}.page-post-detail .sidebar-nav-overview{margin-left:10px}.sidebar-nav .sidebar-nav-active{color:#87daff;border-bottom-color:#87daff}.sidebar-nav .sidebar-nav-active:hover{color:#87daff}.sidebar-panel{display:none}.sidebar-panel-active{display:block}.post-toc-empty{font-size:14px;color:#666}.post-toc-wrap{overflow:hidden}.post-toc{overflow:auto}.post-toc ol{margin:0;padding:0 2px 5px 10px;text-align:left;list-style:none;font-size:14px}.post-toc ol>ol{padding-left:0}.post-toc ol a{transition-duration:.2s;transition-timing-function:ease-in-out;transition-delay:0s;transition-property:all;color:#999;border-bottom-color:#555}.post-toc ol a:hover{color:#ccc;border-bottom-color:#ccc}.post-toc .nav-item{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.8}.post-toc .nav .nav-child{display:none}.post-toc .nav .active>.nav-child{display:block}.post-toc .nav .active-current>.nav-child{display:block}.post-toc .nav .active-current>.nav-child>.nav-item{display:block}.post-toc .nav .active>a{color:#87daff;border-bottom-color:#87daff}.post-toc .nav .active-current>a{color:#87daff}.post-toc .nav .active-current>a:hover{color:#87daff}.footer{font-size:14px;color:#999}.footer img{border:none}.footer-inner{text-align:center}.with-love{display:inline-block;margin:0 5px}.powered-by,.theme-info{display:inline-block}.powered-by{margin-right:10px}.powered-by::after{content:"|";padding-left:10px}.cc-license{margin-top:10px;text-align:center}.cc-license .cc-opacity{opacity:.7;border-bottom:none}.cc-license .cc-opacity:hover{opacity:.9}.cc-license img{display:inline-block}.cloud-tie-wrapper img{display:inline-block}.cloud-tie-wrapper .total-txt{font-size:1em!important}.cloud-tie-join-count .join-count{color:#555!important;font-size:inherit!important;margin:0!important}.post-spread{margin-top:20px;text-align:center}.jiathis_style{display:inline-block}.jiathis_style a{border:none}.post-spread{margin-top:20px;text-align:center}.bdshare-slide-button-box a{border:none}.bdsharebuttonbox{display:inline-block}.bdsharebuttonbox a{border:none}ul.search-result-list{padding-left:0;margin:0 5px 0 8px}p.search-result{border-bottom:1px dashed #ccc;padding:5px 0}a.search-result-title{font-weight:700}a.search-result{border-bottom:transparent;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.search-keyword{border-bottom:1px dashed red;font-size:14px;font-weight:700;color:red}#local-search-result{height:88%;overflow:auto}.popup{display:none;position:fixed;top:10%;left:50%;width:700px;height:80%;margin-left:-350px;padding:3px 0 0 10px;background:#fff;color:#333;z-index:9999;border-radius:5px}@media (max-width:767px){.popup{padding:3px;top:0;left:0;margin:0;width:100%;height:100%;border-radius:0}}.popoverlay{position:fixed;width:100%;height:100%;top:0;left:0;z-index:2080;background-color:rgba(0,0,0,.3)}#local-search-input{margin-bottom:10px;padding:10px;width:97%;font-size:18px}.popup .fa-search{padding-top:8px}.popup-btn-close{position:absolute;top:6px;right:14px;color:#4ebd79;font-size:14px;font-weight:700;text-transform:uppercase;cursor:pointer}#no-result{position:absolute;left:44%;top:42%;color:#ccc}.use-motion .post{opacity:0}.page-archive .archive-page-counter{position:relative;top:3px;left:20px}@media (max-width:767px){.page-archive .archive-page-counter{top:5px}}.page-archive .posts-collapse .archive-move-on{position:absolute;top:11px;left:0;margin-left:-6px;width:10px;height:10px;opacity:.5;background:#555;border:1px solid #fff;border-radius:50%}.category-all-page .category-all-title{text-align:center}.category-all-page .category-all{margin-top:20px}.category-all-page .category-list{margin:0;padding:0;list-style:none}.category-all-page .category-list-item{margin:5px 10px}.category-all-page .category-list-count{color:#bbb}.category-all-page .category-list-count:before{display:inline;content:" ("}.category-all-page .category-list-count:after{display:inline;content:") "}.category-all-page .category-list-child{padding-left:10px}#schedule ul#event-list{padding-left:30px}#schedule ul#event-list hr{margin:20px 0 45px 0!important;background:#222}#schedule ul#event-list hr:after{display:inline-block;content:'NOW';background:#222;color:#fff;font-weight:700;text-align:right;padding:0 5px}#schedule ul#event-list li.event{margin:20px 0;background:#f9f9f9;padding-left:10px;min-height:40px}#schedule ul#event-list li.event h2.event-summary{margin:0;padding-bottom:3px}#schedule ul#event-list li.event h2.event-summary:before{display:inline-block;font-family:FontAwesome;font-size:8px;content:'\f111';vertical-align:middle;margin-right:25px;color:#bbb}#schedule ul#event-list li.event span.event-relative-time{display:inline-block;font-size:12px;font-weight:400;padding-left:12px;color:#bbb}#schedule ul#event-list li.event span.event-details{display:block;color:#bbb;margin-left:56px;padding-top:3px;padding-bottom:6px;text-indent:-24px;line-height:18px}#schedule ul#event-list li.event span.event-details:before{text-indent:0;display:inline-block;width:14px;font-family:FontAwesome;text-align:center;margin-right:9px;color:#bbb}#schedule ul#event-list li.event span.event-details.event-location:before{content:'\f041'}#schedule ul#event-list li.event span.event-details.event-duration:before{content:'\f017'}#schedule ul#event-list li.event-past{background:#fcfcfc}#schedule ul#event-list li.event-past>*{opacity:.6}#schedule ul#event-list li.event-past h2.event-summary{color:#bbb}#schedule ul#event-list li.event-past h2.event-summary:before{color:#dfdfdf}#schedule ul#event-list li.event-now{background:#222;color:#fff;padding:15px 0 15px 10px}#schedule ul#event-list li.event-now h2.event-summary:before{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2);color:#fff;animation:dot-flash 1s alternate infinite ease-in-out}#schedule ul#event-list li.event-now *{color:#fff!important}@-moz-keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-webkit-keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-o-keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes dot-flash{from{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}to{opacity:0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}.page-post-detail .sidebar-toggle-line{background:#87daff}.page-post-detail .comments{overflow:hidden}h1,h2,h3,h4,h5,h6{margin:20px 0 10px}p{margin:0 0 25px 0}a{border-bottom-color:#ccc}hr{margin:20px 0;height:2px}.main-inner{margin-top:80px}.header{background:#f5f5f5}.header-inner{padding:25px 0 20px}.header-inner:after,.header-inner:before{content:" ";display:table}.header-inner:after{clear:both}@media (max-width:767px){.header-inner{width:auto;margin-bottom:50px;padding:10px}}.site-meta{float:left;margin-left:-20px;line-height:normal}@media (max-width:767px){.site-meta{margin-left:10px}}.site-meta .brand{padding:2px 1px;background:0 0}@media (max-width:767px){.site-meta .brand{display:block}}.site-meta .logo{display:none}.site-meta .site-title{font-size:22px;font-weight:bolder}@media (max-width:767px){.site-meta .site-title{line-height:34px}}.logo-line-after,.logo-line-before{display:block;overflow:hidden;margin:0 auto;width:75%}@media (max-width:767px){.logo-line-after,.logo-line-before{display:none}}.logo-line-after i,.logo-line-before i{position:relative;display:block;height:2px;background:#222}@media (max-width:767px){.logo-line-after i,.logo-line-before i{height:3px}}.use-motion .logo-line-before i{left:-100%}.use-motion .logo-line-after i{right:-100%}.site-subtitle{display:none}.site-nav-toggle{position:static;float:right}.menu{float:right;margin:8px 0 0 0}@media (max-width:767px){.menu{margin:20px 0 0 0;padding:0}}.menu br{display:none}.menu .menu-item{margin:0}@media (max-width:767px){.menu .menu-item{display:block}}.menu .menu-item a{padding:0 10px;background:0 0;border:none;border-radius:2px;transition-property:background}@media (max-width:767px){.menu .menu-item a{text-align:left}}.menu .menu-item a:hover{background:#e1e1e1}.menu a::before{display:none}@media (max-width:767px){.menu a::before{display:block}}@media (max-width:767px){.menu{float:none}}.site-search form{display:none}.posts-expand{padding-top:0}.posts-expand .post-meta,.posts-expand .post-title{text-align:left}@media (max-width:767px){.posts-expand .post-meta,.posts-expand .post-title{text-align:center}}.posts-expand .post-eof{display:none}.posts-expand .post{margin-top:120px}.posts-expand .post:first-child{margin-top:0}.posts-expand .post-meta{margin-top:5px;margin-bottom:20px}.posts-expand .post-title{position:relative;font-size:26px;font-weight:400}@media (max-width:767px){.posts-expand .post-title{font-size:20px}}@media (min-width:1600px){.posts-expand .post-title{font-size:26px}}.posts-expand .post-title:hover:before{background:#222}.posts-expand .post-body img{margin:0}.posts-expand .post-tags{text-align:left}.posts-expand .post-tags a{padding:1px 5px;background:#f5f5f5;border-bottom:none}.posts-expand .post-tags a:hover{background:#ccc}.posts-expand .post-nav{margin-top:40px}.post-button{margin-top:20px;text-align:left}.post-button a{margin:0 8px 8px 0!important;padding:0;font-size:14px;color:#666;background:0 0;border:none;border-bottom:2px solid #666;transition-property:border}@media (max-width:767px){.post-button a{font-size:12px}}@media (min-width:1600px){.post-button a{font-size:16px}}.post-button a:hover{border-bottom-color:#222}.links-of-blogroll-inline .links-of-blogroll-item{display:inline-block}.btn{padding:0 10px;border-width:2px;border-radius:0}.headband{display:none}.site-search{position:relative;float:right;margin-top:5px;padding-top:3px}@media (max-width:767px){.site-search{float:none;padding:0 10px}}@media (max-width:767px){.container .main-inner{width:auto}}.page-post-detail .post-meta,.page-post-detail .post-title{text-align:center}.page-post-detail .post-title:before{display:none}.page-post-detail .post-meta{margin-bottom:60px}.pagination{margin:120px 0 0;text-align:left}@media (max-width:767px){.pagination{margin:80px 10px 0;text-align:center}}.footer{margin-top:80px;padding:10px 0;background:#f5f5f5;color:#666}.footer-inner{margin:0 auto;text-align:left}@media (max-width:767px){.footer-inner{width:auto;text-align:center}}
/* rebuild by neat */
\ No newline at end of file
diff --git a/lib/fancybox/source/helpers/jquery.fancybox-buttons.css b/lib/fancybox/source/helpers/jquery.fancybox-buttons.css
index 1f93dd9775..8619b9174a 100644
--- a/lib/fancybox/source/helpers/jquery.fancybox-buttons.css
+++ b/lib/fancybox/source/helpers/jquery.fancybox-buttons.css
@@ -1,3 +1,3 @@
-/* build time:Mon Jun 19 2023 18:25:04 GMT+0800 (China Standard Time)*/
+/* build time:Thu Aug 10 2023 15:47:26 GMT+0800 (China Standard Time)*/
#fancybox-buttons{position:fixed;left:0;width:100%;z-index:8050}#fancybox-buttons.top{top:10px}#fancybox-buttons.bottom{bottom:10px}#fancybox-buttons ul{display:block;width:166px;height:30px;margin:0 auto;padding:0;list-style:none;border:1px solid #111;border-radius:3px;-webkit-box-shadow:inset 0 0 0 1px rgba(255,255,255,.05);-moz-box-shadow:inset 0 0 0 1px rgba(255,255,255,.05);box-shadow:inset 0 0 0 1px rgba(255,255,255,.05);background:#323232;background:-moz-linear-gradient(top,#444 0,#343434 50%,#292929 50%,#333 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#444),color-stop(50%,#343434),color-stop(50%,#292929),color-stop(100%,#333));background:-webkit-linear-gradient(top,#444 0,#343434 50%,#292929 50%,#333 100%);background:-o-linear-gradient(top,#444 0,#343434 50%,#292929 50%,#333 100%);background:-ms-linear-gradient(top,#444 0,#343434 50%,#292929 50%,#333 100%);background:linear-gradient(top,#444 0,#343434 50%,#292929 50%,#333 100%)}#fancybox-buttons ul li{float:left;margin:0;padding:0}#fancybox-buttons a{display:block;width:30px;height:30px;text-indent:-9999px;background-color:transparent;background-image:url(fancybox_buttons.png);background-repeat:no-repeat;outline:0;opacity:.8}#fancybox-buttons a:hover{opacity:1}#fancybox-buttons a.btnPrev{background-position:5px 0}#fancybox-buttons a.btnNext{background-position:-33px 0;border-right:1px solid #3e3e3e}#fancybox-buttons a.btnPlay{background-position:0 -30px}#fancybox-buttons a.btnPlayOn{background-position:-30px -30px}#fancybox-buttons a.btnToggle{background-position:3px -60px;border-left:1px solid #111;border-right:1px solid #3e3e3e;width:35px}#fancybox-buttons a.btnToggleOn{background-position:-27px -60px}#fancybox-buttons a.btnClose{border-left:1px solid #111;width:35px;background-position:-56px 0}#fancybox-buttons a.btnDisabled{opacity:.4;cursor:default}
/* rebuild by neat */
\ No newline at end of file
diff --git a/lib/fancybox/source/helpers/jquery.fancybox-thumbs.css b/lib/fancybox/source/helpers/jquery.fancybox-thumbs.css
index 0ea776fcf3..a21a0823e2 100644
--- a/lib/fancybox/source/helpers/jquery.fancybox-thumbs.css
+++ b/lib/fancybox/source/helpers/jquery.fancybox-thumbs.css
@@ -1,3 +1,3 @@
-/* build time:Mon Jun 19 2023 18:25:04 GMT+0800 (China Standard Time)*/
+/* build time:Thu Aug 10 2023 15:47:26 GMT+0800 (China Standard Time)*/
#fancybox-thumbs{position:fixed;left:0;width:100%;overflow:hidden;z-index:8050}#fancybox-thumbs.bottom{bottom:2px}#fancybox-thumbs.top{top:2px}#fancybox-thumbs ul{position:relative;list-style:none;margin:0;padding:0}#fancybox-thumbs ul li{float:left;padding:1px;opacity:.5}#fancybox-thumbs ul li.active{opacity:.75;padding:0;border:1px solid #fff}#fancybox-thumbs ul li:hover{opacity:1}#fancybox-thumbs ul li a{display:block;position:relative;overflow:hidden;border:1px solid #222;background:#111;outline:0}#fancybox-thumbs ul li img{display:block;position:relative;border:0;padding:0;max-width:none}
/* rebuild by neat */
\ No newline at end of file
diff --git a/lib/fancybox/source/jquery.fancybox.css b/lib/fancybox/source/jquery.fancybox.css
index d8e8e1fd60..b16c2d8176 100644
--- a/lib/fancybox/source/jquery.fancybox.css
+++ b/lib/fancybox/source/jquery.fancybox.css
@@ -1,3 +1,3 @@
-/* build time:Mon Jun 19 2023 18:25:04 GMT+0800 (China Standard Time)*/
+/* build time:Thu Aug 10 2023 15:47:26 GMT+0800 (China Standard Time)*/
/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */.fancybox-image,.fancybox-inner,.fancybox-nav,.fancybox-nav span,.fancybox-outer,.fancybox-skin,.fancybox-tmp,.fancybox-wrap,.fancybox-wrap iframe,.fancybox-wrap object{padding:0;margin:0;border:0;outline:0;vertical-align:top}.fancybox-wrap{position:absolute;top:0;left:0;z-index:8020}.fancybox-skin{position:relative;background:#f9f9f9;color:#444;text-shadow:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.fancybox-opened{z-index:8030}.fancybox-opened .fancybox-skin{-webkit-box-shadow:0 10px 25px rgba(0,0,0,.5);-moz-box-shadow:0 10px 25px rgba(0,0,0,.5);box-shadow:0 10px 25px rgba(0,0,0,.5)}.fancybox-inner,.fancybox-outer{position:relative}.fancybox-inner{overflow:hidden}.fancybox-type-iframe .fancybox-inner{-webkit-overflow-scrolling:touch}.fancybox-error{color:#444;font:14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;margin:0;padding:15px;white-space:nowrap}.fancybox-iframe,.fancybox-image{display:block;width:100%;height:100%}.fancybox-image{max-width:100%;max-height:100%}#fancybox-loading,.fancybox-close,.fancybox-next span,.fancybox-prev span{background-image:url(fancybox_sprite.png)}#fancybox-loading{position:fixed;top:50%;left:50%;margin-top:-22px;margin-left:-22px;background-position:0 -108px;opacity:.8;cursor:pointer;z-index:8060}#fancybox-loading div{width:44px;height:44px;background:url(fancybox_loading.gif) center center no-repeat}.fancybox-close{position:absolute;top:-18px;right:-18px;width:36px;height:36px;cursor:pointer;z-index:8040}.fancybox-nav{position:absolute;top:0;width:40%;height:100%;cursor:pointer;text-decoration:none;background:transparent url(blank.gif);-webkit-tap-highlight-color:transparent;z-index:8040}.fancybox-prev{left:0}.fancybox-next{right:0}.fancybox-nav span{position:absolute;top:50%;width:36px;height:34px;margin-top:-18px;cursor:pointer;z-index:8040;visibility:hidden}.fancybox-prev span{left:10px;background-position:0 -36px}.fancybox-next span{right:10px;background-position:0 -72px}.fancybox-nav:hover span{visibility:visible}.fancybox-tmp{position:absolute;top:-99999px;left:-99999px;visibility:hidden;max-width:99999px;max-height:99999px;overflow:visible!important}.fancybox-lock{overflow:hidden!important;width:auto}.fancybox-lock body{overflow:hidden!important}.fancybox-lock-test{overflow-y:hidden!important}.fancybox-overlay{position:absolute;top:0;left:0;overflow:hidden;display:none;z-index:8010;background:url(fancybox_overlay.png)}.fancybox-overlay-fixed{position:fixed;bottom:0;right:0}.fancybox-lock .fancybox-overlay{overflow:auto;overflow-y:scroll}.fancybox-title{visibility:hidden;font:normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;position:relative;text-shadow:none;z-index:8050}.fancybox-opened .fancybox-title{visibility:visible}.fancybox-title-float-wrap{position:absolute;bottom:0;right:50%;margin-bottom:-35px;z-index:8050;text-align:center}.fancybox-title-float-wrap .child{display:inline-block;margin-right:-100%;padding:2px 20px;background:0 0;background:rgba(0,0,0,.8);-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;text-shadow:0 1px 2px #222;color:#fff;font-weight:700;line-height:24px;white-space:nowrap}.fancybox-title-outside-wrap{position:relative;margin-top:10px;color:#fff}.fancybox-title-inside-wrap{padding-top:10px}.fancybox-title-over-wrap{position:absolute;bottom:0;left:0;color:#fff;padding:10px;background:#000;background:rgba(0,0,0,.8)}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){#fancybox-loading,.fancybox-close,.fancybox-next span,.fancybox-prev span{background-image:url(fancybox_sprite@2x.png);background-size:44px 152px}#fancybox-loading div{background-image:url(fancybox_loading@2x.gif);background-size:24px 24px}}
/* rebuild by neat */
\ No newline at end of file
diff --git a/lib/font-awesome/css/font-awesome.css b/lib/font-awesome/css/font-awesome.css
index 9a48413e5a..232896c62e 100644
--- a/lib/font-awesome/css/font-awesome.css
+++ b/lib/font-awesome/css/font-awesome.css
@@ -1,4 +1,4 @@
-/* build time:Mon Jun 19 2023 18:25:04 GMT+0800 (China Standard Time)*/
+/* build time:Thu Aug 10 2023 15:47:26 GMT+0800 (China Standard Time)*/
/*!
* Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
diff --git a/search.xml b/search.xml
index 5288a807c6..23575666f3 100644
--- a/search.xml
+++ b/search.xml
@@ -1,6408 +1,2825 @@
- 会改变程序执行的堆栈 不会改变代码堆栈流 就这个群晖的网卡,困扰了我两天。 可能这是 DS918+ 之类才会遇到的问题 搜索引擎很多 https://github.com/bb-qq/r8152/releases 下载完成,在群晖套件中心,手动安装,选择刚刚下载的驱动文件安装 修改之后,再次安装即可完成。 由于群晖918+等型号对 lan 口限制了最大 2 个,这里需要修改两个配置文件。 群晖 DS918+,USB 外置网卡安装好驱动,设置好 maxlan 之后, 设置局域网 3 (外置网卡) 为自动获取 IP 后,网络正常,系统控制面积显示正常 需要注册 Cloudflare 账号 速度的话一般,勉强可以接受。 OpenWrt 官方关于 netgear r8000 的信息 128M 的空间,安装 OpenWrt 之后就剩下 21M 的空间可以安装插件 插上 U盘 至 USB3 插口 安装相关软件 格式化 U盘 至 ext4 挂载 U盘 至 overlay 最近看了不少软路由的东西 在官方原版的 OpenWrt 22.03 版本中 安装完成之后,再按教程操作即可. 电商场景下的订单系统 待更新 待更新 入坑水族几年,和年纪无关… 最近几天在折腾过滤, 不懂的多百度,设备什么的购物平台搜搜。 需要有一定的金钱投入,更重要的是精力投入,长期维护。 养宠物之前 鳄鱼龟:互动性不错,有点危险,长的很快. 鱼缸 龟缸 选择透明的玻璃容器,观赏性比较好 龟缸 俗话说,养鱼先养水。 关于自来水 使用过滤器 尽量增大水体体积 滤材表面积大利于细菌进行生长繁殖,可保持干净稳定的水。 异养细菌,把食物残渣、动物粪便等,转化成无机物,氨气(对动物有害)等。 水循环大概过程: 硝化细菌:属于生产者,包括亚硝酸细菌(将氨氧化成亚硝酸),硝酸细菌(将亚硝酸氧化成硝酸), 自养生物(英语:autotroph)也称为生产者(producer) 异养生物(英语:heterotroph),也称为消费者( consumer) 现有的长城 100M 宽带太寒酸了 桥接的好处就是,光猫只做光猫该做的事情。 这一步是需要联系安装宽带的师傅 重点 我的路由器是网件 R8000,输入账号密码等配置生效。 找到 IPv6 相关设置(高级—高级设置—IPv6) 至于为什么要 IPv6,那只能说懂得都懂,啊哈哈。 桥接上网 由于目前经常需要登录数据库查询相关数据 限制:需要在堡垒机进行操作 expect是一个自动化交互套件, Awk是一种便于使用且表达能力强的程序设计语言, 说明:基于 expect 说明:通过 shell 动态获取登录信息 设置完成之后,输入 ma 命令,即可自动登录到 MySQL 客户端 某做科研的朋友 BD09 vs WGS84 找了几个网址,反馈说之前用过坐标不准确 服务免费 我没有选择 IP 白名单 接口文档 简单说明 CoordinateTransformUtil 在参考文档 注意,第一个文档的接口已经过时,新申请的用户无法使用 鉴于目前 Redis 使用广泛 大规模互联网在线应用 对于读多写少的场景,一般作为缓存使用 对于可容忍丢数据,但是对性能有极致要求, 《Redis开发与运维》20 1121~1122 dbsize 获取当前数据库中键总数,复杂度 O(1) keys * 复杂度 O(n) type key 返回 redis 外部数据结构 object encoding key 返回 redis 内部编码实现 redis 为单线程模型,所有命令都进队列。 redis 单线程为何还这么快? 锁和线程切换通常是性能杀手。 单线程可以简化数据结构和算法。 由于是单线程,所以对每个命令执行时间有要求。 mget 结果是按照传入键的顺序返回。 redis 中每个中文占 3 个字节 字符串类型的内部编码有 3 种: list 的 lrange 操作获取指定索引范围的元素。 对于字符串类型的键,再次执行 set 命令会将上次的过期时间去掉。 纯内存存储、I/O多路复用技术、单线程架构是 redis 高性能的三个因素。 了解每个命令的时间复杂度在 redis 命令真正执行的时间通常在微妙级别,所以才会有 redis 性能瓶颈是网络的说法。 原生批命令与 pipeline 的区别: pipeline 只能操作一个 redis 实例,但即使在分布式 redis 场景中,也可以作为批量操作的重要优化手段。 redis 3.2 版本提供了 geo 功能,支持 LBS 服务。 输出缓冲区由两部分组成: RESP(Redis Serialization Protocol Redis),协议。 jedis 没有内置序列化工具,需要自己选用。 理解 redis 通信原理和建立完善的监控系统对快速定位客户端常见问题非常有帮助。 redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理,压缩后的文件远远小于内存大小。 正常情况下,fork 操作耗时应该是每 GB 消耗 20 毫秒左右。 redis 是 CPU 密集型服务,不要做绑定单核 CPU 操作。 子进程通过 fork 操作产生,理论上需要两倍的内存来完成持久化, 复制功能是高可用 redis 的基础。 主从复制延迟,redis 提供了 repl-disable-tcp-nodelay 参数控制是否关闭, 对于写并发量较高的场景, psync 2.8 以上支持,有全量复制,部分复制 redis 支持无盘复制,repl-diskless-sync,试验阶段, 为了降低主从延迟, 对于读写分离,会造成从节点数据延迟, 为了保证复制一致性,从节点自身永远不会主动删除超时数据。 建议做读写分离之前, redis-cli –bigkeys 带宽瓶颈通常出现在以下几个方面: 网络快慢:同物理机 > 同机架 > 跨机架 > 同机房 > 同城机房 > 异地机房 redis 进程的内存消耗主要包括:自身内存 + 对象内存 + 缓冲内存 + 内存碎片。 对象内存是 redis 内存占用最大的一块,存储着用户所有的数据。 输入输出缓冲区在大流量的场景中容易失控,造成 redis 内存的不稳定,需要重点关注。 由于进程内保存大量的键, 在高并发放场景下,建议字符串长度控制在 39 字节以内, 尽量减少字符串频繁修改操作如 append、setrange, redis sentinel 有一套合理的监控机来判断节点不可达,有三个定时任务: redis 使用 raft 算法实现领导者的选举。 redis sentinel 是 redis 的高可用方案实现:故障发现、故障自动转移、配置中心、客户端通知 redis sentinel 模式下,客户端初始化连接的是 sentinel 节点集合, redis cluster 是 redis 的分布式解决方案。当遇到单机内存、并发、流量等瓶颈时, redis cluster 之前的分布式方案: 数据分区是分布式存储的核心, redis cluster 限制: 在分布式存储中需要提供维护节点元数据信息的机制, 常见的元数据维护方式分为:集中式、P2P方式 redis cluster 采用 P2P 的 Gossip(流言) 协议, 虽然 Gossip 协议的信息交换机制具有天然的分布式特性,但他是有成本的。 集群内 Gossip 消息通信本身会消耗带宽,官方建议集群最大规模在 1000 以内。 redis cluster 可以实现对节点的灵活上下线控制。 集群伸缩=槽和数据在节点之间移动。 MOVED 重定向:在集群模式下 redis 接收 key 相关命令先计算对应的槽,再根据槽找到节点, 键使用大括号包含的内容又叫做 hash_tag,它提供不同的键可以具备相同的 slot 功能, smart 客户端通过在内部维护 jediscluster 解析 cluster slots 结果缓存到本地,为每个节点创建唯一的 jedispool 连接池。 cluster slots 风暴: 针对以上问题,jedis 2.8.2 版本做了改进: jedis cluster 中由于 key 分布在不同的节点上,会造成无法实现 mget、mset 等功能。 ASK 与 MOVED 都是对客户端重定向控制,ASK 表示集群正在进行 slot 迁移, 配置纪元的应用场景有: 配置纪元的主要作用: 唯品会开发的 redis-migrate-tool 支持在线迁移, 缓存更新策略最佳实践 缓存粒度问题 使用布隆过滤器减少缓存击穿,page 351 无底洞:投入越多不一定产出越多 无底洞优化 NTP 是一种保证不同时钟一致性的服务。 redis cluster | sentinel 如果多个节点时间不一致, redis 公网无密码情况下,黑客可以写入公钥,通过设置 rdb 文件目录到 /root/.ssh 目录, redis bind 参数指定的是 redis 和哪个网卡绑定(建议绑定内网),和客户端什么网段没有关系。 bigkey,一般字符串类型 value 超过 10KB 就是 bigkey 了,但这个值和具体的 OPS 相关。 redis 查看 key 的大小:debug object key 最近在做重构的项目 目前的 AOP 应用,由于公司生态体系不够完善 PS:链路追踪蛮重要,针对排查问题,性能监控等大有帮助,多关注开源协议/实现( 如 CNCF ) 目前做的项目当中,有一个 IDC 负载均衡的工具 当然,由于知识浅薄,AOP 写对了,但是不生效,工具初始化的先于 AOP 的作用时间。 接下来就通过搜索引起各种找,偶然发现 BeanPostProcess (之前也通过一些 spring 回调做应用预热) 于是就开始一番操作,果然给解决问题了。 之前一直在做业务开发 spring 生命周期,启动流程,各种回调,有必要看看,跑 demo 试试。 最近在做数据迁移 从结果可以看出,一味地追求新颖也不是好事,需要知其然 压测教程:JMH 使用参考 其中不错的一点我觉得是 这样巧妙的计算,避免了先取模,后判断是否有余数的繁杂。 ps:是谁说数学没用的 ???? 过年期间,看到 github 关注的人的动态当中 前面介绍学习的好处让我心动了 不得不说,环境搭建特别方便! 技术方面今年感觉成长不是太明显 本年度阅读图书 38 本 收获较多的为以下几本: 唯一的变化可能是多了 2 只鳄鱼龟。 下半年由于工作原因,晚睡较多,很少早起。 这些年能坚持下来的也就只有下面两个了~ 同事分享《Effective Java》 // 是否需要加 static?才能保证单例正确 带 static 的结果符合预期 开始执行 开始执行 static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。 关键:static 变量在内存中只有一个副本,由所有对象共享。 不知在哪听说过陆奇的传说 榜样的力量或许很虚,关键看自己能悟多少,是否坚持行动。共勉! 大部分人还不了解陆奇,但他值得让我们好好了解一下: 这几年陆奇被格外关注,始于2017年1月17日他被百度任命为百度总裁。这次任命份量极高,到今天百度创立19年,李彦宏给出如此高的权力,陆奇是唯一一个。 但陆奇值得。 陆奇在硅谷非常有名,拥有不错的人脉和江湖地位,凡接触过陆奇的人提起他,几乎是众口一词地称赞。 1998年陆奇加入雅虎,2007年任雅虎执行副总裁。 2008年他辞职时,杨致远当场洒泪,告别会上所有工程师穿上统一的T恤,T恤上印着“我曾与陆奇一起工作,你呢?”,以此纪念陆奇在雅虎的日子。 2008年加入微软,任全球执行副总裁,这是有史以来,华人在科技领域获得的最高职位。 2016年9月离职时,比尔·盖茨极力挽留甚至承诺:“你想要做什么业务,我们去搞个业务给你。或者你先休假一年两年,然后再回来当首席技术官,我们等着你就是了。” 微软现任 CEO 纳德拉曾对微软员工说:“五个人,对微软贡献巨大。一是创始人比尔·盖茨,二是CEO史蒂夫·鲍尔默,三是董事会主席约翰·汤普森,四是诗人奥斯卡·王尔德,最后一个就是陆奇。” 其实早在2005年前后,李彦宏就曾试图说服陆奇加入百度,只是当时并未如愿。 2017年陆奇加入百度后,李彦宏曾公开给了他很高的评价:陆奇上上下下有口皆碑,大家都很喜欢他,他有非常强的技术能力,又有很强的管理能力,并且工作极其玩命。 陆奇身上有太多值得我们学习的地方。 前段时间《晚点》采访时就问陆奇: 你对20、30、40岁的年轻人各有什么建议? 陆奇: 20岁需要做让你可以走得很快的事情,快速学、快速失败。30岁你要让自己可以走得远,建立一个核心支撑体系能让你走得很远。这个体系包括你的身体、你厚实的家庭基础和几个志同道合你可以信任的朋友。 一个人到了35岁,到了打造产品的黄金时段,我已前很关注这个年龄阶段的人才,因为他/她已经犯过不少错,他/她最需要做一个好产品让他/她的职业生涯有一个本质提升。 40岁后,理想情况是找到一个可以让你淋漓尽致去发挥的舞台,一个人的才华和一个公司的才华只有在真正被释放的情况下才能实现它的价值。如果这个舞台是你自己的最好。 这个回答很经典,我反复看了很多遍。但要真的看懂看透,我们还必须要放在陆奇的整个人生系统里看,我一口气翻看了所有关于陆奇重要的中文报道,从中得到了一个更完整清晰的答案。 20岁:做让自己走得快的事情 陆奇:“20岁需要做让你可以走得很快的事情,快速学、快速失败。” 1、20多岁,习得什么能力最重要? 陆奇认为有两个: 学习能力:在这个变化速度越来越快的世界里,拥有学习和持续学习的能力,不断提高自己在某一个专业领域以及在企业内开发产品和业务的认知能力是基础。 原因很简单,因为创新,世界变化的速度越来越快。唯一的应对,是与它共跑甚至赶超。方法就是学习,要持续不断的学习,让自己拥有更多更深的专业知识和技能,更强的在企业内开发产品和业务的能力。 交流能力:这是一个人与人之间愈发紧密联结的世界,通过各种数字通讯服务与工具,社交网络,人们能够以文字、图片乃至视频,与更多的人保持交流。 从长远角度看,一个人越擅长结识他人,表达自己,形成相互学习并共同完成某些理想的关系和友谊,对这个人就越好。 2、20多岁,去创业公司还是大公司? 陆奇认为,要看个人追求。 如果你的长远理想是自己开公司,那加入创业公司,甚至直接创业,都是最好的选择。加入创业公司或自己创业会愈发成为年轻人学习并拥有真正创新能力的重要途径。因为在创业企业,每天做的事就是为了生存而战斗,一个人的真实作战能力测试来的很快。创新或死亡,是创业企业每天面临的现实。就学习和人才发展角度,一个人能获得这样的学习机会是非常宝贵的。 如果你的长远理想是成为一家公司某个职能的高管,那就进入一家可以提供你学习和成长机会的大企业。 但陆奇认为,以上仅限于少部分清楚的知道自己长远目标的人,他对女儿说:大部分人在25岁之前,对于人生想要做什么,其实只有模糊的感觉。 所以,20多岁,要学会快速失败,尝试,反馈,改变。把自己的时间投资在更大的学习发展空间机会中,可能为未来创造更高的收入。 3、陆奇的20多岁,在做什么? 读书,以及继续读书。 1978年,全国恢复高考,17岁的陆奇埋头狠狠啃了两年书,考入复旦大学计算机专业。读书期间,陆奇特别用功。他的同学们回忆说: “他瘦瘦小小的身影,每天穿行在教室和图书馆之间,夜里图书馆熄灯,他才穿过农田,回到另一区的寝室。” “他背着大书包在校园里穿梭,在林荫道上反反复复背着单词。他是全年级最瘦小的男生,但扛着全年级最大的书包。” 凭着超凡的努力,陆奇顺利考取复旦的研究生。凭着读研期间优异的成绩,他毕业后留校任教。 勤奋学习和扎实的专业知识带给陆奇的远不止一份稳定而又体面的工作,还包括更多的人生选项。 1989 年,卡耐基梅隆大学教授克拉克到复旦交流讲学,讲学时间选在了周末。不巧地是,当天的天气很不给力,暴雨倾盆,周末加坏天气使得来听讲座的学生寥寥无几。校方为了不让教授尴尬,就安排周末留校的师生去听讲座,因为暴雨取消回家计划的陆奇就是其中之一。 克拉克教授讲完后,让在场师生提问。陆奇抓住这个机会,接连向教授提了几个专业问题,克拉克听完,立刻就对这个提问的复旦老师的学术水平刮目相看。讲座过后,他专门翻阅了陆奇写的论文,看过之后,克拉克就邀请陆奇去卡耐基梅隆大学读博。 那年陆奇28岁,有点犹豫:“在大学当老师已经是很不错的职业了”。 克拉克只回了一句:“你是鹰,不应该局限在笼子里。” 陆奇去了美国。 走上卡耐基梅隆大学这个更大的平台,才有了陆奇对计算机科学更深入的研究与理解、才有了陆奇与李开复的相识以及后面的开挂人生。 4、59岁的陆奇还在试图重构知识体系,20多岁怎能不学? 2016年陆奇在硅谷接受采访时说:“最近几年我重新觉悟——你必须要重新学习,以前学的东西不光过时了,而且现在很多理论包括物理学都已经有了全新的认识,所有你要从根本上重新构建知识、认识世界。” 陆奇从微软离职原因之一是练习倒骑自行车摔伤了腿,那辆车是他与同事改造的、反向骑行的自行车,骑车时人和身体反应全部是倒置,所以要忘记过去学习到的全部经验。 就连之前选择加入YC,其中一个原因也是学习:我还希望我的工作不能只利用过往的经验,而是要每天学新东西。不学新东西的话,就没什么乐趣。 这几年陆奇观察到人才市场里一个非常重要的宏观趋势,整体的需求从原来的技能驱动型人才,越来越往知识和创新驱动型人才转移。所以他认为,一个人的能否快速学习,并将学到的知识应用于创造新的价值也变得愈发重要。 现在他仍旧保持着每天学习英语、阅读计算机领域最前沿论文的习惯。他说:“我把自己想象成一个软件,今天的版本一定要比昨天的版本好,明天的版本一定要比今天的版本好。” 年近60岁,陆奇还试图重构知识体系,20多岁的我们又怎么能不学习? 30岁:做让自己走得远的事情:搭建系统 陆奇说:30岁你要让自己可以走得远。建立一个核心支撑体系,能让你走得很远。这个体系包括你的身体、你厚实的家庭基础和几个志同道合、可以信任的朋友。 陆奇是一个寻求最优解的人,方式就是建立系统。 任何一个问题他都有系统的固定方式去解决——就是把它变成一个非常理性化、可以拆解成任务的方程。 比如,陆奇的人生里几乎看不冒险,因为他只把机会成本的8%用来冒险,就算这8%,他还是会建立一个决策系统,理性决定——快速反馈——如果方向不对,立即掉头甚至放弃。 比如,看待自己在微软的贡献,他不计较几个产品的得失,还是要回到系统上:比起一个产品的成败,帮助企业建造长期的创新的生命力才是最重要的。 我们再看一下他上面着重提到的三个系统。 1、身体系统 陆奇极度自律,坚持了十几年早上4点起床。 过去十几年他是这样的:“4点起来先弄Email,弄完了以后跑步,跑30分钟,洗个澡,去办公室。跑步第一对呼吸系统是很好的锻炼,第二可以出一身汗,第三是我可以边跑边听书不浪费时间,有时候我会把PPT放在跑步机上翻着看。” 从微软离开后有所变化,他现在对自己的生活效率很不满意,因为骑反向自行车把腿摔伤后,跑步根本不行了,目前他正在找一个让自己感觉每天都很顺畅的方式。 不过他依然精力旺盛,百度期间,同事说他每日长时间工作,无论周末、假期,无论在北京还是在国外,只要开会,他总是准时出现在视频会议的另外一端。他有依然有自己严格的作息制度,有自己严格的生活习惯,也有非常严格的饮食习惯。 陆奇认为,每个人有不同的身体状况,他自己的做法不建议其他人学习。但是他有一套核心的方法论可以介绍给大家: 找到问题的核心,即:无论创业还是在大企业里从业,在工作中如何进行时间管理来让产出最大化,同时也能获得自我满足? 再找到核心的解决办法,即: 设计一个“马拉松快步跑”的时间管理方法和心态。 第一:要意识到这是一场马拉松,不是一场短跑。 第二:这场马拉松的速度需要很快,因为现实世界中,任何高价值的东西——创业公司、大企业的好岗位等——都会有非常激烈的竞争,你需要保持速度并持续领先。 设计这样一个工作节奏和时间管理方式,很类似在高速公路开车。 陆奇说:“你需要保持一个均匀的高速,然后时不时的加速一下,再回到之前均匀的高速。你要避免过度频繁的加速、减速。就像一辆车,如果一直都是高速前进,只是偶尔减速一下,这对与一辆车的损耗是很低的。但如果一辆车过度频繁的突然加速、减速,会对这辆车带来巨大损耗,不用多久车就可能垮掉。 因此,你需要设计属于你自己的一个工作和生活节奏,这种节奏是你可以保持住的高速,而这个高速可以给你带来最大的效率。同时,你也需要设计这个日程节奏,让它可以应对突发变化,可以时不时的冲刺一下,比如偶尔过度加班让工作在截止日期前完成,然后迅速回归之前的速度。必须避免经常性的透支,经常性的拼命追赶截止日期,经常性的处于疲累状态。身体和精神上偶尔透支可以补回,不可长期透支。” 跑一个高效率、可持续、并且可以应对临时突发状况的马拉松才是关键。 2、家庭系统 陆奇的家庭很少出现在媒体中,公开信息绝少,但陆奇在讲搭建系统时特意提到“厚实的家庭基础”,说明他的个人成功受“家庭系统”支持颇多。 2018年5月8日,百度宣布陆奇因“个人和家庭原因”离开百度。 这其实是拿陆奇最不可能的原因当了最常见的公关话术,陆奇的家庭一直是全力支持陆奇做他想做的事业,百度的一位高层说,陆奇就职微软期间,其长期在美国西雅图工作,家人为了陆奇就定居硅谷,“他早就把家庭的事情处理好了”。 陆奇回国加入百度后,为了照顾陆奇的饮食起居,陆奇家人曾一度迁居北京,百度还为陆奇的夫人配备了出入百度大厦的证件。 2018年8月16日,YC媒体沟通会上,主持人官宣陆奇加盟YC担任YC中国首任CEO。陆奇和太太、女儿都在现场。 陆奇的太太说:“我们有一半的时间在美国,他去哪里,我们就跟到哪里。” 陆奇现场致辞的最后,也特别感谢了他的太太和家人。而且说希望在美国、中国多花时间,为了家庭。 写这部分内容时,我突然想起小晚的《晚点》团队采访陆奇时曾问过这么一个问题:你是否经常会太过相信自己的力量? 陆奇说:会。我太太一直觉得我太过于自信了。她老觉得我自以为是。 这就是最好的支持吧,即便有时认为你的理想“不现实”,但只要你想做,我愿意陪你。这就是陆奇所说的“厚实的家庭基础”对一个人事业的重要性吧,如果你的梦想和成长能得到最亲近的人的支持,应该是最幸福的事了。 3、人脉系统 陆奇的人脉有多强? 陆奇的人脉有多好,我相信在开头介绍中,那些顶级大佬的评价就是最好的答案,接触过的人都愿意帮他,合作过的人都愿意捧他。 这里再讲几个点。 1996年,陆奇博士毕业,摆在他面前的有三个选项:回国;华尔街;硅谷。 他不知道该如何选择,就去请教李开复自己该去哪里、进哪个公司工作,李开复给出了自己的建议:“去硅谷吧,找一家技术类的公司。” 于是陆奇就去了IBM的Almaden研究实验室,在那里工作了两年。 之后,陆奇跳槽到雅虎,李开复又一次提醒他:“雅虎的股价不会一直在这个水平上,它要么会上涨5倍,要么下跌5倍。” 陆奇职业生涯的两次关键时刻,李开复都给出了自己的建议和判断,一次让他看清了自己的优势和发展方向,一次让他看清了一家公司的发展空间。 2008年,微软收购雅虎未果,当时已在微软任职的师兄沈向阳向鲍尔默引荐了陆奇,于是有了之后鲍尔默与陆奇长达6个小时的会谈。就这样,微软成功挖到了雅虎搜索引擎业务第一人——陆奇,陆奇也开启了他在微软的执行副总裁生涯。 沈向阳的引荐,让陆奇成为“硅谷最有权势的华人”。 再到2019年,YC撤出中国,陆奇独立运营新基金奇绩创坛,很快首期美元基金募集完成约1亿美金,出资人都是谁呢? 陆奇的朋友们,阵容相当豪华:比尔盖茨、孙正义、红杉中国、高瓴资本、北极光创投等。 陆奇如何看待人脉? 中国人常说,做成一件事就是:天时地利人和。 人和就是人脉。陆奇喜欢那句“机会总是留给有准备的人”,但他喜欢那句“机会是留给广结良友的人。” 陆奇说:我个人的经验里,除了准备充分,你所拥有的人脉的宽度和广度也很重要,要通过交流结识更多人,最好是拥有不同职业背景的人,并跟他们保持关系)。美国有一句谚语,你获得一份工作不是因为你知道什么,而是因为你认识谁。这句话在某种角度上其实很正确,至少在我个人的经验里,这句话很正确。 陆奇为什么有如此好的人脉资源? 这句按照查理芒格的说法,当然是陆奇配得上。 他做了什么让自己配得上? 我们来分析几点。 陆奇的人品。 小晚的团队采访他时,多次试图让他聊百度,我们看陆奇的表现。 比如问“回头来看,加入百度是一个错误的选择吗?”,陆奇回答“不好意思,我真的不想讲百度”。 记者追问“你可以谈微软,但是避免谈百度,为什么?”,陆奇回答“是职业道德,我不想为它带来任何Distraction(干扰)”。 我看完这句,佩服。 谈及老东家YC,陆奇说:我个人很感激YC,我一定要强调这一点,他们送我们到了他们能送到的最远的地方。 记者问:看着雅虎一步步走向衰落,为什么没有更早的离开? 陆奇答:因为我答应杨致远做10年。当时雅虎进入了一个危机,杨致远找我说,中国有一个传统,朋友有难的时候不应该离开。我说那我就不离开了。 膜拜。 陆奇的情商。 小晚团队问:你心中优秀的CEO是什么样子?你的榜样是谁? 陆奇答:最强的人愿意为你而来,这是我觉得最好的CEO。在中国我觉得马云做得不错。 后面的一个问题中,他特意提及了张小龙,“张小龙是我非常敬仰的人。中国的移动生态走得很远,很大因素是微信,微信可能是当代做得最出色的一个产品”。 赞美阿里的组织,赞美腾讯的产品。 陆奇的品质。 一个浑身闪耀着发光品质的人怎么会没朋友? 陆奇身上的优秀品质太多,略举一二。 比如准时。自媒体人辉哥曾和陆奇在百度共事,他说某次出差,他们先到楼下大堂等,距离预定出发的时间还有1分钟时,他有一些着急,问要不要给陆奇打个电话。熟悉他的人说“他会准时的”,话音刚落,电梯门打开,陆奇出现,一分不差他极度守时。 比如来信必回。无论是邮件还是微信,你只要发给他,他一定会回复,时间不确定,有时候是凌晨1-2点,有时是早晨5-6点左右。 比如永远正向。辉哥说,工作中永远难免会遇到困难,但陆奇任何时候都保持正向的态度。无论是在公司开会,还是做大会的 MC,或是回邮件,永远是用简短有力,但充满了力量和鼓舞人上进的精神。大家最累最困难的时候,只要陆奇在那里振臂一挥,大家顿时又像打了鸡血。 40岁:找一个可以让你淋漓尽致发挥的舞台 陆奇:“40岁后,理想情况是找到一个可以让你淋漓尽致去发挥的舞台,一个人的才华和一个公司的才华只有在真正被释放的情况下才能实现它的价值。如果这个舞台是你自己的最好。” 陆奇说过一句广为流传的话: “人生不是线性的,不要以为一班车就能把你从现在的位置带到你自己所期望的位置。” 什么阶段做什么,40岁以后,就要找到一个可以让你淋漓尽致发挥的舞台。 为什么不是20岁? 前文也说了,陆奇认为那个阶段,绝大部分人对于人生想要做什么,其实只有模糊的感觉。 而且陆奇认为,20多岁你要考虑一些现实因素,比如财务方面,工作收入需要满足自己生活的需求以及其他潜在财务责任,比如资助父母兄妹等,理想情况下,还可以有一些存款。 20多岁多学多做多试,30多岁搭建系统,正是为了40岁以后真正有属于自己的舞台。 微软属于他的舞台,但不够,所以他离开,回到中国,找更合适的舞台。 比尔·盖茨一直挽留他,说:百度能给你什么,我都给你。 陆奇说:你不能给我中国。 中国是他现在更好的舞台,一个更大意义上的舞台,他要借助一家合适的平台在这个舞台上跳舞。很可惜,百度没能最终成为那个合适的舞台。后来他加入YC,很可惜YC也没最终成为那个合适的舞台。 后来陆奇认为:属于自己的舞台,如果真的“属于自己”,那是最好的。 “如果你想真正大规模改变世界,那你必须是这个企业的创始人,否则你永远受限于你的雇主。当这个平台是你亲手建造,那你可以发挥的能量和范围是最充分的。” 陆奇的的签名是:“Do more, know more, be more”。 这大概就是追求“be more”吧,40岁以后,自我更重要了。 这个问题,《晚点》和陆奇的对话很精彩: 《晚点》:甘地说,be the change you want to see in the world。成为更好的自我和建立一个更好的世界,后者难道不会推动人走得更远吗? 陆奇:自我才会让人更永久。赚很多钱、建设一个成功公司,甚至建造一个国家、世界,都是外在目标。如果一个目标是外在的,你永远会在达到目标之后变得一片空虚。 《晚点》:有一些商人,他们的目标就是赢,他们乐此不疲,似乎并不空虚。 陆奇:你的追求是建立在别人输的基础之上,为什么世界上一定要有人输你才觉得你的生命是有价值的?我认为人的目标是你自己而不是任何外在的因素。 如今他终于有了属于自己的舞台,奇绩创坛,也真的“属于自己”。 翻看书签的时候偶然发现 RASP 两个收藏 安全无小事,从点滴做起。要有安全意识。 RASP( Runtime Application Self-Protection )是一种在运行时检测攻击并且进行自我保护的一种技术。 化繁为简,抓住事情的本质,这就是优势。 攻击动作 当发生 SQL 注入攻击时,WAF 和 IDS 只能看到 HTTP 请求。 曾经整理过一个帖子,不过是在公司内网。 学习的过程需要不断发现好的资源,深入钻研某个领域。 最近做项目有一个地址库文件需要放在后端 接下来遇到了一件奇怪的事情,部分汉字乱码了, 最后求助于百度搜索,得到了一些有效的信息。 据说现在很多人没法纯手写通过流读取文件了…(说的就是我!) CSDN 之前京东组里有同事使用二进制优化支付密码打标性能(大促 QPS 数百万),节省内存资源。 目前公司遇到个套餐打标,也通过二进制实现简单高效得解决掉了。 知识点:二进制、与运算 打标,无非就是识别某个东西是不是包含某些属性。 目前相对较好的方案是通过二进制位来做标记,再结合与运算,快速找出数据。 如上表所示,相应套餐的购买资格标记。 对相关标记进行入库处理:A=7,B=6,C=4; 正常思维,需要存三个字段,没有扩展性,性能还差。 系统流量小的时候 说到底还是要知其然,更要知其所以然。 由于近期换工作,停下了技术书籍,去了解行业 《移动健康和智慧医疗》0711~0717 医疗信息化建设提升医疗系统效率 减少医疗信息不对称 互联网医疗典型方向: 《移动健康和智慧医疗》0711~0717 利用现代技术加强相关人员交流和互动 慢性病管理 骨科手术后居家康复指导,尽快出院,获取足够信息与支持。 服务设计、实现、患者使用过程,均反应出一系列信息技术和预防、临床医学(流程、知识)之间的相互作用和支持,提现了互联网+多学科交叉,跨行业深度融合的思想。 互联网医疗典型方向:健康促进、慢性病管理、诊断治疗、术后康复。 健康医疗APP重要因素:专业性、相关性、有效性、趣味性、社交化。 医疗云平台:数据汇集分发、电子健康档案、业务管理、安全体系、运维系统。 对多元异构多模态大数据进行处理、分析、挖掘,从中获取新知识和洞察,优化经营、管理,提升患者体验,提取最佳临床路径,辅助临床决策,实行计算机自动筛查和诊断,为其它利益相关方提供未知的信息资源等,这是互联网医疗追求的理想和目标。 研究发现我国近2/3接受糖尿病治疗的患者未能适当控制血糖,因此会出现各种并发症,如:心脏病、中风、失明、肾功能衰竭等。 2014年,慢性疾病导致的死亡占中国总死亡人数的 85%,导致的疾病负担占总疾病负担的 70%。 虽然中国经济的增长速度赢得了世界的瞩目,但是如何提高慢性病是综合防治能力,减少慢性病的发病率、致残率和死亡率,降低费用支出,仍是健康医疗服务需要应对的巨大挑战。 著名卫生经济学家普林斯顿大学教授 WR 提出,各国医疗体系的本质在于国家价值观和国家性格决定其系统如何运行。 低功耗可穿戴设备使得随时随地采集健康医疗数据成为可能。这些大量的、连续的、包含上下文情境的健康医疗数据,为健康医疗提供决策依据、促进健康生活方式的养成、改善疾病监护、诊治状况。 移动互联网具有用户身份、位置可识别,随时交互、多元数据可采集、用户可高度参与等一系列技术特征,使得移动互联网与其他行业融合时带来新的解决方案、服务模式和发展机遇。 医护路径全流程服务:促进健康、预防/慢性病管理、院前急救、诊断治疗、院外康复/干预。 院前急救:伤者历史数据、辅助诊断、车载数据同步医院,医院提前准备。 远程问诊成本低,灵活性强,出现一些早期症状可以及时获得指导。 量化自我:2007年凯文凯利提出,通过设备和技术持续跟踪、采集自己的生理心理特征,形成生活日志,探索身体健康的奥秘。 可穿戴设备的数据如果作为对患者实施诊断、治疗等环节的重要依据,则属于医疗器械,需要监管。 智能服装才是可穿戴设备的终极形式。 单点登录的目的是为了让多个相关联的应用使用相同的登录过程,代码复用,提升体验。 CAS 是开源的企业级单点登录解决方案。 根据密钥的职责和重要性,一般分为:主密钥、二级密钥、初级密钥。初级密钥是直接使用的密钥。高级密钥对低一级密钥做加密,保护低一级的密钥。 不同级别的密钥应该分开存放,最好是异地、异设备。 密钥不以明文形式存储在数据库或传输媒介中:避免密钥被截获后直接用来解密数据,增强安全性。 HIS:医院信息系统 流式计算的数据来自一个最近的时间窗口,数据延迟短但精度可能较低。 一个完全测序的人类基因组包含 100~1000G的数据。 精准医疗:根据每个人的基因、生活环境、生活方式等的不同,提供相适应的个性化疾病治疗和预防 健康医疗大数据的收集、分析、整理和挖掘对于患者健康医护路径的不同环节都有非常重要的价值。 任何疾病最有效的治疗方式是预防保健。 每年心脑血管医疗费用占比搞,且再次入院率高,如何有效管理心血管病、节省医疗开支、降低出院患者再次入院率已经成为社会各界关注的重点。 美国的分级诊疗制度、医生多点职业、医疗信息化、商业保险、医院集团管理等一系列成熟体系,为美国移动健康医疗的发展提供了肥沃土壤。 远程医疗服务提供简单、方便、低成本的方式为患者远程诊治感冒、流感、喉咙痛或其它简单非急症性疾病。 2014 年 5 月,阿里旗下的支付宝推出“未来医院计划”,支付宝对医疗机构开放自己的平台能力,包括:账户体系、移动平台、支付及金融解决方案、云计算能力、大数据平台等,旨在优化患者在医院的就医流程,提高就医体验,提升医院的管理效率。 2015年阿里健康业务 北京大学人民医院是中国最具实力的三级甲等研究型医院之一,积极推进医疗信息化建设,2014 年通过了国际上衡量医院信息化水准的 HIMSS EMRAM 最高等级(7级)的评审,成为亚洲第二,中国第一家。 简单介绍,《凤凰架构》作者,周志明。 阅读时间:0531~0612 用输出倒逼输入 目前的软件没有烟囱式的,都是金字塔类型,所以底层基础要牢固! 四层负载均衡的优势是性能高 七层负载均衡的优势是功能强 将简单的校验交给 bean validation, 能够使用确定的操作,促使状态间产生确定的转移结果的计算模型,在计算机科学中被称为状态机。 状态机特性:任何初始状态一样的状态机,如果执行的命令序列一样,则最终达到的状态也一样。(可用于分布式协商…) 广播指令、状态机复制。 让各个系统节点不受局部网络分区、机器崩溃、执行性能、其它因素影响,都能最终表现出整体一致的过程,被称为各个节点的协商共识。 一致性是指数据不同副本之间的差异, 足可见技术圈里即使再有本事,也需要好好包装一下。paxos 论文发表三次后,被谷歌实现之后,凭着谷歌大拿的高度评价,获得了极大的关注。 操作转移模型 达成共识的三步 网关 = 路由器(基础职能) + 过滤器(可选职能) 打饭解释各种 I/O 模型 BFF网关:backends for frontends,针对网关这种边缘节点,对同样的后端集群,裁剪、适配、聚合出不一样的前端服务,有助于后端的稳定,也有助于前端的赋能。 由于服务随时都有可能崩溃,因此快速的失败检测和自动恢复就显得至关重要。 lstio(mesh) 在 1.5 之前是使用微服务架构开发 微服务的目的是有效拆分应用,实现敏捷开发和部署。 凡事总该现有目的,有预期收益再谈行动才显得合理。 《没有银弹》:硬件的成本能够持续稳定地下降,而软件开发的成本则不可能。 系统的架构趋同于系统设计团队的沟通解构。 大厂研发收到追捧,出除了企业本身的光环外(来自于哪里?),有大型系统浸染的经验,更有可能属于技术专家,也是其中的原因。 微服务对普通业务研发友好,但是对架构要求极高。 微服务的前提 需要想清楚做一件事的目的是什么?考虑 ROI 长期来看,多数服务端结局都是报废而非演进–Martin Fowler。 微服务拆分粒度 治理,系统复杂性下的产物。 软件研发的认知负荷,本质上是来自技术的认知复杂度。 分布式系统早已放弃 Unix 所追求的简单性设计哲学。 治理架构腐化唯一有效的办法就是演进式设计。 Architect 架构师一词从建筑行业借鉴而来,让人容易误解架构师类似于给建筑设计骨架、绘制图纸的建筑架构师。演进式设计更像是“换房子”而不是“造房子”。 先进的生产力都伴随着更高的复杂性,需要有与生产力符合的生产关系来匹配,敏锐地捕捉到生产力的变化,随时调整生产关系,这才是架构师治理复杂性的终极方法。 1992 Java write once,run anywhere。 目前 graal vm 将思考具象化。 纸书作者应该还在初版中,目前看的是 PDF. 作为一个软件开发工程师,日常很多机会和英文打交道。 今天心血来潮,再次看了一下之前收藏的相关文章,感觉收获不少。 复旦大学中文系教授严峰 严老师的英语学习硬核秘诀 学外语有什么用 程序员圈”名”人王垠 : 解谜英语语法 英语学习的一些经验 GitHub 上的成功人士: 还是得坚持看文档,背单词。 在压测过程中发现有部分 redis cluster 节点内存占用比其它节点高(来自监控) 内存倾斜的隐患 redis cluster slot 分配不均匀 合理算法:单节点内存 = (集群总内容 / slot 数量) * 当前节点 slot 数量 key 根据 crc16 计算之后比较均匀,排除 key 分布不均 查找 slot 分布 通过 awk 计算每个节点管理的槽 ( slot ) 数量 由于本案例当中,大部分节点都是包含 326 个 slot,问题节点明显偏多 360 awk NR 代表行号 根据上述假设,经过验证,发现确实是由于 slot 分配不均匀导致 人工手动调整 slot 较多节点的内存,使之达到与其它节点内存占用水平。 最近在看代码,发现一个 Date 格式化为 String 的方法。 看到这个方法想到 带着以上三个疑问,就想着做个对比测试。 优点:不用自己写相关统计代码,而且统计方式有多种 性能从低到高 说明: 插件中心搜索:JMH 安装了 JMH 插件之后,直接对着类名右键,选择运行即可。 ETA 00:10:50 代表整个测试需要近11分钟 JDK8 因未指定 MetaSpace 大小,程序启动过程中元空间不够用,触发 full gc。 详细如下: 应用启动时出现 full gc; gc日志重点:GC (Metadata GC Threshold) [PSYoungGen: 354024K->15340K(1376256K) 启动过程中,出现了 JVM Full GC 告警。 看原因是元空间内存不够大导致的 问题是解决了,但是原因是什么呢? 所谓知其然,更要知其所以然。 网络 中断(Interrupt)是指 处理器接收到来自硬件或软件的信号,提示发生了某个事件,应该被注意,这种情况就称为中断。 软中断 (form 《UNIX 操作系统设计》) 内核在收到软中断信号的进程上下文中处理软中断信号,因此进程必须运行以便处理信号。 Java 中不推荐使用抢断式中断,倡导: 一个线程的生命不应该由其他线程终止,应当由它自己选择是否停止。 在近两年高并发系统 DevOps 的过程中, 《计算机网络:自顶向下方法》 收获甚大 所以想继续深入学习 软件工程师分为两种: 这两种人都自称软件工程师,都能在职业生涯早期挣到差不多的工资。 内容值得一看,真心建议多花功夫学好底层知识。 来自亚马逊 CTO 的博文也值得一看,操作系统经典书籍 响应国家就地过年的号召,今年第一次在外过年。 找到自己的兴趣,追求精进,坚持做对的事情。 这本书是 leader 推荐给大家的 春节之前断断续续看了一部分,后面主要是春节在看。 有自己清晰的不为清单,发现错了立马纠正,因为这时候止损成本最低。 段永平的投资问答录其实很多时候也适合于人生建议,都是相通的。 书本当中也能接触到不少成功人士,正所谓近朱者赤, 实践出真知,作者成就非凡 eg: 看完对马斯克以及他的企业和野心有更多的了解 触动最大的就是@纯银V 一位产品经理的微博 感悟就是:积极、主动、为自己工作,找到喜欢的事情,持续精进。 和家里亲戚去郊区玩了几天,还是比较放松。 安排好自己的时间,加强执行力! 本文灵感来自《人人都是产品经理 2.0》 作为一个研发,工作过程中如果能及时发现如下场景, 技术问”为什么要做”时: 技术问细节(业务细节,非技术细节)时: 1、这不是很简单嘛,就改个 XXX,几行代码就搞定 1、任何时候只知道公事公办,技术承诺了却做不到,自己就没有责任了。 1、经常在某个迭代周期内做”非受迫的需求变更”,这招杀伤力很大,技术同学一般受不了。 1、可以想各种办法隔绝与研发的联系。 1、帮技术确定各种技术方案,这个应该这样实现… 1、发布之后,犹如石沉大海,不告诉大家任何结果,甚至庆功宴都不叫 Ta 们,紧接着继续安排他们干活。 1、让研发一阵忙一阵闲,发布之后再开始研究接下来做什么。 1、你定吧,你说往哪儿走我们照办 1、藏着噎着一些坏消息,eg:老板正考虑干掉这个项目等,大家只能通过小道消息得知 1、只关注结果,不关注人的成长,永远把合作伙伴当”资源” 由于某种原因,需要手工处理错误日志提取某些信息。 压缩包文件名不一样,但是压缩包中的文件有一样的名字。 尝试使用如下方式,提示有重复,需要挨个选择如何处理,极度不便。 提示有文件重复,需要处理。 尝试使用 -n 参数,不覆盖 -n 表示不覆盖,有重名的直接跳过,结果就是 100 个文件只解压的 10 个。 怎么拿到压缩包内的文件名? 1.3 的问题解决了就可以开始写脚本 文件名 uf.sh 注意,目前在目标目录下才能正确运行 然后解决问题,解压所有 100 个压缩包,并且得到 100 个文件(文件名为 1~100)。 不得不说解决问题是最快的学习方式 进制除了 Byte 与 bit 之间是 8,其它的都是 1024,但是目前很多时候习惯用 1000,比如 1T ≈ 1000G; 运营商(ISP)带宽宣传常见的有:50M、100M、500M、1000M… 各种下载软件,比如迅雷会现在下载速度:12M/s 所以由带宽传输速率转换为下载速度一般需要除以 8 关于字节的占用,最明显的就是文本编辑器,写入文本后保存,在文件管理器中能看到具体占用了多少存储空间。 最近做压力测试,不同的系统的机器监控数据差异明显 那么是什么导致 A B 系统出现这种情况? Linux load averages track not just runnable tasks, but also tasks in the uninterruptible sleep state. On Linux, load averages are (or try to be) “system load averages”, for the system as a whole, measuring the number of threads that are working and waiting to work (CPU, disk, uninterruptible locks). Put differently, it measures the number of threads that aren’t completely idle. Advantage: includes demand for different resources. 目前测试机器为 4C8G 最大最小设置成一致的值,是为了不让堆大小进行收缩(缩的过程会 GC) 目前应用堆响应时间比较敏感,追求低延迟。 JVM 新生代大小与老年代大小默认为 1:2, 先占个坑,后续继续填内容。1.1 背景
1.2 效果
1
2
3
4
5
6
7[Byte Buddy] BEFORE_INSTALL net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer@87f383f on sun.instrument.InstrumentationImpl@4eb7f003
[Byte Buddy] INSTALL net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer@87f383f on sun.instrument.InstrumentationImpl@4eb7f003
[Byte Buddy] TRANSFORM com.hisen.agent.util.Hisen [sun.misc.Launcher$AppClassLoader@18b4aac2, null, Thread[main,5,main], loaded=false]
name before:hisen
hello: hisen1677417020466
public static void com.hisen.agent.util.Hisen.hello(java.lang.String): took 0 millisecond
HisenAdvice exit. time use:02. 代码逻辑
2.1 启动类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
* @author hisenyuan
* @date 2023/2/6 21:31
*/
public class Start {
public static void main(String[] args) {
startTraceAgent();
Hisen.hello("hisen");
}
private static void startTraceAgent() {
Instrumentation install = ByteBuddyAgent.install();
HisenInterceptor.init(install);
new HisenInstrumentation().init(install);
}
}2.2 拦截方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28/**
* @author hisenyuan
* @date 2023/2/8 21:17
*/
public class HisenInterceptor {
public static void init(Instrumentation instrumentation) {
new AgentBuilder.Default()
.type(ElementMatchers.nameEndsWith("Hisen"))
.transform((builder, type, classLoader, module, protectionDomain) -> builder.method(ElementMatchers.any()).intercept(MethodDelegation.to(TimeInterceptor.class)))
.installOn(instrumentation);
}
public static class TimeInterceptor {
public static Object intercept(@Origin Method method, @SuperCall Callable<?> callable) throws Exception {
long start = System.currentTimeMillis();
try {
return callable.call();
} catch (Exception e) {
// 进行异常信息上报
System.out.println("方法执行发生异常" + e.getMessage());
throw e;
} finally {
System.out.println(method + ": took " + (System.currentTimeMillis() - start) + " millisecond");
}
}
}
}2.3 代码注入
这种方式也可以增强系统类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49/**
* @author hisenyuan
* @date 2023/2/8 20:16
*/
public class HisenInstrumentation {
public void init(Instrumentation instrumentation) {
new AgentBuilder.Default()
.disableClassFormatChanges()
.with(RETRANSFORMATION)
// Make sure we see helpful logs
.with(AgentBuilder.RedefinitionStrategy.Listener.StreamWriting.toSystemError())
.with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
.with(AgentBuilder.InstallationListener.StreamWriting.toSystemError())
.ignore(none())
// Ignore Byte Buddy and JDK classes we are not interested in
.ignore(
nameStartsWith("net.bytebuddy.")
.or(nameStartsWith("jdk.internal.reflect."))
.or(nameStartsWith("java.lang.invoke."))
.or(nameStartsWith("com.sun.proxy."))
)
.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.type(nameEndsWith("Hisen"))
.transform(
(builder, type, classLoader, transformer, module) ->
builder.visit(Advice.to(HisenAdvice.class).on(isMethod().and(named("hello")))))
.installOn(instrumentation);
}
public static class HisenAdvice {
.OnMethodEnter
static long enter(@Advice.Argument(value = 0, typing = DYNAMIC, readOnly = false) String name) {
System.out.println("name before:" + name);
// change name
name += System.currentTimeMillis();
return System.currentTimeMillis();
}
.class) .OnMethodExit(onThrowable = RuntimeException
static void exit(
@Advice.Enter
long startTime) {
System.out.println("HisenAdvice exit. time use:" + (System.currentTimeMillis() - startTime));
}
}
}
因为按照之后没法在系统控制面板里面找到对应的网卡。
就连 GitHub 上驱动的作者都说不支持 RTL-8156B(详见:GitHub-issue) 的外置网卡。
但是我想那么多人都买了这种网卡,并且成功了,于是周末到处搜,最终找到了办法。1. 获取 root 权限
2. 安装驱动
2.1 查询群晖架构
2.2 下载对应驱动
我这里是 DM7 的系统,下载的最新版本
下载到 PC 上即可,不用下载到 NAS2.3 安装
第一次安装会失败(GitHub 上也有说明),需要执行如下命令1
sudo install -m 4755 -o root -D /var/packages/r8152/target/r8152/spk_su /opt/sbin/spk_su
3. 修改配置
都是找到 maxlanport=“2” 修改数字为大于 2 的数字即可。3.1 其一
1
2
3vi /etc.defaults/synoinfo.conf
# 我这里的修改
maxlanport=“4”3.2 其二
1
2
3vi /etc/synoinfo.conf
# 这个文件有点大,好好找找,我的是在 77% 左右
maxlanport="4"4. 信息中心-网络
系统命令行可以识别网卡,并且可以获取 IPv6 地址,但是没有 IPv4 的地址1
2
3
4
5
6
7
8
9
10root@HiSEN-DS:~# ifconfig
eth2 Link encap:Ethernet HWaddr 00:xx:xx:xx:xx:03
inet6 addr: fd7e:a5c4:268d:0:2e0:ffff:fe68:80/64 Scope:Global
inet6 addr: fe80::2e0:ffff:fe68:80/64 Scope:Link
inet6 addr: 2408:8207:ffff:6700:2e0:ffff:fe68:80/64 Scope:Global
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1175 (1.1 KiB) TX bytes:1446 (1.4 KiB)5. 控制面板-网络-网络界面
1
2
3
4
5
6
7
8
9
10
11root@DS:~# ifconfig
eth2 Link encap:Ethernet HWaddr 00:xx:xx:xx:xx:03
inet addr:10.0.0.xxx Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fd7e:a5c4:268d:0:2e0:ffff:fe68:80/64 Scope:Global
inet6 addr: fe80::2e0:ffff:fe68:80/64 Scope:Link
inet6 addr: 2408:8207:ffff:6700:2e0:ffff:fe68:80/64 Scope:Global
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1419 errors:0 dropped:0 overruns:0 frame:0
TX packets:312 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:465252 (454.3 KiB) TX bytes:71449 (69.7 KiB)6. 参考
]]>
这个服务目前是可以免费使用
后续再折腾看看是什么问题。2. 主要操作步骤
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 安装客户端
opkg install cloudflared
# 登录, 返回一个 cloudflare 官方连接,点击会生成密钥
cloudflared tunnel login
# 创建一条隧道,<NAME> 替换成你喜欢的名字
cloudflared tunnel create <NAME>
# 创建一个域名解析
cloudflared tunnel route dns hisen home.hisenyuan.xyz
# 配置 xxx.yml
url: http://192.168.0.10 # 内网的网关,注意做好鉴权
tunnel: d42a48c9-26da-4734-b249-1b9eee69ba8c
credentials-file: /root/.cloudflared/d42a48c9-26da-4734-b249-1b9eee69ba8c.json
# 启动一个内网穿透服务
cloudflared tunnel --config xxx.yml run3. 参考文档
]]>
https://openwrt.org/toh/netgear/r8000
“Second data partition (79 MiB) not available in OpenWrt”
那自然是不够用的了,于是乎就找了些扩大空间的办法,最靠谱的就是利用U盘挂载二、解决
2.1 获取U盘信息
登录 OpenWrt 控制台,查看 USB 在 OpenWrt 中的名称
也就是 /dev/sda1
2
3
4
5
6
7
8
9
10
11root@OpenWrt:~# cat /proc/scsi/usb-storage/0
Host scsi0: usb-storage
Vendor: SanDisk
Product: Extreme
Serial Number: AA010316152154386775
Protocol: Transparent SCSI
Transport: Bulk
Quirks: SANE_SENSE
root@OpenWrt:~# ls /dev/sda*
/dev/sda2.2 安装所需软件
因为需要格式化 U盘 至 ext4 的格式
以及挂载U盘空间至 overlay1
root@OpenWrt:~# opkg update && opkg install block-mount e2fsprogs kmod-fs-ext4 kmod-usb-storage kmod-usb2 kmod-usb3
2.3 格式化U盘
1
2
3
4
5root@OpenWrt:~# mkfs.ext4 /dev/sda
mke2fs 1.46.5 (30-Dec-2021)
/dev/sda contains a ext4 file system
created on Sat Oct 29 08:03:58 2022
Proceed anyway? (y,N) y2.3 挂载 U盘
重启之后,就大功告成
放心地去安装各种插件吧1
2
3
4
5
6
7
8
9
10
11root@OpenWrt:~# mount /dev/sda /mnt
root@OpenWrt:~# mkdir /tmp/root
root@OpenWrt:~# mount -o bind / /tmp/root
root@OpenWrt:~# cp /tmp/root/* /mnt -a
root@OpenWrt:~# umount /tmp/root
root@OpenWrt:~# umount /mnt
root@OpenWrt:~# block detect > /etc/config/fstab
root@OpenWrt:~# uci set fstab.@mount[0].target='/overlay'
root@OpenWrt:~# uci set fstab.@mount[0].enabled='1'
root@OpenWrt:~# uci commit fstab
root@OpenWrt:~# reboot三、参考
]]>
于是折腾了一波 OpenWrt
奈何网件 R8000 配置一般,跑起来体验不好。
后续估计是会上 x86 主机了,虽然可能会性能过剩。二、问题
如果直接在 software 中安装 luci_app_passwall
那么安装后会提示没法实现透明代理,还需要安装一些额外的软件才行三、解决问题
1
opkg install ipset ipt2socks iptables iptables-mod-conntrack-extra iptables-mod-iprange iptables-mod-socket iptables-mod-tproxy kmod-ipt-nat
原因就是新版本的系统中默认不包含上述模块。
问题解决参考自 GitHub issue.四、参考
]]>
往往会有很多查询需求
单体数据库无法满足大量数据存储、各种复杂查询2. 方案
3. 总结
0.1 简介
修生养性,培养一个兴趣爱好,毕竟生命在于折腾
下班回家,看着鱼儿在水中游,喂喂乌龟,也蛮有趣
进一步了解了一下过滤系统,
也有朋友在问养鱼养龟方面的问题,
于是就想着写一篇博客简单的记录一下。
有兴趣可以逛逛:南美水族论坛、乌龟吧(百度贴吧),等水族相关内容。0.2 预防针
0.3 我的水族
1. 动物选择
一定要先了解清楚
自己喜欢什么,适合什么
先了解学习一些经验,不要着急入手
宝莲灯:个人比较喜欢的热带灯科鱼,小型的.2. 植物选择
主要考虑过滤使用
选择根系强大的挺水植物3. 容器选择
鱼缸4. 过滤选择
要想养好水,就需要过滤器材。
开缸尽量不要用自来水,
使用自来水最好是晾晒 2 天,
水质稳定之后,换水的时候也可以直接注入少量自来水。4.1 建议
尽量增大水与滤材的接触面积(过滤效果好)
滤材选择:表面积越大越好,一般比较贵;便宜的可以以量取胜。4.2 背景知识
硝化细菌,把氨气转换为硝酸盐(对动物无害),可以供植物吸收。
『有机物(残渣、粪便)』 一异养细菌一> 『氨(有害)等其它无害物质』 一硝化细菌一> 『硝酸』 一> 『植物吸收』4.2.1 详细解释
硝化细菌(英语:nitrifying bacteria)是一群好氧的化能自养生物之统称,属于生产者,
细菌能通过食用无机氮化合物生长。硝化细菌以二氧化碳为碳源,通过代谢将氨或铵盐氧化成硝酸盐。
指食物链底端可以利用阳光(光合作用)或无机物氧化配以地热能(化能合成)
将空气和周边环境中的二氧化碳、水以及无机盐等制造成有机物来提供代谢底物并存储化学能的生物,
主要包括绿色植物、海藻和少数微生物(浮游植物)。
指不能直接利用无机物或有机物维生,必须摄取现成的养分来维持生存机能的生物。5. 参考
]]>
之前的住户说想升级光纤都没办法
于是乎咨询了下联通可否装光纤
答案是可以,换个套餐就行
其它事情由自己的路由器进行设置并且管理。
这样即使你搬家什么的,路由器搬走,
任何设备都不用动,包括固定内网 IP 等
我主要的点是固定内网 IP,因为我由 NAS1. 操作
1.1 改为桥接
他们远程可以直接修改
如果改为桥接,那么原有网络无法使用1.2 路由器拨号
完事之后就可以上午,但是,这时候 IPv6 是不好使的。1.3 IPv6
选择 PPPoE,使用 IPv4 一样的账号密码拨号
等待配置生效,即可发现 IPv6 正常
IPv6 测试网址:test-ipv6.com2. 参考
这篇文章的一些观点我可能不太认同,
最重要的是,里面提到可以联系客服修改为桥接
这就很方便了,网上很多都是各种破解,挺麻烦。
每次进行登录一系列操作,有点费劲
于是乎想着看看怎么自动化1. 知识
1.1 expcet
主要应用于执行命令和程序时,
系统以交互形式要求输入指定字符串,实现交互通信。1.2 awk
可应用于各种计算和数据处理任务。
入门指南2. 脚本
2.1 自动登录脚本
文件:mysqlLogin.sh1
2
3
4
5
6
7
8
9
10
11
12
13 !/usr//bin/expect -f
set ip [lindex $argv 0]
set port [lindex $argv 1]
set user [lindex $argv 2]
set password [lindex $argv 3]
spawn mysql -h$ip -u$user -P$port -p
set timeout 1000
expect "Enter password:"
send "$password\r"
expect ">"
send "use xxx_database\r"
interact2.2 获取信息并登录
文件:autologin.sh1
2
3
4
5
6
7
8
9 !/usr/bin/bash
ips=`get_single_ip_by_domain hisen.me`
ip=($(echo $ips | awk '{print $2}'))
port=($(echo $ips | awk '{print $3}'))
echo "+---------------------------+"
echo "| Login to MySQL offline |"
echo "+---------------------------+"
调用上面的脚本,包含 4 个参数
expect /root/soft/login/mysqlLogin.sh $ip $port user pwd2.3 快捷命令设置
1
2cat ~/.bashrc
alias ma='sh /root/soft/login/autologin.sh'3. 参考文档
]]>
需要对一些地点的坐标
然后在 WGS-84 坐标系的底图上呈现相关内容
北京韩美林艺术馆,BD09:116.68347847243588,39.88148624000483
北京韩美林艺术馆,WGS84:116.67097966259838,39.874465837541021. 准备
1.1 寻找成品
1.2 使用百度地图 API
1.2.1 注册百度地图开放平台
需要实名认证
网址:lbsyun.baidu.com1.2.2 创建应用
选择的是 SN 签名
获取 AK、SK1.2.3 文档
之前 V2 版本的接口已经停用了
地址:地理编码文档
SN 生成
注意文档的生成方式还是 V2 的例子
地址:SN 生成文档2. 代码
地址文件格式一行一个
转换后会输出文件:地址,精度,纬度1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164/**
* Baidu.com Inc.
* Copyright (c) 2022 All Rights Reserved.
*/
package com.hisen.api.baidu.map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;
import org.springframework.util.DigestUtils;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author hisenyuan
* @date 2022/5/28 10:55
*/
public class SnCal {
private static final String URL = "https://api.map.baidu.com";
private static final String PATH = "/geocoding/v3/?";
/**
* 百度地图 AK
*/
private static final String AK = "your ak";
/**
* 百度地图 SK
*/
private static final String SK = "your sk";
private static final String LINE_BREAK = "\n";
private static final String FORMAT = "yyyyMMdd_HH_mm_ss_SSS";
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
// 需要转换的文件,一行一个
String file = "/Users/hisenyuan/Downloads/address.txt";
// 结果输出文件夹
String resDir = "/Users/hisenyuan/Downloads/";
File resFile = getResFile(resDir);
// 读取文件
List<String> addressList = getAddressList(file);
for (int i = 0; i < addressList.size(); i++) {
convertLocation(resFile, addressList, i);
System.out.println("current line:" + (i + 1));
}
long use = System.currentTimeMillis() - start;
// 打印耗时
System.out.println("time us(ms):" + use);
}
private static void convertLocation(File resFile, List<String> addressList, int index) throws IOException {
String address = addressList.get(index);
String reqUrl = getReqUrl(address);
// 返回结果
String res = sendUrlGet(reqUrl);
double[] doubles = getWgs84(res);
String wgsRes = address + "," + doubles[0] + "," + doubles[1];
Files.append(wgsRes + LINE_BREAK, resFile, Charsets.UTF_8);
}
private static List<String> getAddressList(String file) throws IOException {
List<String> addressList = Files.readLines(new File(file), StandardCharsets.UTF_8);
System.out.println("sum line:" + addressList.size());
return addressList;
}
private static File getResFile(String resDir) throws IOException {
DateTime dateTime = new DateTime();
File resFile = new File(resDir + "处理结果_" + dateTime.toString(FORMAT) + ".txt");
if (!resFile.exists()) {
boolean newFile = resFile.createNewFile();
System.out.println("create file, result:" + (newFile ? "success" : "fail"));
}
return resFile;
}
private static double[] getWgs84(String res) {
JSONObject jsonObject = JSON.parseObject(res);
JSONObject result = jsonObject.getJSONObject("result");
JSONObject location = result.getJSONObject("location");
Double lng = location.getDouble("lng");
Double lat = location.getDouble("lat");
return CoordinateTransformUtil.bd09towgs84(lng, lat);
}
private static String getReqUrl(String address) throws UnsupportedEncodingException {
Map<String, String> paramsMap = new LinkedHashMap<>();
paramsMap.put("address", address);
paramsMap.put("output", "json");
paramsMap.put("ak", AK);
// 参数值转为 UTF-8
String paramsStr = toQueryString(paramsMap);
// 参与 MD5 计算的参数
String wholeStr = PATH + paramsStr + SK;
// UTF-8
String tempStr = URLEncoder.encode(wholeStr, "UTF-8");
// Md5 摘要( SN 计算)
String md5 = md5(tempStr);
// 请求地址
return URL + PATH + paramsStr + "&sn=" + md5;
}
/**
* 值 UTF-8
*/
public static String toQueryString(Map<?, ?> data)
throws UnsupportedEncodingException {
StringBuilder queryString = new StringBuilder();
for (Map.Entry<?, ?> pair : data.entrySet()) {
queryString.append(pair.getKey()).append("=");
queryString
.append(URLEncoder.encode((String) pair.getValue(), StandardCharsets.UTF_8.name()))
.append("&");
}
if (queryString.length() > 0) {
queryString.deleteCharAt(queryString.length() - 1);
}
return queryString.toString();
}
/**
* md5 摘要
*/
public static String md5(String str) {
return DigestUtils.md5DigestAsHex(str.getBytes(StandardCharsets.UTF_8));
}
/**
* 发起 http 请求
*
* @param url 请求地址
* @return 返回数据
*/
public static String sendUrlGet(String url) {
String responseContent = null;
try {
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = client.execute(httpGet);
HttpEntity resEntity = response.getEntity();
responseContent = EntityUtils.toString(resEntity, StandardCharsets.UTF_8);
// close resources
response.close();
client.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return responseContent;
}
}3. 参考
虽然数据结构、API 比较简单
但是想使用好,还是有一定难度
建议了解下《Redis 开发与运维》
以达到知其然且知其所以然的境界一、使用场景
流量比较大,响应时间要求高
Redis 作为一款流行的高性能数据库
某大型电商订单系统读写比大概在 10:1
并且订单读取 90% 的流量都是创建订单当天查询
比如优惠券发放,流量高,这种情况下当做 DB 用也挺好。二、问题与建议
2.1 常见问题
2.2 建议
三、阅读摘抄
redis 是面向快速执行场景的数据库。
随说:utf-8 汉字 3 ,ascii unicode 2
geo 功能是 redis 借鉴了 ardb 功能实现,ardb 的作者来自中国。
保证客户端与服务端的正常通信,是各种编程语言开发客户端的基础。
page 121 有使用 protostuff (protobuf的Java客户端)进行操作的例子。
随说:这块 21 年出实际场景测试过,时间、空间复杂度优化幅度都蛮大
由于子进程非常消耗 CPU,会和父进程产生单核资源竞争。
但 Linux 有写时复制机制(copy-on-write),
父子进程会共享相同的物理内存页,
当父进程处理写请求时会把要修改的页创建副本,
而子进程在 fork 操作过程中共享整个父进程内存快照。
TCP_NODELAY,默认为 no,即开启 TCP_NODELAY 功能,
这时主节点会合并较小的 TCP 数据包节省带宽但是增大了主从之间的延迟,
适用于跨机房部署。如果为 yes,那么会立即发送,适合同机房网络。
多个从节点会导致主节点写命令的多次发送从而过度消耗网络带宽,
同时也加重了主节点的负载影响服务稳定性。
需要组件支持:
rdb 文件不保存到硬盘而直接通过网络发送给从节点。
一般把 redis 主从部署在同机房 / 同城机房,
避免网络延迟和网络分区造成的心跳中断等情况。
可以编写外部监控程序监听主从节点的复制偏移量,
当延迟较大时出发报警或者通知客户端避免读取延迟过高的从节点。
可以考虑使用 redis cluster 等分布式解决方案,
这样不止扩展了读性能还可以扩展写性能和可支撑数据规模,
并且一致性和故障转移也可以得到保证,
对客户端的维护逻辑也相对容易。读写分离成本太高
把历史扫描过的最大对象统计出来,分析优化
随说:但它们的容灾性正好相反
维护每个键精准的过期删除机制会导致消耗大量的 CPU,
对于单线程的 redis 来说成本过高,
因此 redis 采用惰性删除和定时任务删除机制实现过期键的内存回收。
以减少 redisObject 内存分配次数,从而提高性能。
改为直接使用 set 修改字符串,降低预分配带来的内存浪费和内存碎片化。
不再是具体的 redis 节点,但 sentinel 只是配置中心不是代理。
可以采用 cluster 架构方案达到负载均衡的目的。
理解和灵活运用数据分区规则对于掌握 redis cluster 非常有帮助。
所谓元数据是指:节点负责哪些数据,是否出现故障等状态信息。
Gossip 协议工作原理就是节点彼此不断通信交换信息,
一段时间之后所有节点都会知道集群完整信息。
redis 集群内节点通信频率为每秒 10次。单次通信消息 > 2KB,
消息体携带的数据量根集群节点数息息相关,更大的集群代表更大的通信成本。
因此对于 redis 集群来说并不是大而全的集群更好,需要对集群的规模做限制。
随说:大规模集群可以考虑使用哨兵模式、或者拆分 redis cluster
其中原理可以抽象为槽和对应数据在不同节点之间的灵活移动。
如果节点是自身,则处理命令,否则返回 MOVED 重定向错误,通知客户端请求正确的节点。
常用于 redis I/O 优化。在集群模式下实现 mget mset pipeline 等操作。
slot → node 的映射关系,本地就可以实现
key → node 的查找,从而保证 I/O 效率低最大化,而 MOVED 重定向负责协助 smart 客户端更新 slot → node 映射。
但是可以利用 CRC16 计算出 key → slot,以及 smart 客户端保存 slot → node 的特性,
将属于同一个 redis 节点的 key 进行归类,
然后分别对每个节点对应的子 key 列表执行 mget 或者 pipeline 操作。
不知道什么时候完成。MOVED 明确表示 slot 对应的节点,因此需要更新 slot 缓存。
采用多线程加速,提供数据校验和查看迁移状态等功能。
随说:在 github 开源了
随说:考虑使用 hash 全量存,按需取
随说:订单业务很难做到,特别是订单量大
随说:以上针对单个 redis 节点,非 cluster
会影响日志排查,但不会影响功能,节点依赖各自的时钟。
并且文件名设置为 authorized_keys 即可实现免密登录。爆破主机。
看其中的 serializedlength 即可。
进入阶段性收尾阶段
总结记录下相关的内容
方便大家遇到类似问题可以想起有某个地方可以参考一、初识 AOP
利用 AOP + ThreadLocal(transmittable-thread-local,ttl)
做一部分链路追踪的事情( 耗时打印,traceId 处理 )
这部分倒是很简单,只是之前用的很少二、初识 BeanPostProcess
2.1 应用场景
有设置当前机器所属机房的方法,但是没有提供从配置文件读取的能力
因为 IDC 路由不生效,会造成跨机房访问,导致访问延迟偏高( 回头再写性能优化相关内容 )
当时发现这个问题的时候已经上线,以稳定性为主,不想升级 jar 版本
于是乎当时想通过 AOP 或者字节码的方式去做一个增强2.2 代码概览
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class Idc implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ClientFactory) {
ClientFactory clientFactory = (ClientFactory) bean;
String idc = System.getenv("IDC");
if (StringUtils.isNotBlank(idc)) {
clientFactory.setIdc(idc);
}
clientFactory.setIdc("nj");
}
return bean;
}
}2.2 BeanPostProcess 文档
三、总结
也很少做从零到一的项目
即使看过一些 spring 的书籍和文档
但是还是没有理解太深,没有太注意
果然是书到用时方恨少哇,以后还是万事深挖一步四、参考文档
]]>
为了加速迁移速度
其中就需要把查询到的数据( max 100 条)
拆分成 5 份,然后执行 5 个子任务,加速处理一、代码
1.1 常规做法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public static <T> List<List<T>> split2(List<T> lists, int subCount) {
if (CollectionUtils.isEmpty(lists) || subCount < 1) {
return null;
}
List<List<T>> result = new ArrayList<>();
int size = lists.size();
int count = (size + subCount - 1) / subCount;
for (int i = 0; i < count; i++) {
List<T> subList = lists.subList(i * subCount, (Math.min((i + 1) * subCount, size)));
result.add(subList);
}
return result;
}1.2 新颖做法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public static <T> List<List<T>> split(List<T> lists, int subCount) {
if (CollectionUtils.isEmpty(lists) || subCount < 1) {
return null;
}
// 简约的计算分桶次数,避免判断是否有余数,再+1
int splitTimes = (lists.size() + subCount - 1) / subCount;
return Stream
// 每次递增指定子列表个数
.iterate(0, n -> n + subCount)
// 限制循环次数
.limit(splitTimes)
// 转换成想要的结果
.map(item -> lists.stream()
// 跳过之前的下标
.skip(item)
// 限制每次的个数为子表个数
.limit(subCount)
// 转换为子列表
.collect(Collectors.toList()))
// 转换为主列表
.collect(Collectors.toList());
}三、性能
3.1 结果
java 8 的 stream 并不占优势,性能相差好几个数量级…1
2
3Benchmark Mode Cnt Score Error Units
ListSplit.split2Test thrpt 10 306050.155 ± 24646.689 ops/s
ListSplit.splitTest thrpt 10 353.048 ± 122.423 ops/s3.3 压测代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85import com.google.api.client.util.Lists;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author hisenyuan
* @date 2022/2/18 20:05
*/
// 默认的 State,每个测试线程分配一个实例
(Scope.Thread)
// 如果 fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。
1) (
// 预热的次数 3 次基准测试(不是执行三次方法)
1) (iterations =
// 基准执行次数 10 次(参数含义同上)
10) (iterations =
(Mode.Throughput)
public class ListSplit {
private static final List<Integer> INTEGERS = Lists.newArrayList();
public void init() {
List<Integer> list = Stream.iterate(0, n -> n + 1)
.limit(1000)
.collect(Collectors.toList());
INTEGERS.addAll(list);
}
public void splitTest(){
List<List<Integer>> listList = split(INTEGERS, 3);
}
public void split2Test(){
List<List<Integer>> listList = split2(INTEGERS, 3);
}
public static <T> List<List<T>> split(List<T> lists, int subCount) {
// 简约的计算分桶次数,避免判断是否有余数,再+1
int splitTimes = (lists.size() + subCount - 1) / subCount;
return Stream
// 每次递增指定子列表个数
.iterate(0, n -> n + subCount)
// 限制循环次数
.limit(splitTimes)
// 转换成想要的结果
.map(item -> lists.stream()
// 跳过之前的下标
.skip(item)
// 限制每次的个数为子表个数
.limit(subCount)
// 转换为子列表
.collect(Collectors.toList()))
// 转换为主列表
.collect(Collectors.toList());
}
public static <T> List<List<T>> split2(List<T> list, int len) {
if (CollectionUtils.isEmpty(list) || len < 1) {
return null;
}
List<List<T>> result = new ArrayList<>();
int size = list.size();
int count = (size + len - 1) / len;
for (int i = 0; i < count; i++) {
List<T> subList = list.subList(i * len, (Math.min((i + 1) * len, size)));
result.add(subList);
}
return result;
}四、后话
1
int splitTimes = (lists.size() + subCount - 1) / subCount;
这个不是我想到的,也不知道怎么通过数学证明,但是这样就是对的 ==
有人 star 了这个项目 Rust语言圣经
这些年也听说过 Rust,一直没有特意去了解
当我看到大佬也关注了这个课程的时候
感觉应该是一个不错的学习资料
就跟着学习了前面 4 节课
目前感觉良好
有空继续学一、实践
1.1 code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46fn greet_world(){
let southern_germany = "Grüß Gott!";
let chinese = "世界,你好";
let english = "World, hello";
let regions = [southern_germany, chinese, english];
for region in regions.iter() {
println!("{}", ®ion);
}
}
fn more_than_hello(){
let penguin_data = "\
common name,length (cm)
Little penguin,33
Yellow-eyed penguin,65
Fiordland penguin,60
Invalid,data
";
let records = penguin_data.lines();
for (i, record) in records.enumerate() {
if i == 0 || record.trim().len() == 0 {
continue;
}
let fields: Vec<_> = record
.split(",")
.map(|field| field.trim())
.collect();
if cfg!(debug_assertions) {
eprintln!("debug: {:?} -> {:?}", record, fields);
}
let name = fields[0];
if let Ok(length) = fields[1].parse::<f32>() {
println!("{}, {}cm", name, length);
}
}
}
fn main() {
greet_world();
more_than_hello();
}1.2 out put
1
2
3
4
5
6
7
8
9$ cargo run --release
Finished release [optimized] target(s) in 0.02s
Running `target/release/world_hello`
Grüß Gott!
世界,你好
World, hello
Little penguin, 33cm
Yellow-eyed penguin, 65cm
Fiordland penguin, 60cm二、资源
]]>回顾 2021
展望 2022
一、成长
有所改变的是会深入洞察需求
逐步完善设计之后开始 coding,而不是着急开始。二、阅读
由于上半年部分时间在准备换工作
以及 6 月份换了工作之后花在工作的时间比较多
所以今年的阅读量下降地厉害,但是还是会坚持每天都翻几页三、生活
夜深人静之时,回到家,给乌龟喂食互动下也挺有意思。四、习惯
需要找准自己的节奏,调节步伐,逐步早起。五、随说
六、推荐
其它的可能不太适合长时间跟踪
其中第十章,并发部分例子有争议
变量是否需要(代码如下) static?
几个大佬说需要加,我众目睽睽下反驳不需要,略尴尬
private volatile Singleton singleton;一、程序关键代码
1.1 原程序(错误)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class Singleton {
private volatile Singleton singleton;
public Singleton() {
}
private Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}1.2 正确程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Singleton {
private static volatile Singleton singleton;
public Singleton() {
}
private Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}二、验证
2.1 验证程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54public class Singleton {
private static final AtomicInteger COUNT = new AtomicInteger(0);
// 通过volatile关键字来确保安全
private volatile Singleton singleton;
public Singleton() {
}
private Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
System.out.println("new:" + COUNT.addAndGet(1));
singleton = new Singleton();
}
}
}
return singleton;
}
public void test() {
int taskCount = 700;
// 锁住所有线程,等待并发执行
final CountDownLatch begin = new CountDownLatch(1);
final ExecutorService exec = Executors.newFixedThreadPool(taskCount);
for (int index = 0; index < taskCount; index++) {
submitTask(begin, exec);
}
System.out.println("开始执行");
// begin 减1 ,开始并发执行
begin.countDown();
//关闭执行
exec.shutdown();
}
private void submitTask(CountDownLatch begin, ExecutorService exec) {
Runnable run = () -> {
try {
// 等待,所有一起执行
begin.await();
//开始模拟等待。。。
Singleton singleton = new Singleton();
Singleton instance = singleton.getInstance();
System.out.println(Objects.isNull(instance));
} catch (InterruptedException e) {
e.printStackTrace();
}
};
exec.submit(run);
}
}2.2 验证结果
对象只创建一次,并且返回结果均不为 null2.2.1 不带 static
new:1
new:2
new:3
false
true
省略几十行….2.2.2 带 static
new:1
false三、原因分析
而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。四、参考
]]>
对于一位地位如此之高的华人
甚是敬仰,奈何相关资料甚少,很难深入了解
不像李开复、吴军那样,出过一些书,了解可以多些一、工程领导(Engineering Leadership)
未来任何一个工业都会变成软件工业。
你所写的每一行代码是否值得?
追求工程技术的卓越的能力。
每天学习,每天都争取变地更好。
学经济、学产品、懂商业、懂生态。
把公司的事业,当成是自己的事业,own everything。从我做起,从身边的每一件事做起。二、关于陆奇的文章
2.1 摘要
2.2 原文
2.2.1 介绍
2.2.2 采访
三、参考
]]>
脑子里毫无相关内容,细看之下,收获不小
ps:是不是看看收藏夹,能有意外收获
安全投入的比例,可以根据公司所处的行业公司规模进行相应调整。
安全投入包括:软件安全设计、招人、买设备、买服务、做评估。二、介绍
2.1 RASP 是什么
2.2 RASP 优缺点
做一件事,方式方法有很多,最终的目的都一样。
对于安全来说,攻击方式千变万化,但是”攻击动作”万变不离其宗。
RASP 通过监控”攻击动作”进行自我保护,而不是对攻击方式的识别与防御。2.2.1 优势
2.2.2 劣势
2.3 RASP 与 WAF、IDS
而 RASP 不但能看到完整 SQL 语句,还可以和 HTTP 请求关联,
并结合语义引擎、用户输入识别等能力,实现对 SQL 注入的检测。
ps:WAF 可以理解为安全网关,门卫。IDS 入侵检测系统。三、参考
]]>
今天突然想起,博客上零散的 jvm 相关内容,
但未系统整理相关知识和工具,遂写一篇文章。二、知识
2.1 图书
2.2 文档
2.3 文章
三、工具
]]>
由于文件在 jar 包中的问题,一些读取文件的姿势失效(方便的 Guava Files)
最后通过 getResourceAsStream 解决
调整编码,重新编辑汉字都试过了,无法解决。
汉字是两个字节的,如果每次读固定个字节,可能会把汉字截断,造成乱码。
再次印证了基础知识的重要性!二、相关代码
2.1 罪魁祸首
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private static String getAddressJson(String path) throws IOException {
log.info("cacheFile start. PATH:{}", path);
InputStream resourceAsStream = Address.class.getClassLoader().getResourceAsStream(path);
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[10240];
int length;
while ((length = Objects.requireNonNull(resourceAsStream).read(buf)) != -1) {
// 此处 new String 放进去了一半中文字符,导致乱码
sb.append(new String(buf, 0, length, StandardCharsets.UTF_8));
}
resourceAsStream.close();
return sb.toString();
}2.2 完美运行
1
2
3
4
5
6
7
8
9
10
11
12
13private static String getAddressJson(String path) throws IOException {
log.info("cacheFile start. PATH:{}", path);
InputStream resourceAsStream = Address.class.getClassLoader().getResourceAsStream(path);
StringBuilder sb = new StringBuilder();
InputStreamReader isr = new InputStreamReader(Objects.requireNonNull(resourceAsStream));
BufferedReader br = new BufferedReader(isr);
String newLine;
while ((newLine = br.readLine()) != null) {
sb.append(newLine);
}
resourceAsStream.close();
return sb.toString();
}三、参考文章
随说:存二进制报文小,传输快,反序列化快(之前存 JSON 对象),节省缓存。
随说:目前倒不是要求性能,只是这么设计扩展性好,操作简单。二、设计
那么有什么好的办法能做到通用与高效?
如果固定映射,扩展性不好,查询逻辑费劲,存储成本偏高。
随说:Java MySQL 均支持与运算套餐 VIP1 VIP2 VIP3 标记值 A 1 1 1 7 B 1 1 0 6 C 1 0 0 4
A 套餐所有会有均可购买
B 套餐 VIP3 不能购买
C 套餐仅 VIP1 可购买
使用二进制,结合与运算,降本(计算、传输、匹配)增效(性能提升)。三、代码
1
2
3
4
5
6
7
8
9
10
11
12
13public static void main(String[] args) {
Integer a = 7;
Integer b = 6;
Integer c = 4;
List<Integer> suit = Lists.newArrayList(a, b, c);
System.out.printf("支持 VIP1 (0100=4)的套餐:" + Arrays.toString(suit.stream().filter(e -> (4 & e) != 0).toArray()));
System.out.printf("支持 VIP2 (0010=2)的套餐:" + Arrays.toString(suit.stream().filter(e -> (2 & e) != 0).toArray()));
System.out.printf("支持 VIP3 (0001=1)的套餐:" + Arrays.toString(suit.stream().filter(e -> (1 & e) != 0).toArray()));
// 支持 VIP1 (0100=4)的套餐:[7, 6, 4]
// 支持 VIP2 (0010=2)的套餐:[7, 6]
// 支持 VIP3 (0001=1)的套餐:[7]
}四、总结
粗糙烂制也不是不能用
但是当系统流量大了就得想办法优化:CPU、传输、存储
很多时候往往利用简单的原理解决大的问题,只是很多时候限于认知不知道可以这么用。
《移动健康和智慧医疗》算是互联网医疗的科普资料
前面部分的内容已经后面部分国际案例,了解之用足够
里面提到的『量化自我』,如果把世界量化分析,岂不是美哉?
随说:前提是大家相信分析出来的结论,以及按建议行事。一、微博读后感
过去人口红利式的告诉发展逐渐降速
老龄化突显使疾病预防和控制更重要
医疗数据收集与分析改进医疗方案
多维度健康数据分析建议促进健康
降低患者再次入院率
早运动早发现早治疗
有效地减少医疗支出二、摘抄(医疗相关)
过去中国高速发展,目前人口红利逐渐消失,老龄化日益突显,使得以传染病为主,转向非传染性疾病的预防和控制 。
血糖控制,通过监测行为特征,配合辅助功能,加强用户掌控能力,医生,家人远程支持与提醒。
随说:收集足够信息,给出专业建议
随说:给予高质量内容,提升自我恢复能力。
随说:降本增效,沉淀数据,线上线下无缝对接
随说:社交?相互鼓励,交流心得
随说:小毛病挂专家号,会诊几分钟…
PACS:影像系统
LIS:检验信息系统
RIS:放射信息系统
EMR:电子病历
HIMSS:美国医疗信息和管理协会
EMRAM:电子病历采纳模型
CHA:康体佳健康联盟
他最出名的书籍非《深入理解Java虚拟机》莫属了
书中了解到他对技术的态度,以及持续奋战一线值得学习,《程序员之路》值得一看(底部有链接)。
构建凤凰磐涅般的系统
介绍了一整套技术体系
穿插着技术的来龙去脉
着实是一部不错的书籍
架构的前提是足够了解
综合实际情况做出权衡
给人感觉不太像架构书
总的来说还是值得一看
这就是写博客等其它输出手段的作用二、部分摘抄
主要工作在
数据链路层(2层),改写Mac地址
网络层(3层),改写 IP 地址
而把复杂校验留给自己,简直就是买株还珠。
可以使用自定义注解,优雅地解决校验问题。
检查校验项预置好默认提示信息。
基础校验直接放在 bean 属性上,业务的单开类。
共识是指达成一致性的方法与过程。
状态转移模型
异步 I/O :下完外卖订单后干别的去,骑手送上门
同步 I/O
阻塞:打饭发现饭还没好,就一直干等着
非阻塞:打饭发现饭还没好,per 3min 看好了没
多路复用:同上,只是一个人可以处理多个请求
信号驱动:发现饭没好,让厨师好了通知你
模块如下
康威定律核心观点:沟通决定设计
随说:良好设计的系统,应该是能够报废的,而非一味追求一步到位。
下界:独立(发布 / 部署 / 运行 / 测试),内聚(本地事务)
上界:2 披萨团队 (6~12)在一个研发周期完成全部需求。
开发过程中少妥协,否则会形成破窗效应。
2018 graal vm,run programs faster anywhere。
优势:启动时间快,打包小,内存消耗少
劣势:无法无缝支持动态代理技术,延迟、吞吐量、可监控方面略差,性能劣于 hotspot jit 优化。毕竟是运行时优化,各种分支预测~
如果不把自己思考的内容输出给他人,
我们很容易就被自己所欺骗,
误以为自己已经理解得足够完备了。
随说:用输出倒逼输入。三、图书资源
这本书属于开源书籍,开源地址:《凤凰架构》
凤凰架构附录的一篇文章不错:《程序员之路》
特别是上一份工作,做全球支付项目,需要用到英文与国际友人沟通。
奈何自己的英语水平捉襟见肘,于是经常会有意地去收集相关的文章。
于是就想写一篇文章归集一下相关的内容,方便日后翻阅,顺便分享给有需要的人。二、资源
学习英语最重要的还是兴趣,推荐听广播,背课文,背单词。
关于学习外语的一些用途,方便大家思考自己学习的目的。
语法、动词比较重要
推荐:练习造句。分析句子。
语法树的概念蛮好理解,我让我明白了什么叫宾补~
语法和句子结构是关键,其次才是词汇量。
如果你的词汇量足够阅读技术文档,那就可以开始看了。
遇到不懂的单词,查询之,使用英英字典,记录在本子上,加强记忆。三、后话
一、问题
redis cluster 集群内存分配算法的缺陷
问题算法:单节点内存 = 集群总内存 / 节点数二、排查
2.1 key 分布问题?
在 key 均匀的情况下,考虑 slot 分配问题2.2 slot 分布问题?
redis 控制台执行:cluster slots
取最后一个节点的 rely 日志如下(日志含义见参考链接)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401(0)(0)10137
(1)10463
(2)(0)192.25.238.97
(1)2048
(2)1ab1735417e34e1fb38aa19958e2375498158be8
(3)(0)192.25.239.118
(1)2049
(2)2b444bb8ece6edcf4881cfacb60def2eb3bfba85
(1)(0)6540
(1)6866
(2)(0)192.168.184.118
(1)2048
(2)464c059fd4354b72cd277a7aaf6159a2682e47ff
(3)(0)192.168.198.232
(1)2048
(2)c4ae0536b5a9157b43516e26c4c77ca9e431005a
(2)(0)1308
(1)1634
(2)(0)192.168.197.41
(1)2048
(2)bb0b682b4eed16f773ed7b0d2cf430ac4e776624
(3)(0)192.25.222.250
(1)2048
(2)098251c97fb147b7aee8143ced13c742ec3115a9
(3)(0)8502
(1)8828
(2)(0)192.168.184.111
(1)2048
(2)3680ab0d0961e4dda6f9a35eb4c72cbcc04bba3b
(3)(0)192.168.176.75
(1)2048
(2)99d64ca4bf375460537a296ce0bdab2374c8487c
(4)(0)14388
(1)14714
(2)(0)192.25.239.116
(1)2048
(2)37d438fc43097bab896e04589b10659c2898c56b
(3)(0)192.168.184.113
(1)2048
(2)2697f554dac4c6b6452239b5f3f192052504431f
(5)(0)1962
(1)2288
(2)(0)192.168.198.241
(1)2049
(2)7c323af2d42df59cb172c1f2989fdb47972c4b6b
(3)(0)192.168.184.112
(1)2048
(2)94f67ff376efbecf3d84905dbfe6d9e8a5c9cf83
(6)(0)0
(1)326
(2)(0)192.168.197.9
(1)2048
(2)510edbf404ed2b24aeeff53f9d8f43c6404d62c0
(3)(0)192.168.198.249
(1)5010
(2)a150d1f3671d8a5e42c238e900a23031693ddd32
(7)(0)12426
(1)12752
(2)(0)192.168.198.240
(1)5010
(2)cb2c653239757df27da883dc024e87a8f11890f0
(3)(0)192.168.197.41
(1)2049
(2)ed4a2925e913bc2773cd3a4c13d48deac7f423fa
(8)(0)4251
(1)4577
(2)(0)192.25.239.105
(1)2048
(2)f2eb3bb1afc0d9345173d1eb2aaa675161f5d675
(3)(0)192.168.198.242
(1)2048
(2)67a2926615eb6e4e4f850f59f78f670010ef573a
(9)(0)9156
(1)9482
(2)(0)192.25.239.107
(1)5010
(2)4806e385ba1b193b48c0c6a8dd35e5d8a5738257
(3)(0)192.25.239.105
(1)2048
(2)c1490e0c9963628972be63339f032c63191f1897
(10)(0)6867
(1)7193
(2)(0)192.168.184.115
(1)2048
(2)2339d951c551c45daf84c147acaf6e6854f66f8c
(3)(0)192.25.222.250
(1)2049
(2)cd6e7d09828b8d795afe671c39a0312b3d6859fe
(11)(0)2616
(1)2942
(2)(0)192.168.198.234
(1)2048
(2)e5bfd81c7a0df2ec29b3ac4ce188795881b2bc1e
(3)(0)192.25.238.96
(1)2049
(2)513edbe433f180924500db83ef155426e7f2f040
(12)(0)5559
(1)5885
(2)(0)192.168.198.252
(1)2048
(2)515990729e830f0f75e3dc8179438d43c6c7c9b7
(3)(0)192.25.238.92
(1)2048
(2)5328403d6ecd5272c51250977cc1af7de3f16407
(13)(0)15369
(1)15695
(2)(0)192.168.176.78
(1)2049
(2)a140264d0aefdbb9b99c961c0c223266fa90129d
(3)(0)192.168.197.32
(1)2049
(2)5fbc13a478470e14006500e38fa032472ec0da50
(14)(0)12753
(1)13079
(2)(0)192.168.198.249
(1)2049
(2)120c04813a4f2db04bfc890874a5cf4e7ce47e15
(3)(0)192.168.197.9
(1)2048
(2)e8ca0053b9a99684f683202d68994cf8b28f26e0
(15)(0)4905
(1)5231
(2)(0)192.25.239.120
(1)2048
(2)e1a5f230ad1a7716c4e04bc785fcb001e7841b7f
(3)(0)192.168.176.76
(1)2049
(2)c370b87def3a5533ca436ac17ed22d2d5ef64cf7
(16)(0)15696
(1)16022
(2)(0)192.168.197.24
(1)2048
(2)ebad5e02b596b81431e7e35d80687b94eb4f495b
(3)(0)192.168.176.77
(1)5013
(2)96771bd26c4f0f3af5a1cb3de4de6467e07f1a6d
(17)(0)11118
(1)11444
(2)(0)192.168.198.147
(1)2049
(2)5e16b0661d43a03254fe0c9a97a21beada5665eb
(3)(0)192.168.184.109
(1)5010
(2)c132bdd8ab5c38d4cce4bee4ffc1a298e75d5538
(18)(0)16023
(1)16383
(2)(0)192.168.176.76
(1)2048
(2)e9b9b9354d6c77a980c0da35bef89b26042b716d
(3)(0)192.168.198.146
(1)2048
(2)1ca744d6e5c24d3f2c64eca1dec65eea8545ce8b
(19)(0)4578
(1)4904
(2)(0)192.25.239.104
(1)2048
(2)0aea965323c78cdefb3e8b4e03955b9651c719b6
(3)(0)192.168.198.240
(1)2049
(2)365350cfa7621749e2c696d84d32d2228122fdc6
(20)(0)10464
(1)10790
(2)(0)192.168.198.232
(1)2048
(2)2fe68c5065aefc24ddcc747071dd65c6cadd427b
(3)(0)192.168.184.118
(1)2049
(2)bdc2191de10b7d825f359922e3e31ce328c0a972
(21)(0)14061
(1)14387
(2)(0)192.168.198.231
(1)2049
(2)7a47f437951b03a95460924ffd349b3ecfb05bc7
(3)(0)192.168.184.114
(1)2048
(2)bfebcd3837ccf9df6989be91951087cb7351404c
(22)(0)9810
(1)10136
(2)(0)192.168.184.116
(1)2048
(2)3caff203db4214bea1f2bcbc2935bb3e2273ac72
(3)(0)192.25.223.2
(1)2048
(2)d2fe724704165a35eef6541f75cb2ba5245472fa
(23)(0)327
(1)653
(2)(0)192.25.238.90
(1)2049
(2)6254a81f003cce2cb66222dc312c0ad4ee0a900a
(3)(0)192.25.223.2
(1)2049
(2)7781d87ca77b51fcd07c8d0956ab350e3db3ba1c
(24)(0)9483
(1)9809
(2)(0)192.168.198.254
(1)2048
(2)a0acf25a9487c3fa6fc74af8ba57cc50d1b1a95c
(3)(0)192.25.239.119
(1)2048
(2)e05f23f53bad3f8ccc7ae4f9080426e289350557
(25)(0)12099
(1)12425
(2)(0)192.168.184.110
(1)2048
(2)39d6559849aa2d00b560cb554cfa79a30ee3ede1
(3)(0)192.168.198.247
(1)5010
(2)fe6696fa4333b4776ed5ee38b93380a21755eaa0
(26)(0)3924
(1)4250
(2)(0)192.168.198.180
(1)2048
(2)ba944b0643a2ad68033d129d78c1dee805d2191a
(3)(0)192.25.239.121
(1)2049
(2)b5b020b3105be1e4a49c57d54647da6797a0a3cc
(27)(0)14715
(1)15041
(2)(0)192.168.198.147
(1)2048
(2)937e58683236b2708fdc6ef77dd08e66ef7e7ad5
(3)(0)192.25.239.120
(1)2048
(2)274760f1e7e84bd14593b43f95965546f4cb34f5
(28)(0)1635
(1)1961
(2)(0)192.168.198.239
(1)2048
(2)ae4dc5d4d544dde49f177554c89e2001727d99e4
(3)(0)192.168.198.250
(1)2048
(2)bea5260033bac6fb7ab67a444f9a1d0e8c9f93b9
(29)(0)5886
(1)6212
(2)(0)192.25.239.116
(1)2049
(2)7c9f26573b5a79b77d9089ed7e5783f47f6d030d
(3)(0)192.25.239.104
(1)2048
(2)5c999bc681e6751ec576049db73c3bee2717f8b6
(30)(0)3270
(1)3596
(2)(0)192.168.198.179
(1)2048
(2)addeda3c397b1d6ca21996be33435f4a65ca7686
(3)(0)192.168.198.231
(1)5010
(2)1d78a81025acdc123f04680a30a80cff6258e909
(31)(0)2289
(1)2615
(2)(0)192.25.239.117
(1)2049
(2)b8ff018e1810697710963e0c4a17faca2b3b6421
(3)(0)192.168.184.111
(1)2049
(2)f7cc831c676ec19560f6ea779f86971bd227ba7f
(32)(0)6213
(1)6539
(2)(0)192.168.184.113
(1)2048
(2)ee943d8aec010e34fe1b573826d65cc9e1f14fce
(3)(0)192.168.198.242
(1)2049
(2)bfa424b2f9d4e476c3985025f5bf8bdb6625b74a
(33)(0)654
(1)980
(2)(0)192.25.239.106
(1)5010
(2)fa13eedd26af4e0364f56b1604cef9865afde98d
(3)(0)192.168.198.251
(1)2049
(2)ea87dd7cbf8b8cbeee37a3d482493b5fc41a755b
(34)(0)2943
(1)3269
(2)(0)192.25.239.118
(1)5010
(2)150932a7e4f0020b99c50312c8cec9d07d7aabcf
(3)(0)192.25.239.121
(1)5010
(2)816d511dcab3f7d9e2068401ba5958e01f2212dd
(35)(0)8175
(1)8501
(2)(0)192.168.198.148
(1)2048
(2)34d51673796ab652da7e312cff119296dae1d3bb
(3)(0)192.168.197.28
(1)2048
(2)e1f48544722bbb62d1fb8910a6a4b00d9ccbd09b
(36)(0)981
(1)1307
(2)(0)192.168.197.32
(1)5010
(2)41ea02b87652650c3ba2f085849fb6ac2169d897
(3)(0)192.168.197.28
(1)2049
(2)9717393eb89ab32126263741fd250198e378023c
(37)(0)5232
(1)5558
(2)(0)192.168.184.109
(1)2049
(2)96a728eece26f6f200b26ff9ddecae3fb5b8df11
(3)(0)192.25.239.117
(1)2048
(2)69f84dd28d8c254732a4f0d5e5fd56c60c58b7fa
(38)(0)3597
(1)3923
(2)(0)192.168.198.146
(1)2048
(2)526a0bc43f480738c704ea745f5377258c0e3cdb
(3)(0)192.168.176.78
(1)5010
(2)f54b7898236acf827c53277f22fc3dcadcd37602
(39)(0)15042
(1)15368
(2)(0)192.168.197.37
(1)2048
(2)57ceee2905d66bd5863acae5422bf9e39afa971d
(3)(0)192.168.198.179
(1)2048
(2)55192b8693c15df7f11cffc788f2043275886002
(40)(0)10791
(1)11117
(2)(0)192.25.222.249
(1)2048
(2)3c9b5f682360324951435b987489fbc2e4e5bfc3
(3)(0)192.168.198.251
(1)2048
(2)2dcf8603ecbdf43d18112dcaf06d3f9321bc2e0c
(41)(0)7194
(1)7520
(2)(0)192.168.184.112
(1)2048
(2)8a77d41c2bb0a0672654baecfdee52592bb04050
(3)(0)192.25.238.96
(1)2048
(2)8632629188cb269a900677ec0dc395cb292c1e2e
(42)(0)8829
(1)9155
(2)(0)192.168.198.241
(1)2048
(2)37684e5201b0fb50eaf184235a87f2e6a359dd01
(3)(0)192.168.184.115
(1)2048
(2)4684a38fa0b4df0b21f0d777b91300afcace551a
(43)(0)7848
(1)8174
(2)(0)192.168.184.114
(1)2048
(2)a6f9c01f4b3b2df4b4993f5745b78d1307d6ea81
(3)(0)192.168.197.37
(1)2049
(2)51e3568c115be10067d9e808d094f71f96c92647
(44)(0)13734
(1)14060
(2)(0)192.168.198.182
(1)2048
(2)6acca7f88ea98f8ba073f423707d7692592053f3
(3)(0)192.25.238.90
(1)2048
(2)84965ce2c21634a7ce9405374e36e80fa0e4521b
(45)(0)13407
(1)13733
(2)(0)192.168.184.117
(1)2048
(2)2fad26dc888fc776dec4fd33e167c860bd76d64e
(3)(0)192.25.239.181
(1)5090
(2)c91e8c9f8aea8424683258e18c5aa93ec45bb216
(46)(0)11772
(1)12098
(2)(0)192.168.199.1
(1)2048
(2)77c4678d6eddc2f8eb328fa02705d99a6c27a1ca
(3)(0)192.25.239.176
(1)5074
(2)21106c8a361da9c3cf494857e168c5b640eca234
(47)(0)7521
(1)7847
(2)(0)192.25.223.1
(1)2048
(2)ef990477dd7eb4b3c9915bf31b300e87d8fa9b29
(3)(0)192.25.239.106
(1)2049
(2)b0a2975c5cc56a69b3bc63b348a88252fa09ec1a
(48)(0)13080
(1)13406
(2)(0)192.168.198.182
(1)2049
(2)01baf618cc0945c5a379a37ff92e4b1e1eeefac8
(3)(0)192.168.184.116
(1)2048
(2)041464f26f3e7bdb277d0624ba7003bb447f227b
(49)(0)11445
(1)11771
(2)(0)192.25.239.107
(1)2049
(2)0495711f467db7ef747eeb9a24f16b7a5ce0c4ff
(3)(0)192.168.198.234
(1)2048
(2)34d285e446013db478a030f3172fce256b6d4ba8
reply from: 192.168.197.41:20481
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 把上面的日志粘贴到 slots 文件中
$ vi /tmp/slots
# 计算每个节点的槽数量并且排序,输出结果
$ cat /tmp/slots | awk '{if((NR % 8 == 1) || (NR % 8 == 2)) print $0}' | awk '{if(NR % 2 == 1) print $0,getline,$0}' | sed 's/)/ /g' | awk '{print $6,$3,$6-$3}' | sort -k 3 -r | head -n 3
16383 16023 360
9809 9483 326
980 654 326
# 根据槽号反向查找
$ cat /tmp/slots| grep 16023 -A8
(18)(0)16023
(1)16383
(2)(0)192.168.176.76
(1)2049
(2)e9b9b9354d6c77a980c0da35bef89b26042b716d
(3)(0)192.168.198.146
(1)2048
(2)1ca744d6e5c24d3f2c64eca1dec65eea8545ce8b
(19)(0)45782.2.1 相关命令解释
awk getline 获取下一行,并且赋值到 $0 (本意是代表当前行数据)。
sort -k 3 -r,以第三列排序(-k 3),倒序输出(-r)
head -n 3,输出前三行三、结论
四、改进
提示:redis 可以通过修改参数( maxmemory,单位 byte )调整最大内存。五、参考
]]>1
2
3public String dateFormatString() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date);
}
恰巧最近在 perfma 社区看 jvm 相关内容时,刷到了『性能调优必备利器之 JMH』二、结论
1
2
3
4
5
6Benchmark Mode Cnt Score Error Units
DateConvertTest.dateFormatString thrpt 10 867333.631 ± 9510.553 ops/s
DateConvertTest.dateFormatStringApache thrpt 10 2158217.955 ± 89012.866 ops/s
DateConvertTest.dateFormatStringApacheStaticPattern thrpt 10 2141167.550 ± 93715.889 ops/s
DateConvertTest.dateFormatStringJoda thrpt 10 2802803.925 ± 121600.833 ops/s
DateConvertTest.dateFormatStringJodaStaticPattern thrpt 10 2744918.391 ± 131925.235 ops/s
Error 列是空的,看 Score 和 Units 即可
ops/s:一秒钟执行多少次操作三、代码
3.1 引入相关 jar
1
2
3
4
5
6
7
8
9
10<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.23</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.23</version>
</dependency>3.2 IDEA 安装 JMH 插件
安装量最高的那个就是3.3 编写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53import org.apache.commons.lang.time.DateFormatUtils;
import org.joda.time.DateTime;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author hisenyuan
* @date 2021/5/10 18:39
*/
// 默认的 State,每个测试线程分配一个实例
(Scope.Thread)
// 如果 fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。
1) (
// 预热的次数 3 次基准测试(不是执行三次方法)
3) (iterations =
// 基准执行次数 10 次(参数含义同上)
10) (iterations =
public class DateConvertTest {
private final static Date date = new Date();
private final static String PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
public String dateFormatString() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date);
}
public String dateFormatStringJoda() {
return new DateTime(date).toString("yyyy-MM-dd HH:mm:ss.SSS");
}
public String dateFormatStringJodaStaticPattern() {
return new DateTime(date).toString(PATTERN);
}
public String dateFormatStringApache() {
return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss.SSS");
}
public String dateFormatStringApacheStaticPattern() {
return DateFormatUtils.format(date, PATTERN);
}
}3.4 执行
JMH 会默认执行当前类下面的所有的基准测试。四、执行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184# JMH version: 1.23
# VM version: JDK 1.8.0_171, Java HotSpot(TM) 64-Bit Server VM, 25.171-b11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatString
# Run progress: 0.00% complete, ETA 00:10:50
# Fork: 1 of 1
# Warmup Iteration 1: 698627.190 ops/s
# Warmup Iteration 2: 873835.360 ops/s
# Warmup Iteration 3: 870972.646 ops/s
Iteration 1: 875650.632 ops/s
Iteration 2: 872407.599 ops/s
Iteration 3: 864390.061 ops/s
Iteration 4: 872456.756 ops/s
Iteration 5: 870538.248 ops/s
Iteration 6: 861600.599 ops/s
Iteration 7: 868469.312 ops/s
Iteration 8: 868930.572 ops/s
Iteration 9: 864686.616 ops/s
Iteration 10: 854205.911 ops/s
Result "com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatString":
867333.631 ±(99.9%) 9510.553 ops/s [Average]
(min, avg, max) = (854205.911, 867333.631, 875650.632), stdev = 6290.642
CI (99.9%): [857823.077, 876844.184] (assumes normal distribution)
# JMH version: 1.23
# VM version: JDK 1.8.0_171, Java HotSpot(TM) 64-Bit Server VM, 25.171-b11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringApache
# Run progress: 20.00% complete, ETA 00:08:42
# Fork: 1 of 1
# Warmup Iteration 1: 1922497.366 ops/s
# Warmup Iteration 2: 2121425.254 ops/s
# Warmup Iteration 3: 2142439.041 ops/s
Iteration 1: 2174791.808 ops/s
Iteration 2: 2101868.007 ops/s
Iteration 3: 2174003.026 ops/s
Iteration 4: 2202522.277 ops/s
Iteration 5: 2039234.570 ops/s
Iteration 6: 2105338.449 ops/s
Iteration 7: 2205933.974 ops/s
Iteration 8: 2175865.041 ops/s
Iteration 9: 2167544.736 ops/s
Iteration 10: 2235077.658 ops/s
Result "com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringApache":
2158217.955 ±(99.9%) 89012.866 ops/s [Average]
(min, avg, max) = (2039234.570, 2158217.955, 2235077.658), stdev = 58876.499
CI (99.9%): [2069205.089, 2247230.821] (assumes normal distribution)
# JMH version: 1.23
# VM version: JDK 1.8.0_171, Java HotSpot(TM) 64-Bit Server VM, 25.171-b11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringApacheStaticPattern
# Run progress: 40.00% complete, ETA 00:06:31
# Fork: 1 of 1
# Warmup Iteration 1: 1964208.975 ops/s
# Warmup Iteration 2: 2138997.654 ops/s
# Warmup Iteration 3: 2164194.409 ops/s
Iteration 1: 2221565.433 ops/s
Iteration 2: 2231776.725 ops/s
Iteration 3: 2210494.794 ops/s
Iteration 4: 2057487.199 ops/s
Iteration 5: 2111366.133 ops/s
Iteration 6: 2150355.985 ops/s
Iteration 7: 2116673.562 ops/s
Iteration 8: 2140376.847 ops/s
Iteration 9: 2099801.246 ops/s
Iteration 10: 2071777.579 ops/s
Result "com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringApacheStaticPattern":
2141167.550 ±(99.9%) 93715.889 ops/s [Average]
(min, avg, max) = (2057487.199, 2141167.550, 2231776.725), stdev = 61987.258
CI (99.9%): [2047451.661, 2234883.440] (assumes normal distribution)
# JMH version: 1.23
# VM version: JDK 1.8.0_171, Java HotSpot(TM) 64-Bit Server VM, 25.171-b11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringJoda
# Run progress: 60.00% complete, ETA 00:04:21
# Fork: 1 of 1
# Warmup Iteration 1: 2767967.530 ops/s
# Warmup Iteration 2: 2839342.269 ops/s
# Warmup Iteration 3: 2824726.959 ops/s
Iteration 1: 2859527.645 ops/s
Iteration 2: 2799624.402 ops/s
Iteration 3: 2876558.678 ops/s
Iteration 4: 2862478.579 ops/s
Iteration 5: 2882872.177 ops/s
Iteration 6: 2860788.081 ops/s
Iteration 7: 2742885.180 ops/s
Iteration 8: 2779727.212 ops/s
Iteration 9: 2719266.181 ops/s
Iteration 10: 2644311.112 ops/s
Result "com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringJoda":
2802803.925 ±(99.9%) 121600.833 ops/s [Average]
(min, avg, max) = (2644311.112, 2802803.925, 2882872.177), stdev = 80431.422
CI (99.9%): [2681203.092, 2924404.757] (assumes normal distribution)
# JMH version: 1.23
# VM version: JDK 1.8.0_171, Java HotSpot(TM) 64-Bit Server VM, 25.171-b11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringJodaStaticPattern
# Run progress: 80.00% complete, ETA 00:02:10
# Fork: 1 of 1
# Warmup Iteration 1: 2711358.480 ops/s
# Warmup Iteration 2: 2823432.725 ops/s
# Warmup Iteration 3: 2745545.759 ops/s
Iteration 1: 2752446.099 ops/s
Iteration 2: 2792047.450 ops/s
Iteration 3: 2828389.094 ops/s
Iteration 4: 2799921.909 ops/s
Iteration 5: 2670924.332 ops/s
Iteration 6: 2533779.871 ops/s
Iteration 7: 2733321.639 ops/s
Iteration 8: 2738839.592 ops/s
Iteration 9: 2802775.869 ops/s
Iteration 10: 2796738.055 ops/s
Result "com.jd.finance.jrpaypassword.performance.DateConvertTest.dateFormatStringJodaStaticPattern":
2744918.391 ±(99.9%) 131925.235 ops/s [Average]
(min, avg, max) = (2533779.871, 2744918.391, 2828389.094), stdev = 87260.375
CI (99.9%): [2612993.156, 2876843.626] (assumes normal distribution)
# Run complete. Total time: 00:10:52
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.
Benchmark Mode Cnt Score Error Units
DateConvertTest.dateFormatString thrpt 10 867333.631 ± 9510.553 ops/s
DateConvertTest.dateFormatStringApache thrpt 10 2158217.955 ± 89012.866 ops/s
DateConvertTest.dateFormatStringApacheStaticPattern thrpt 10 2141167.550 ± 93715.889 ops/s
DateConvertTest.dateFormatStringJoda thrpt 10 2802803.925 ± 121600.833 ops/s
DateConvertTest.dateFormatStringJodaStaticPattern thrpt 10 2744918.391 ± 131925.235 ops/s五、JMH 介绍
]]>
JDK8 因未指定 MetaSpace 大小,默认初始大小约 21M
程序启动,元空间大小占用稳定在 90M
因为超过了默认元空间大小,导致元空间扩容(每次扩容会 full gc)
从 GC 日志来看,每次元空间扩容都是增加 20M 左右,所以程序启动时 full gc 4 次二、问题
三、排查过程
由于启动过程中之前没有遇到这种情况,找不到其它原因。
于是修改 JVM 参数,增加 GC 日志,于是就看到了『二』中的内容。
通过 GC 日志可以看到元空间实际占用大小,100M
于是调整 JVM 元空间大小至 128M,问题解决。
在结论部分已经讲了,这里不重复。
只有这样才能明白问题的本质,学到知识。四、背景知识
]]>
处理软中断信号的方式:二、Java 的中断
1
2
3
4
5
6// 中断当前线程,仅设置中断标识位。
public void interrupt()
// 线程的中断标识位是否被标记
public static boolean interrupted()
// 类似 interrupted,无论之前是否被中断,都不会清空中断标识位
public boolean isInterrupted()1
2
3
4
5try {
// 业务代码
} catch (InterruptedException e) {
// 可选:退出 | 忽略 | 执行相关逻辑
}三、扩展
四、参考
]]>
遇到了很多底层的问你题,eg: 网络、硬件、虚拟机等,
有些现象虽然知其然,但是不知其所以然,书到用时方恨少!
抱着深入学习的心态这两年看了一些相关书籍:
《操作系统精髓与设计原理》
《Java性能优化权威指南》
《Redis运维与开发》
《性能之巅》
误打误撞,看到了之前在 GitHub 关注的一个『自学计算机科学』仓库,很赞同下面这个观点
然而,随着时间流逝,第一种工程师不断成长,所做的事情将会越来越有意义且更为高薪,
不论是有价值的商业工作、突破性的开源项目、技术上的领导力或者高质量的个人贡献。一、资源
1.1 摘要
科目 为何要学 最佳书籍 最佳视频 编程 不要做一个“永远没彻底搞懂”诸如递归等概念的程序员。 《计算机程序的构造和解释》 Brian Harvey’s Berkeley CS 61A 计算机架构 如果你对于计算机如何工作没有具体的概念,那么你所做出的所有高级抽象都是空中楼阁。 《深入理解计算机系统》 Berkeley CS 61C 算法与数据结构 如果你不懂得如何使用栈、队列、树、图等常见数据结构,遇到有难度的问题时,你将束手无策。 《算法设计手册》 Steven Skiena’s lectures 数学知识 计算机科学基本上是应用数学的一个“跑偏的”分支,因此学习数学将会给你带来竞争优势。 《计算机科学中的数学》 Tom Leighton’s MIT 6.042J 操作系统 你所写的代码,基本上都由操作系统来运行,因此你应当了解其运作的原理。 《操作系统导论》 Berkeley CS 162 计算机网络 互联网已然势不可挡:理解工作原理才能解锁全部潜力。 《计算机网络:自顶向下方法》 Stanford CS 144 数据库 对于多数重要程序,数据是其核心,然而很少人理解数据库系统的工作原理。 《Readings in Database Systems》 (暂无中译本) Joe Hellerstein’s Berkeley CS 186 编程语言与编译器 若你懂得编程语言和编译器如何工作,你就能写出更好的代码,更轻松地学习新的编程语言。 《Crafting Interpreters》 Alex Aiken’s course on Lagunita 分布式系统 如今,多数 系统都是分布式的。 《数据密集型应用系统设计》 MIT 6.824 1.2 详情
原文:Teach Yourself Computer Science
翻译:自学计算机科学
The OS Classics三、相关资源
]]>
弹指一挥间,12 天的假期已经成为过去。
期间还是有不少的收获,最主要的是看了 4 本书。
以及在微博上面看到了不少的人和事,甚是触动。一、阅读
1.1 《 UML 和模式应用》0113~0207
基于职责去做设计的理念确实很棒,值得观摩实践。1.2 《段永平投资问答录(商业逻辑篇)》0120~0214
关键是:要做对的事情,把事情做对。(前者更重要)
创始人对公司的文化影响很大,文化又对公司影响大。
很幸运有如此成功的人愿意与普通人进行交流,传授经验。
还有所谓的圈子,多看多想多学,总是会进步的。1.3 《代码精进之路:从码农到工匠》0216~0217
其中的很多理念深度赞同
是一本值得翻阅的书,收益颇多1.4 《硅谷钢铁侠:埃隆·马斯克的冒险人生》0217~0218
羡慕他精力旺盛、超强的学习能力、以及追求梦想的执着二、微博
特别是关于一个 95 后实习生的故事
也很佩服纯银从一个法警做到如此高阶的产品经理
羡慕他把看产品的思路套用在看公司上,然后 2020 投资中概股收益颇丰三、生活
有时候不管是家人之间的沟通,还是朋友之间,可能更多的时候需要的是倾听,而不是讲道理。
犹如《代码精进之路》里讲的”不过在家里,我依然是输多赢少,后来我才发现,原来家不是一个讲逻辑的地方。”
位置:7.4.2 如何做一个让 Ta 们讨厌的人
及时给对方负反馈,否则受伤的是整个团队。
看了这本书之后,感觉对产品有新的认知,
知道他们在做什么,怎么做,后续可以更好的与他们沟通。
而且里面的内容对于研发来讲也是适用的。一、开始实施之前
1.1 不说清需求价值
1、时支支吾吾
2、这是老板(XXX)要的,假装自己是个传话筒
3、我接的是二手需求,什么都不知道
随说:其实正确的做法是追溯这个需求的初衷,有利于评估 ROI (投入产出比),以及排优先级,以及增进对业务的理解。1.2 不去想细节功能
1、装作自己完全没有想过
2、那就这样做
3、肯能那样做也可以
4、要不你来定吧
随说:这些表现其实都是不负责的!没有明确的需要,后期容易扯皮,也可能做出来的东西有问题。1.3 帮技术评估工作量
2、这些我都评估过了,都能做
3、不要偷懒,不要忽悠我,我抖动
随说:评估真是个高难度的活,往往只见树木不见森林1.4 逼着技术团队承诺
随说:互联网企业更多的只是一个”预测”,而非”承诺”,因为变化太快,承诺是技术对产品的责任,而预测是产研一起担责。二、实施过程中
2.1 做了一半改需求
随说:非受迫,意味着是产品没有想清楚,然后导致研发无谓劳动。万万不可取。2.2 开发过程中消失
随说:一般都需要多次沟通,反复确认细节。2.3 过度关注细节
随说:这种一般少见,研发转岗产品的多一些三、产品发布之后
3.1 没有发布后的反馈
随说:技术人员也需要从市场、用户那里获得反馈,从而对自己做的事情产生价值感和成就感。3.2 任务无节奏感
2、一会儿让研发有着天天通宵的高强度,给 deadline,下死命令,做完之后不知道做什么。
随说:保持合理的安排,让研发有个合理的预期比较好。而不是等你们上了大学就自由了这种…四、全程适用
4.1 优柔挂断
2、啊…那个…方案各有利弊,我也不知道怎么办,你们有什么好想法
随说:自己左手和右手互搏,思考清楚之后给大家一个明确的结果。4.2 报喜不报忧
随说:这样很破坏信任感4.3 不把 Ta 们当人看
随说:结果导向没有问题,但是没有成长,留不住人。
下载下来的日志文件是压缩包1.1 文件信息
1
2
3
4system_error.log.2020-11-01.20201105200433.zip
system_error.log.2020-11-01.20201105195953.zip
system_error.log.2020-11-01.20201105200830.zip
...省略1.2 压缩包信息
1
2
3
4
5
6
7$ unzip -v system_error.log.2020-11-01.20201105200830.zip
Archive: system_error.log.2020-11-01.20201105200830.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
4495560 Defl:N 78526 98% 11-01-2020 23:43 504551c6 system_error.log.2020-11-01
-------- ------- --- -------
4495560 78526 98% 1 file
例如:system_error.log.2020-11-01
于是想使用 shell 来解决( 之前没写过 shell )1.2 尝试过程
1
2
3$ unzip '*.zip'
Archive: system_error.log.2020-10-15.20201105200943.zip
replace system_error.log.2020-10-15? [y]es, [n]o, [A]ll, [N]one, [r]ename:1
2
3
4$ unzip -n '*.zip'
Archive: system_error.log.2020-10-15.20201105200943.zip
...省略
100 archives were successfully processed.1.3 怎么解压并且重命名?
1
2mv A B
# 把 A 改名为 B1
2
3
4
5
6
7
8
9
10
11
12
13
14# 输出压缩包内的信息
$ unzip -v system_error.log.2020-11-01.20201105200830.zip
Archive: system_error.log.2020-11-01.20201105200830.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
4495560 Defl:N 78526 98% 11-01-2020 23:43 504551c6 system_error.log.2020-11-01
-------- ------- --- -------
4495560 78526 98% 1 file
# 使用 awk 截取相关信息
# NR 行号,NF 最后一列
# unzip -v 的输出方式可能有变动,需要自己修改位置,以得到正确的结果
$ unzip -v system_error.log.2020-11-01.20201105200830.zip | awk '{if(NR==4) print $NF}'
system_error.log.2020-11-01二、脚本信息
2.1 脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 !/bin/sh
压缩包目录
srcDir=$1
解压后文件存放目录
dstDir=$2
文件名序号
seq=1
for file in ${srcDir}/*
do
# 判断是否为文件
if test -f $file
then
# 获取压缩包名称,例如:system_error.log.2020-11-01.20201105200830.zip
filename=$(basename $file)
# 解压文件,移动文件,并且改名(这里使用的是序号,可以截取原文件名拼接时间戳等避免重名)
unzip $filename && mv `unzip -v $filename | awk '{if(NR==4){print $8}}'` ${dstDir}/$((seq++))
fi
done2.2 使用方法
1
2chmod 775 uf.sh
sh uf.sh ./src ./dst三、总结
第一次写脚本相对耗时,也是一个不错的尝试过程。
对linux系统相关的命令/函数不熟悉,导致到处查资料,有必要系统化的看看书。四、参考信息
]]>
ps:没有提供注释,对新手不太友好单位 英文全称 中文全称 转换 b bit 位 - B Byte 字节 1B=8b KB Kilo Byte 千字节 1KB=1024B MB Mega Byte 兆字节 1MB=1024KB GB Giga Byte 千兆 1GB=1024MB TB Trillion Byte 万亿字节 1TB=1024GB PB Peta Byte 千万亿字节 1PB=1024TB EB Exa Byte 百亿亿字节 1EB=1024PB ZB Zetta Byte 十万亿亿字节 1ZB=1024EB YB Yotta Byte 一亿亿亿字节 1YB=1024ZB BB Bronto Byte 一千亿亿亿字节 1BB=1024YB NB Nona Byte 1NB=1024BB DB Dogga Byte 1DB=1024NB CB Corydon Byte 1CB=1024DB 二、带宽/网速
2.1 带宽
注意:这是传输速率,而不是下载速度。
它们的单位其实是:bps (全称 bit per second,b/s)
50M 中 M 的含义是:million 即 百万。
翻译过来就是:50Mbps = 50,000,000 b/s;2.2 网速
这个 12M 的单位是 byte 也就是字节。
由表常见单位可知,1byte = 8bit
即 100M 带宽,理论上最大的下载速度为:100Mbps / 8 = 12.5Mbyte / s(俗称网速 12.5M);三、字节占用
问:一个英文(或标点)占用多少字节?一个汉字(或标点)占用多少字节?
答:与所使用的编码有关系,具体如下表:
]]>编码 英文 汉字 ASCII 1byte 2byte UTF-8 1byte 3byte Unicode 2byte 2byte
A 系统:CPU 高 load 低
B 系统:CPU 低 load 高
CPU 高了系统肯定跑不动了,那么 load 多高代表系统跑不动呢?一、解释
CPU 很忙,没有等待其它资源,瓶颈在 CPU。
等待磁盘 I/O 完成的进程过多,导致进程队列长度过大,
但是 CPU 运行的进程却很少,这样就导致负载过大,但 CPU 使用率低,瓶颈不在 CPU,可能在 I/O。二、load averages 知识
Linux 平均负载不仅跟踪可运行的任务,还跟踪处于不可中断睡眠状态的任务。
在 Linux 上,负载平均值是(或试图是)“系统负载平均值” ,对于整个系统来说,测量正在工作和等待工作的线程数(CPU、磁盘、不可中断锁)。换句话说,它测量的是没有完全空闲的线程数量。优势: 包括对不同资源的需求。
1993年,一位 Linux 工程师发现了一个与平均负载不直观的案例,一个三行补丁永远地将它们从“ CPU 负载平均值”改变为人们可能称之为“系统负载平均值”他的更改包括处于不可中断状态的任务,因此平均负载反映了对磁盘资源的需求,而不仅仅是 cpu。三、总结
四、load 优化
五、参考
]]>
两台机器完全处理一样的工作
大部分时间对象朝生夕死,很少进入老年代
CMS 指定了新生代最大 1536M,略微有点浪费
于是设置 G1 自动调节各个区域大小,看看能否有所改善
也因为最近重温了两本 JVM 相关的书籍,找机会进行实践看看一、G1 设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14-Xms4096M
-Xmx4096M
-XX:+UseG1GC
-XX:+UnlockDiagnosticVMOptions
-XX:SurvivorRatio=8
-XX:+ParallelRefProcEnabled
-XX:MaxTenuringThreshold=6
-XX:ParGCCardsPerStrideChunk=4096
-XX:MaxGCPauseMillis=100
-XX:MaxMetaspaceSize=256M
-XX:MetaspaceSize=256M
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:/home/hisen/gc.log二、CMS 设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34# 初始堆大小
-Xms4096M
# 最大堆大小
-Xmx4096M
# 年轻代的大小
-Xmn1536M
# eden 区比例,此处为 8:1:1
-XX:SurvivorRatio=8
# 最大元空间大小
-XX:MaxMetaspaceSize=256M
# 最小元空间大小
-XX:MetaspaceSize=256M
# 使用 CMS 垃圾收集器
-XX:+UseConcMarkSweepGC
# 只使用占用率作为启动 CMS GC 的标准,配合 CMSInitiatingOccupancyFraction 使用
-XX:+UseCMSInitiatingOccupancyOnly
# CMS垃圾收集器,当老年代达一定比例,触发CMS垃圾回收。此处为 70%
-XX:CMSInitiatingOccupancyFraction=70
# 默认为 false,并行的处理 Reference 对象,如 WeakReference,除非在 GC log 里出现 Reference 处理时间较长的日志,否则效果不会很明显。
-XX:+ParallelRefProcEnabled
# 开启或关闭在CMS重新标记阶段之前的 YGC 尝试
-XX:+CMSScavengeBeforeRemark
# 晋升老年代的阈值
-XX:MaxTenuringThreshold=6
# 解锁诊断参数,否则 ParGCCardsPerStrideChunk 不生效
-XX:+UnlockDiagnosticVMOptions
# 每个线程扫描 old gen 的 CardTable (一定大小的内存块) 个数
-XX:ParGCCardsPerStrideChunk=4096
# 打印 GC 的时间戳
-XX:+PrintGCDateStamps
# 打印 GC 明细日志
-XX:+PrintGCDetails
# 存放 GC 日志的路径
-Xloggc:/home/hisen/gc.log三、结果对比
Type Duration Xmn YGC count YGC avg Interval Time G1 72 hrs 21 min 8 sec 1.66G 7596 19.6 ms 34 sec 294 ms CMS 70 hrs 24 min 51 sec 1.5G 7029 14.4 ms 36 sec 68 ms
就上表来看,G1 新生代的大小确实上去了,但并不尽如人意。
但是随着而来的是 G1 『更频繁的YGC』以及『更长的停顿时间』
在《深入理解JVM虚拟机》第三版看到,
由于 G1 处理跨 region 需要耗费额外 10% ~ 20% 的资源,小堆 (堆大小<8G) 上没有优势。
大部分应用按这个设置是 OK 的,
虽然有时候看着老年代一直很小,
设置那么大浪费内存,但是当调用量大的时候,就能派上用场,减少 Full GC。
看这个文档本来的目的是每天坚持阅读英文文档
技术文档一般都比较简洁易懂,英语是一个长期的过程,还得继续坚持阅读~
看的过程中发现,结合一定的场景,和示例
和官方文档相比,没有那么枯燥,也更好理解
甚至有一些之前未曾关注的用法让我感到惊艳
所以推荐一下
下载地址:how-to-manage-a-redis-database.pdf
]]> - - -很多时候我们调用接口并不是需要接口返回的所有信息;
就像查询数据库很少使用 select * from table; 一样;
为了使现有的存储结构以及代码逻辑改动最少
想办法在最外层的接口对返回的对象进行精简
目的使为了提高接口性能:减少 RPC 传输时间、节省网络带宽、节省序列化开销
前面两种比较呆板,属于定制化开发;
Spring BeanWrapper 方案处理非集合对象比较完美,输出对象小不少;
基本数据类型有默认值,无法去除,不过这种对大小影响不大;
完整代码:github.com
1 | public static void main(String[] args) { |
输出 src:
1 | { |
输出dst
1 | { |
目前 Spring BeanWrapper 处理集合类型比较费劲,需要告知一个个具体的路径
比如:productInfos[1].name
如果能做到 productInfos[any].name 这种,然后取出所有 index 的属性,就比较完美
(目前解决方法:通过自定义处理,遇到 any 标识,自动补全所有 index 的 key 即可,只是不那么优雅)
缺陷原因:内部逻辑直接用 key 转换为 index ,没有 any 逻辑。
1 | else if (value instanceof List) { |
代码位置:org.springframework.beans.AbstractNestablePropertyAccessor#getPropertyValue
Spring 官方文档:Bean Manipulation and the BeanWrapper
]]>有个朋友抛出一个问题,明显不符合最左匹配原则的 SQL,居然走索引了
兜兜转转,嘀咕了好几天,期间也和几个朋友讨论了一下
都没有结果,最后还是在 MySQL 的官方文档中找到了原因
记录下,也算是一次不错的探索。
1 | CREATE TABLE `people_new` ( |
1 | mysql> select * from people_new; |
可以看到 Using index
但是 possible_keys null 而 key 显示 index_union
1 | mysql> explain select * from people_new where bob = '2008-08-08' and first_name = 'yuan'; |
1.1 的表结构显示,除了 id,其余三个属性都在 联合索引 中
所以通过任何字段查询,返回的字段都被索引覆盖了,构成 覆盖索引 ,
由于扫描全部索引会快于全表扫描,所以这时候 sql 不管是不是最左匹配都会走索引(应该是『全索引扫描』)。
3.1 的表结构中,除了 id ,还有 area 不在联合索引当中,此时破坏了 覆盖索引 ,故不走索引。
1 | If the index is a covering index for the queries and can be used to satisfy all data required from the table, |
1 | CREATE TABLE `people_new` ( |
1 | mysql> select * from people_new; |
1 | mysql> explain select * from people_new where bob = '2008-08-08' and first_name = 'yuan'; |
有时候多和同行交流也能学到很多。
带着问题去看官方文档收获会比较大。
遇到问题,找到原因,解决问题,印象会深刻。
面试决定因子:70% 能力、20% 缘分、10% 行情。
软件工程师是条不归路,每天进步一点点,早日走上人生巅峰。
仓库的内容更多是抛砖引玉,提供通用与重要的技术,
真正掌握还得贴合自身需要,花时间持续深入地学习。
基础指引:https://github.com/Snailclimb/JavaGuide
进阶之路:https://github.com/doocs/advanced-java
编程书籍:https://github.com/jobbole/awesome-programming-books
算法小抄:https://labuladong.gitbook.io/algo/
大厂试题:https://github.com/0voice/interview_internal_reference
简历打磨:https://github.com/geekcompany/ResumeSample/blob/master/java.md
后续持续更新,多交流,共同成长。
早几天在领导 JG 的朋友圈看到这篇文章
简单几个字的标题,让我产生了兴趣
一来这个标题是挺吸引人,典型的自媒体文章
二来JG 之前推过一些书很不错
三来一般领导朋友圈都不会推垃圾信息
全文看来其实感觉还是挺切合我的认知:
离开学校
大部分时间都是围绕着工作
有些人可能觉得当前的工作不满意
然后想着学点什么高大上的东西为以后的工作做准备
极端情况下这种选择是对的,大部分情况会让自己进退两难
正确的选择应该是:过好当下,瞭望远方,持续学习,总结反思,慢慢进步
架构师同事 SGLS 说过:做好当下的事情才是最重要的,不管现在是做什么项目,设计和实现是我们自己可以控制的。
以下为原文
1 | 审视是一个特别好的词。当一个人开始审视世界、审视经历、审视自己的时候,更容易做出有担当的选择。 |
什么是促使人成长的本质原因?
王慧文一直在渴求突破,也一直在探究这个问题。
王慧文修行的开端,就是校内网。
2006年3月,王慧文、王兴和另外四名同伴绞尽脑汁、黑白颠倒,终于让校内网收获了一百多万用户。
王兴开始四处找投资,但在多数投资人眼里看来,他们仍是群“生瓜蛋子”、“杂牌军”,校内网不过是几个大学生做的小打小闹的玩意儿。
但在这时,千橡集团董事长陈一舟出现了,他愿意拿出一千多万人民币,收购校内网。《九败一胜:美团创始人王兴创业十年》中这样描述
1 | 陈一舟说,如果你们不卖,我们可以拿这钱砸到市场上推广。当然,校内网的这群狂妄的小子被这句话激怒了,拒绝跟陈一舟谈。 |
不论校内网是成功的,还是失败的,在王慧文和王兴的心里,它永远都是遗憾的。
回首往事,王慧文已经不再执着,反而觉得这段遗憾对自己的人生是件好事。他说:
如果校内网做成了,我会变成让别人非常讨厌的人,刚愎、自负,因为挫折,所以我才懂得反省自己,能更理智客观冷静地看待自己。
还有人问王慧文,如果当初不卖的话,校内网能不能做得成?王慧文答:
这取决于我们遇到什么样的投资商,如果投资商能够在很多地方帮助我们,是可能做成的;如果投完钱就不怎么管,让我们自己随便搞,那就不行,因为我们还不够成熟。
管理者的自我反思,会反馈在他的战略、领导力、管理、业务实操等能力上。
人必须反思,是因为事物是时刻变化的,不断反思,才能不断跟上变化。
王慧文在一次采访中说:美团的持续高速增长,不是我们在推动着业务发展,而是业务快速发展,我们努力地跟上,不是我们做了什么事情,只是我们跟上了,没掉队。
在一个快速发展的行业里,在一个快速变化的时代里, 创业者、管理者如果没有自我反思,是很难生存下来的。
在第一次创业修行中,王慧文就悟出一个道理:人,把事做成不易,不断成长、突破自己边界更难。
“君子不器”是王慧文的人生原则之一。
2019年,在极客公园创新大会上,极客公园创始人、总裁张鹏问王慧文:你觉得美团的基因是什么?
王慧文当时就说出了“君子不器”四个字,他面对张鹏侃侃而谈:孔子说,君子不器,君子不是一个器皿,人不要搞自我定义,自我定义就是自我设限,我不倾向于用美团的基因来自我设限。
他还用“基因突变”举例,基因变化变错的概率比变对的概率高几百万倍,所以大家都很恐惧基因变化,抵触变化。
但王慧文认为变化不可怕,自我设限才最可怕,他还幽默地说:一旦变对了呢?一旦长出翅膀了呢?
这种不自我设限,就是“美团无边界,专注而不专一”的根源。
君子不器,有两个含义:
一是人想要成长就不能有固化思维,事物是变化的,人也要具备动态发展的眼光,反思过去,展望未来;
二是人不能像器皿那样自我设限,器皿只有某一方面的用途和才能,而人应该博学多识。
孔子的这两点要求,王慧文都做到了,他的生活和工作就是如此。
《财经天下》周刊记者朱晓培这样形容“百变的王慧文”
1 | 在王慧文的朋友圈里,总能看见他忽然想到一个问题,比如:是不是20世纪在唯心主义和唯物主义领域都没有出现过大师?如果地球上没有美洲,哥伦布的船直接西行到了亚洲,今天的世界格局又会是什么样子?为什么射雕英雄传的五绝里只有反派欧阳锋没有广招门徒? |
正如王慧文在内部信中所说,他个人的兴趣“散乱不稳定”。
当年创业时,王慧文和王兴都不会敲代码,但他们都觉得:没事,我们可以学。同样,后来在美团时,有一段时间王慧文要研究零售,他几乎每天都看一本关于零售的书,并且跟很多人谈论自己的心得。
1 | 王慧文敬佩爱因斯坦,爱因斯坦曾说:科学和艺术一样,都让我们的世界更加绚丽多彩。 |
王慧文从中体会到:爱因斯坦经常从艺术和审美的视角去探讨科学命题,人如果永远只站在一个视角来看待人生,人生就会变得特别狭隘,不够丰富,而站在不同视角来看待问题,不设限地长大,才非常重要。
不自我定义、不自我设限、不抗拒变化、不沉溺过去的王慧文,与“无边界”的美团极为匹配。
1 | 2012年底,美团实现盈亏平衡后,王慧文认为团购领域大局已定,又开始把目光聚焦在了外卖领域。 |
如果管理者认为自己就是一个器皿,那么你就会认为自己的状态永远不会改变,也没有改变的必要。如果王慧文这样想,就不会为美团的基业立下赫赫战功。
只有当你明白“君子不器”的道理时,才会意识到成长的必要性,也才会清醒地看到自己过去的弱点。
不自我设限,多元思考人生,始终相信自己有更多机会,这样的管理者才能持续地自我突破,才能在激烈的竞争中拼杀出属于自己的战场。
造就能征善战的王慧文
王慧文信奉曾国藩的九字箴言:练强兵,结硬寨,打呆仗。
“练强兵”很容易理解,当时清朝腐败,太平天国武装起义,清朝的正规军竟无力抵抗,只好调动地方军事力量,多亏有曾国藩统率的湘军,才能击败太平军。此后,湘军成为了清朝军事上强有力的骨干。
没有强兵,则无法作战。但强兵如何练成?
曾国藩治理湘军,主要凭思想纪律,而不是战术技巧。
王慧文“练强兵”,看重三点:人聪明,接地气,学习能力强(不是考试能力强)。
其次,王慧文主张:管理者的一个重要责任,就是——担当。
王慧文有一句话曾经火遍全网:
有担当的管理者,要把下属从“愚昧之巅”推向“绝望之谷”,至于下属能否爬上“开悟之坡”,看个人造化。
王慧文解释,这句话的核心词是“担当”。
他向来不喜欢说“责任”,因为他认为:责任可以逃避,只有有担当的管理者才不会逃避责任。
那么,什么是“愚昧之巅”、“绝望之谷”、“开悟之坡”?
这些词语源于 达克效应 ,王慧文说:我思考我个人的成长和周围同事的成长,每个人都希望自己最后成为智者(大师),但是,我们要承认一个事实,大部分人没有走上去。
愚昧之巅——人的智慧极低,但是自信度极高;
绝望之谷——认识到自己的不足,智慧有所增长,自信度大幅降低;
开悟之坡——智慧继续增长,自信度开始反弹增长;
持续平稳高原——智慧达到顶级,自信心也持续平稳,走上大师之路。
王慧文说:大部分人没能从愚昧之巅走到绝望之谷,大部分人都在这个部分遇到了困难。
王慧文借用“达克效应”理论,不是为了拆穿别人的智慧不足,而是为了强调管理者的担当,他认为:
1 | 大部分人都知道别人处在愚昧之巅,但是很少有人知道自己处在愚昧之巅,这就产生了非常大的信息不对称。 |
王慧文觉得他们在离开美团的环境后,很可能更没希望得到他人的有效反馈了,所以他有好几次,在同事或下属离职时,告诉了对方正处于愚昧之巅的真相,但是转眼就被拉黑了。
尽管王慧文承认他们是一个好人、正直的人,也是一个想成长的、对美团有过贡献的人,将来也会成为对社会有贡献的人,王慧文希望对方成长得更好,才戳破真相,但是要戳破真相、给他人有效反馈,就必须承担得罪人的风险。
也正因此,管理者才更需要担当。
王慧文说:你给别人反馈的时候,也可能你自己是一个傻×,可能我自己是在愚昧之巅,其实人家是对的,这个可能性也是很大的,通过这个行为反而证明了你可能在愚昧之巅的事实。
管理者能不能从善意出发,帮下属敲响警钟?又能不能在被误解时,甘愿承受来自下属的伤害?或者是在发现自己比下属更愚昧的时候,还能不能调整心态,通过努力学习来提升自己的智慧和自信?
回答这些问题的最好方式,就是努力向一个有担当的管理者去逼近。
担当,是管理者们最稀缺的能力,但却是“练强兵”必不可少的素质。
“结硬寨,打呆仗”,是曾国藩的兵法内核。字面意思是,把军营扎得坚如磐石,打仗时不讲究技巧而是追求笨方法。
曾国藩带兵打仗有个规矩,他到任何地方安营扎寨之后,不论当时是刮风还是下雨,首先命令士兵们挖掘战壕,壕深约两米,而且还要筑墙,墙高约八尺高,墙外再挖一道沟。这就确保整个营盘固若金汤。
湘军总是要挖沟、筑墙,行军速度非常慢。由于这种打法显得特别笨,所以才叫“结硬寨,打呆仗”。
王慧文的工作速度并不慢,但他也爱下笨功夫,一个细节一个细节得打磨,确保每个业务流程都能稳扎稳打。
美团前员工这样评价王慧文:老王可能是我见过在互联网行业,大佬级别中所谓“比你聪明还更拼搏”,并且会关注很多业务细节的人。
工作起来,王慧文就像变成了拼命三郎,让很多比他年轻的人都心生畏惧。
据美团前员工回忆:每周六下午,是大团队的业务管理会,每个分支业务的负责人要详细地讲解业务进度,用数据说话,以结果为导向,绝对不让周报变成“流水账”;
在这个过程中,王慧文会非常认真地听每个人的讲解,绝不走过场,绝不讲废话;
某个员工在周报中提及“某个数据变化属于正常波动”,这是产品负责人没有特别认真思考或经验欠缺、全局感不强而惯用的一个理由,而此时王慧文则会一针见血地指出是因为什么问题、什么原因导致的数据变化,让人心服口服。
王兴在内部信里这样评价王慧文:
1 | 美团精神,老王身体力行、堪称典范。回顾老王过去九年多的工作,既有冲锋在前的勇猛,又有安营扎寨的稳健;既有舍我其谁的担当,又有功成不必在我的潇洒;既有“天下兴亡,匹夫有责”的责任感,又有“我们什么都没有,但是我们有兄弟和勇气”的真性情;既长期有耐心地保持战略定力,又坚持时不我待、只争朝夕地忘情投入。 |
2013年6月,美团收购猛买网,猛买网创始人张智勇在加入美团之后,曾发微博说:牛x都是苦x堆出来的,你看美团网牛x,没看到的都是苦x。原来公司没有比它做得好,就是我不够苦x,是因为我管理不好。在这里,每月每周都能学到东西,蛮好的。辛苦没关系,能学到东西就行,最怕加班没结果。
对王慧文来说,周六全天开会,周日半天高管会,每周留给自己的时间或许只有一个下午而已。但王慧文向外界和美团内部员工展现的,永远是一副精力充沛、充满激情的样子。
这就像将军带兵打仗,“跟我上”和“给我上”,一字之差,但全军的战斗力却会有天壤之别。
前者能把团队里每个人的心思都拧成一股绳,无往不胜;后者却永远苦于团队像一盘散沙。
造就未来不可限量的王慧文
王慧文在今年年初的内部信里,把自己在美团拼搏的17年激情燃烧岁月,轻描淡写地说成了“我运气实在太好”。
低调、收敛,不是王慧文今天才有的风格,而是他始终具备的性格底色。
王慧文经常开玩笑地说,我是农民的孩子,只会拼命工作。玩笑的背后,是他专注做事的态度,以及不居功自傲的格局和胸襟。
管理者要常常怀有“清零思维”,过去的错误要变成未来的前车之鉴,不能用来惩罚自己;过去的成就要变成未来的经验和警示,不能用来炫耀自己、骄傲自满。
如果管理者觉得自己“满了”,也就意味着,你认为自己的成长之路到头了。
清零思维也是一种包容心。《九败一胜:美团创始人王兴创业十年》写道:王慧文曾去过无锡,见到88米高的灵山大佛,从远处看大佛,跟山一样高,走近大佛,人还没有大佛的脚趾头高。
王慧文心想,如果这尊大佛有脚臭的话,那么来观光的人就只能闻到大佛的脚臭味,而看不见整个大佛的巍巍如山。只有包容的人,心胸宽广,眼界开阔,才看得到大佛的宝相庄严。
该书的作者李志刚说:也只有包容的CEO,才能听到下面的真实心声,兼听则明,才能有各种奇人异士来帮你做事。
王慧文这17年来,已经为美团培养了大批人才,也为人才梯度建设付出了贡献,他离职后,自然也不需要人才来帮自己做事了,但是这种包容心会始终伴随他,让他的未来无法限量。
王慧文也包容对手,他和王兴都不认为美团是在跟同行们“争”,美团是在“竞”,他说:我们不认为千团大战是我们打赢了别人,而是我们跟上了行业节奏,他们没有跟上,这个认知是跟打仗不一样的;同向为竞,相向为争。
包容,就是不眷恋。
王慧文不眷恋名利荣誉,他说“我运气实在太好,不宜继续贪天之功,知止不殆”;
王慧文不眷恋自己的能力,他说“感谢我的家人,承受很多困难,无怨无尽地给我支持和包容”,还感谢了时代、王兴和所有同事;
王慧文不眷恋他的江湖,他说“美团十年,豪兴不浅。他日江湖相逢,再当杯酒言欢”。
金庸先生曾写:天上白云,散了又聚,聚了又散,人生离合,亦复如斯。
今天,我们预测王慧文的人生“下半场”会有怎样的风景,已经是徒劳,因为他早已选择了一条“不确定”的人生旅程。
王慧文说过,固定靶比移动靶更难打中。人生就像一个移动靶,我们谁也不知道自己的未来将穿梭至何处,也几乎不可能帮别人预测。
我们只能希望,当自己修炼出清零思维、包容心、不眷恋的人生态度时,能够跟上时代变化莫测的脚步,不要掉队。
不论人生的下半场将会如何,至少王慧文已经可以潇洒地说出一句——“这十年激烈精彩,不负年华”。
分页查询一般都会想到 offset limit
当不停机需要全量同步数据时
有可能会漏掉或者重复处理很多数据
因为中途会有数据改动
每次分页内的数据与预期的会有出入
offset 会进行全表扫描
通过不变的字段进行排序
最好是使用递增的主键索引
1 | select * |
工作当中会遇到很多部署导致的问题
其中大部分的问题原因是配置问题
关于部署
互备很重要,哪怕对方没有介入开发,简单的按正常流程问你几个问题,也许就会发现漏了什么。
]]>美国风险投资家 Naval Ravikant 通过一个很长的推特阐明了他的商业观,感觉挺精辟。
积累独到的知识(无法批量复制的),为社会提供他们需要的。
财富不是靠出卖时间获得,应该通过杠杆(资本、人力、一本万利的工具<写书等>)去积累。
选择一个可以长期从事的行业,寻找一批可以长期共事的人。
Seek wealth, not money or status. Wealth is having assets that earn while you sleep. Money is how we transfer time and wealth. Status is your place in the social hierarchy.
去寻求财富,而非金钱或地位。财富就是你拥有资产,而资产在你睡觉的时候都还在为你赚钱;金钱是我们转换时间和财富的工具;身份是你在社会等级体系里所处的位置。
Understand that ethical wealth creation is possible. If you secretly despise wealth, it will elude you.
要明白一件事:一个人完全可以不靠坑蒙拐骗站着赚取财富。如果你在暗中鄙视财富,那么财富也会躲着你。
Ignore people playing status games. They gain status by attacking people playing wealth creation games.
别去理会那些热衷于玩身份游戏的人,他们通过攻击那些创造财富的人以获得自己的身份。
You’re not going to get rich renting out your time. You must own equity — a piece of a business — to gain your financial freedom.
你不会通过出租自己的时间而变得富有。你必须拥有产权,也就是生意的一部分,以此才能赢得个人财务自由。
You will get rich by giving society what it wants but does not yet know how to get. At scale.
提供社会大众想要但是他们还不知道如何获取的东西,你就会因此而致富。但有一点:你必须规模化地供应社会。
Pick an industry where you can play long term games with long term people.
选择一个你可以长期从事的产业,寻找一批可以一起长期共事的人。
The Internet has massively broadened the possible space of careers. Most people haven’t figured this out yet.
互联网极大拓展了一个人职业生涯的可能性。绝大多数人对此毫无认知。
Play iterated games. All the returns in life, whether in wealth, relationships, or knowledge, come from compound interest.
玩就玩复利游戏。无论是财富,人际关系或者是知识,所有你人生里获得的回报,都来自复利。
Pick business partners with high intelligence, energy, and, above all, integrity.
在选择商业合作伙伴的时候,选择那些高智商、精力旺盛的家伙,但在这一切之上,他应该是个正直诚实的人。
Don’t partner with cynics and pessimists. Their beliefs are self-fulfilling.
不要和愤世嫉俗者和悲观主义者合作,因为他们会任由坏事发生,以此证明他们的负面看法是正确的。
Learn to sell. Learn to build. If you can do both, you will be unstoppable.
学会如何销售,学会如何创建。如果你同时能做到这两件事,你的成功将无可阻挡。
Arm yourself with specific knowledge, accountability, and leverage.
用独到知识,责任感和杠杆武装自己。
Specific knowledge is knowledge that you cannot be trained for. If society can train you, it can train someone else, and replace you.
独到知识是那种不可以通过培训而获得的知识。这是因为,如果这种知识可以经由培训而得,那么其他人同样也可以,并且以此取代你。
Specific knowledge is found by pursuing your genuine curiosity and passion rather than whatever is hot right now.
在真正的好奇心和热情驱使你前进的路上,你更有可能获得独到知识,而不是在追逐潮流热点的闻风起舞脚步里。
Building specific knowledge will feel like play to you but will look like work to others.
创建独到知识的过程对于你就像是在玩,而对于别人则像是工作。
When specific knowledge is taught, it’s through apprenticeships, not schools.
不能通过学校教育教会一个人独到知识,它只能通过学徒制口传身教。
Specific knowledge is often highly technical or creative. It cannot be outsourced or automated.
独到知识通常极富技术性和创造性,因此它不能被外包或自动实现。
Embrace accountability, and take business risks under your own name. Society will reward you with responsibility, equity, and leverage.
拥抱责任感,押上自己的声誉以承担商业风险。社会也会以责任,产权和杠杆作为回报。
The most accountable people have singular, public, and risky brands: Oprah, Trump, Kanye, Elon.
最具责任感的人都具有独一无二的、世人皆知的、敢于冒险的个性特征,如奥普拉、川普、坎耶、埃隆。
“Give me a lever long enough, and a place to stand, and I will move the earth.” — Archimedes
只要给我一根足够长的杠杆,一处可以立足的地方,我就能撬起地球。——阿基米德
Fortunes require leverage. Business leverage comes from capital, people, and products with no marginal cost of replication (code and media).
财富增长需要使用杠杆。商业杠杆有三个来源:1、资本;2、人力;3、复制起来边际成本为零的产品(如:代码和媒体)。
Capital means money. To raise money, apply your specific knowledge, with accountability, and show resulting good judgment.
资本的意思就是钱。想要融资,那就运用你的独到知识,配合你责任感,展示出你良好的判断力。
Labor means people working for you. It’s the oldest and most fought-over form of leverage. Labor leverage will impress your parents, but don’t waste your life chasing it.
人力指的就是为你干活的人,它是最古老也是争夺最激烈的杠杆。人力杠杆会让你父母因为你手下有许多人为你工作而感到骄傲,但你不要浪费生命去追求这一点。
Capital and labor are permissioned leverage. Everyone is chasing capital, but someone has to give it to you. Everyone is trying to lead, but someone has to follow you.
资本和劳动力是需要征得许可才能使用的杠杆。每个人都在追逐资本,但总得有个什么人给你才行;每个人都想要领导其它人,但总得有什么人愿意跟着你才行。
Code and media are permissionless leverage. They’re the leverage behind the newly rich. You can create software and media that works for you while you sleep.
代码和媒体是无需要许可即可使用的杠杆。它们是新贵人群背后的杠杆,你可以通过自己创建的软件和媒体,在睡觉时仍然为你干活。
An army of robots is freely available — it’s just packed in data centers for heat and space efficiency. Use it.
一支机器人军团已经集结待命,只是为了节约空间和热效能,它们被打包放进数据中心。去用吧。
If you can’t code, write books and blogs, record videos and podcasts.
如果你不会编程,那你还可以写书和博客,或者做视频或者音频节目。
Leverage is a force multiplier for your judgement.
杠杆能够成倍地放大你的判断力(所产生的效能)。
Judgement requires experience, but can be built faster by learning foundational skills.
判断力需要经验,但它可以通过学习基本技能的方法更快速地建立起来。
There is no skill called “business.” Avoid business magazines and business classes.
并不存在一种叫做“商业”的能力。尽量避开商业杂志和商业课程。
Study microeconomics, game theory, psychology, persuasion, ethics, mathematics, and computers.
去学习微观经济学、博弈论、心理学、说服术、伦理学、数学和计算机科学。
Reading is faster than listening. Doing is faster than watching.
读比听快,做比看快。
You should be too busy to “do coffee,” while still keeping an uncluttered calendar.
你应该忙得没有社交的时间才对,与此同时你应该始终保证日程安排井井有条。
Set and enforce an aspirational personal hourly rate. If fixing a problem will save less than your hourly rate, ignore it. If outsourcing a task will cost less than your hourly rate, outsource it.
你应该为自己设定一个有抱负的个人时薪数,并且坚持执行。如果解决一个问题所能节省下来的成本低于你的个人时薪,那就忽略这个问题好了;如果一项任务的外包成本低于你的个人时薪,就把它外包出去。
Work as hard as you can. Even though who you work with and what you work on are more important than how hard you work.
尽管你跟谁一起工作、做什么工作,要远比你的努力程度更加重要。但还是要倾尽全力去工作。
Become the best in the world at what you do. Keep redefining what you do until this is true.
你所做的事情,要努力做到世界最好。不断重新定义你在做什么,直到真的做到世界最好。
There are no get rich quick schemes. That’s just someone else getting rich off you.
这个世界上并没有快速赚钱致富的方法,如果你想要找寻这种方法,那它只会让别人从你身上赚钱致富。
Apply specific knowledge, with leverage, and eventually you will get what you deserve.
运用你的独到知识,配合上杠杆,最终你会得到你应该得到的东西。
When you’re finally wealthy, you’ll realize that it wasn’t what you were seeking in the first place. But that’s for another day.
终有一天当你变得富有,你会发现那一切并不是你最开始想要的东西。但是那就是另外一回事了。
财富就是你睡着觉,你的资产也在为你继续赚钱。这是一个越来越被广泛接受的定义。Naval Ravikant 是硅谷狂热的数字货币支持者,所以,他的话另有所指。从前后文来看,他所谓的资产并不等于是传统意义上的房产、股票、收藏,而是偏向于他反复提及的:软件和媒体。
出租时间概念,许多人理解为打工,认为打工就是出租自己的时间以换取金钱。其实并非如此,Naval 所指的出租时间概念,指的是一个人的财富增长,是否直接关系到他的时间。一个小卖部的老板,他并不为谁打工,但是他的财富增长需要他长时间守在店里,因此,他依然是出租时间换钱。但一个淘宝点卡店老板则不同,他的点卡销售是全自动的,不需要 24 小时守着,而且也不需要只做这一样生意。这就是Naval所谓互联网拓宽了个人职业生涯的一个例子。
equity 我翻译为产权,不是一个很好的翻法。但是 Naval 前文提到 assets,很明显,作为投资人他非常清楚地知道这两个字眼之间的区别。equity 无论是翻译为股票、权益或者是资产,原文说“You must own equity — a piece of a business — to gain your financial freedom.”,这是和出租时间概念做对应的。出租时间的人,在商业链条里作为生产资料出现,不拥有任何产权,也就无法通过商业行为获利,所以,我这里勉强翻译为产权。
specific knowledge 我翻译为独到知识,没有翻译为特定知识、专业知识或者是特殊知识。原因是在我的理解中,specific knowledge 不是书本知识,也不是学校教授的知识,更不可能在网上免费获取。一方面,它只能提供自己实践来获取;另一方面,它只能通过前人口耳相传。这种知识是做成一件事情的关键,属于知识体系中不共的那一部分。所以,我翻译为独到知识。
“Give me a lever long enough, and a place to stand, and I will move the earth.” — Archimedes 这话不像是阿基米德说的。更像是一次抬杠的结果:
1 | “给我一个支点,我就能撬起地球!” |
accountability 我本想翻译为“靠谱程度”,想想还是算了。
号称是“四十条语录”,但是我就找见了 39 条。
结合上下文看,Leverage 一词始终翻译为“杠杆”其实也不大对头。Naval 一再强调代码、博客、播客、视频节目,我觉得 Leverage 在他那里,有些时候应该相当于是个人影响力的代名词,或者可以简单理解为放大器。
其中有一个经常发 Java 相关的内容
今天看到一个稍微熟悉一点关于 FastJson 漏洞
窃以为Fastjson入门的最佳篇章非Mi1k7ea这个系列莫属,郑重推荐: Mi1k7ea。
共有5篇,从第3篇开始,成体系地由旧到新展示了1.2.25之后各版本的补丁绕过,
直至思路惊艳的1.2.47绕过方案及1.2.48的修补方案,相当完备。
可以看出此君是动手实践派、整理归纳派,要我说,新学东西时就得这套路,无它。
今天看了这两篇文章,不得不说对 Java 是异常的熟悉。
想做好安全,想必要对用的东西了如指掌,知道坑在哪里,怎么填坑。
后记:
很多时候大部分人都只关注自己工作职责内的那一亩三分地
其实很多时候横向观察一下会发现很多靓丽的风景
至今没有如此深入的去看过底层甚是愧疚
用最多的时间去做最正确的事情!
网页版:draw.io
桌面版:github 下载支持:Windows、macOS、Linux、Google Chrome OS
“I wish i had” vs “I’m glad i did”
人生会不会留下遗憾,在 20 年之后的这两句话中就能看出。
希望 20 年后的自己,能够很自豪的说:I’m glad i did.
这是一个只定义了标准的日志组件
1 |
|
常见配置:log4j.xml
1 |
|
《贫穷的本质》告诉我们,贫穷的本质是认知。其实很多时候真的是认知,方法论决定了一个人可以走多远。
《刻意练习》原地踏步的练习是没意义的,大众眼里一万小时定律基本上是错误的,需要的是有进步练习;
《学习之道》十个不错的方法:运用回想、知识组块、简化类比、方法交替、间隔重复、注意休息、心理对照、自我测试、保持专注、困难先行;
《如何阅读一本书》里面有提到主题阅读,不同的人对同一主题会有不同的看法,可以对比吸收;
《程序员的职业素养》有提到卡塔练习,提高我们的肌肉反应,让写代码像聊天打字一遍的顺畅;
早些天看到一篇不错的帖子
对我感触最深的就是:4
标题:如果高效学习有什么秘诀的话,那就都在这里了:)
1)不要完美主义!
2)不要过度“学习路径依赖”,学习要冲着自己的目标去。
3)不要迷信权威的“好”教材。
4)不要看不起“薄薄”的“傻”教材,这些你看不起的学习材料,可能是你入门某个领域的关键。
5)不要迷信单一教材。
6)实践!
7)debug非常非常重要。
8)量变到质变。
9)最后,一定要相信时间的力量。
参考:
2015 年刚毕业的我懵懵懂懂看书都想睡觉
很开心来到北京遇到了许多美好的人和事
受到环境的影响一路走来成长加速收获颇丰
从 2016 开始慢慢喜欢上了阅读
从开始看书就想睡觉到现在一个6层书架都放不下的纸质书
从开始的『kindle voyage』到现在的『kindle oasis』第三代
从开始的只是在北京地铁5号线看下电子书到现在有点时间就看
慢慢地养成了阅读的习惯,生活也没有那么无聊,工作慢慢步入正轨
非技术书籍喜欢用 kindle 看,技术书还是纸书比较合适翻阅
简单统计
2020 51本
2019 71本
2018 38本
2017 48本(2017以及之前)
Q:看书想睡觉怎么办?
A:先找有兴趣/好奇的主题
Q:看书记不住怎么办?
A:能不能记住无所谓,看的过程中有思考即可,好的书多看几遍
Q:哪来这么多时间?
A:合理安排时间,少浪费时间即可(通勤+早晚+中午,最少有3个小时时间)
读书使人充实,读史使人明智,读诗使人灵秀,
数学使人周密,科学使人深刻,伦理使人庄重,逻辑修辞学使人善辩
古人说开卷有益(无营养的除外)
通过阅读我们可以了解他人的经历
在他人的经历中我们可以得到经验
在他人的经验当中我们可以得到思想
一个人毕竟阅历有限,站在巨人的肩膀上你可以看的更高
科普性的书很多时候会恍然大悟
技术性的书能获得很多优秀的设计和实践以及学习新的技能
人文历史地里这些基本上是扩展知识面、提高个人综合素养、探索人生存在的意义
从我的书单(hisen.me/booklist/)当中可以看出
刚开始的时候基本上都是兴趣导向
俗话说兴趣是最好的老师,有些好书恨不得立马就看完,
接触很多人说看书就想睡觉,其实那不是我们的错,
是书没有写好,换一本就好了,如果还是不行,那就继续换。
当找到感兴趣的主题,看了一段时间之后
会发现阅读速度会有所提升,也会有很强的满足感
毕竟看的过程中总会有所收获,有所思考
兴趣是最好的老师,但是兴趣不能当饭吃
这个时候应该开始找一些通俗易懂的技术书,而不是那些很难啃的枕头
还是以有趣,通俗易懂为主
坚持一段时间,技术上也会有所收获
慢慢的就可以驰骋技术书籍的战场了
如果有时候发现看不下去了
那么就切换其它类型的书籍(我一般都是一本技术一本非技术)
建议看看《如何阅读一本书》
当通过阅读,名利双收的时候,我想没有几个人会不沉迷于阅读
想做到名利双收,需要养成好的习惯,挑选好的书籍
建议看看相关领域大佬分享的书单,或者直接咨询
书籍看多了实践也得跟上
有条件可以合志同道合的人一起看同一本书,看的时候多交流探讨,会有意想不到的效果
贫穷的本质是认知的差异
阅读、反馈、实践慢慢迭代认知
有长远的目标,不负韶华,坚持学习,努力提高
2019
1.【完成】换一份合适的工作
2.【完成】信息系统项目管理师
3.【完成】坚持阅读,数量质量超过2018
2020
1.羽毛球/骑行/等锻炼项目
2.通过一项含金量较高的考试项目
3.持续阅读/5本华章CS/其它不限
4.深入了解公司内部组件/知其所以然
2019预料之中夹着惊喜,正反馈激励我前行。
2020充实得度过每一天,有所追求有所进步。
自己想要什么样的生活?
最近几年一直在思考这两个问题
如今已经慢慢勾勒出了自己想要的生活
大概就是舒服的活着,向身边人学习,帮助他人成长,体现自己的社会价值(马斯洛需求层次理论的4~5之间)
想清楚自己想要什么样的生活之后
接下来就是给自己设定一系列目标
例如:长期目标、5年规划、3年规划
抛砖引玉:
全部书单
从17年开始阅读量稍微上来一点到如今已经走过了快3个年头
在阅读中观摩了不少他人的经历、接触了各种不同的思维方式、看了很多恍然大悟的见解、领略了技术的魅力
有一句话说的不错:书是一面镜子,折射出一个人的方方面面
翻越自己的书单,也能看到一个变化的过程,从兴趣开始,逐步转向个人提升以及对精神世界的追求
目前发现不少的书籍内容有部分的”重叠”,所以有些书还是看的比较快,有些书值得重复阅读,特别是技术书
2019 Top8 (非权威排行)
《贫穷的本质》
《重塑大脑,重塑人生》
《领域驱动设计》(系列)
《代码简洁之道:程序员的职业素养》
《枪炮、病菌与钢铁:人类社会的命运》
《可伸缩服务架构:框架与中间件》
《Java并发编程的艺术》
《深入理解Java虚拟机》
关键字:绿植、养鱼、骑行、羽毛球、辣椒
绿植和养鱼
看书累了/下班回家浇浇水赏赏鱼放空下自己挺好
偶尔还会收获成长的喜悦、以及把控感
骑行和羽毛球
运动方面实际行动比较多的今年是羽毛球
技术不咋地,野路子,打算2020培训下
骑行看季节看队友,春秋时节郊区遛遛挺好
辣椒
作为一个江西人,应该是无辣不欢的体质,无惧新型社交绝症
2019
起床:06:30
午休:20分钟
入睡:01:00
2020
起床:05:00
午休:20分钟
入睡:23:30
起床热身,煮早餐,基本上八点半左右出门
步行过程中耳机听互联网广播(目前是:36氪随身听)
地铁上耳机切换至音乐模式看书(kindle/纸书)
2020走养生路线,早睡早起!
中午看20分钟的书
早上看约1~3小时
晚上看书0~1小时
关注周围的事情,了解动态,吸取营养,输出影响力
包含全球200+国家和地区的信息
本列表属于之前有外国人整理过
利用有道翻译API翻译了国家名
涉及到全球的业务应该会用的上
1 | SET FOREIGN_KEY_CHECKS=0; |
1 | 1,AF,AFG,AFGHANISTAN,阿富汗,Afghanistan,4,93 |
题目要求:
Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
每一行都不能重复1-9
每一列都不能重复1-9
每个33的小格子(99分为9个3*3)不能重复
开始解题的时候可以一个大循环解决一个小问题,后续再把循环合并即可;
开始的时候我是写了三个双重for循环:
当发现每一步都可行之后,尝试着合并,以减少时间复杂度;
1 | public static boolean isValidSudoku(char[][] board) { |
可运行demo
github地址:ValidSudoku.java
做这件事的目的是为了了解一条数据库记录从创建到使用的一个情况;
查询分布时间计算方式采用Top Percentile方式,就是按一定排序的数据,前面xx%的最大值是多少;
TP999 1ms 代表某接口99.9%的响应都在1ms之内;
最终的目的也就是为了知道数据多久之后可以打入冷宫,使用廉价存储;
冷热数据分级处理有利于在性能和成本上达到一定的平衡;
如把内存缓存时间设置为tp90所处的时间,那么90%的数据都能快速返回,其它少量数据回源处理;
关键字
java格式化输出
java8
stream
parallelStream
分组
排序
DoubleSummaryStatistics数据分析
TP999
日志源数据预览
1 | 19-10-24.14:47:12.721 [THREAD-22000-18-T-17] INFO FacadeImpl - response yw:jiaoyi, orderId:123456, time:2019-10-24T14:46:44 |
yw | count | min(ms) | max(ms) | tp50(ms) | tp90(ms) | tp99(ms) | tp999(ms) |
---|---|---|---|---|---|---|---|
hisen | 1000 | 1 | 10000 | 20 | 60 | 90 | 130 |
hisen-1 | 200 | 2 | 16000 | 16 | 50 | 70 | 110 |
ps 输出是格式化的数据,并不是表格,可以通过:
world->粘贴输出文本->插入->表格->文本转换成表格->空格
即可完成文字到表格转换
这种过程可能比较low,但是也需要时间去处理,过程中还得配合linux命令等整合文本;
完整:github-CallerAnalyze.java
摘要如下:
1 | /** |
从中不难看出源头是黑卡、被利用的宽带账号、也有可能是路由器、物联网设备等;
运营商加强实名认证
宽带拨号频率限制
网络设备安全加固,关闭特殊权限端口,禁用弱密码
打击网络黑产交易,防止黑产规模化,产业化趋势;
蜜罐系统收集黑产IP
提供IP代理给黑产使用了解对方信息
医学专业已经建立起一套严密的辅导体系
软件行业建立一种包含学徒期、实习期、和长期指引的机制已是迫在眉睫
有人指导大多数人都可以快速的成长,节省很多走弯路的时间
当然,事在人为,只是说掌握了书中的那些要领,成为专业人员的几率更高,做更好的自己
如果从小学开始就一直有人引路并且自己也愿意跟着走的话,应该会很棒,现在也不晚,抓住时间就好
主要内容:
专业主义
学会说“不”,学会说“是”
编码的正确姿势
TDD
卡塔练习很重要,肌肉反应
验收测试(各方都一致同一的检验方式)
测试策略,自动化测试是趋势
时间管理,番茄工作法,注意力点数
预估的概念以及方法
压力,避免与面对
协作,学会与人交流
团队与项目,有凝聚力的团队战斗力强
软件开发如医生一样培训更佳
合适的工具事半功倍
豆瓣链接:《代码简洁之道:程序员的职业素养》
业务当中多处用到线程池进行异步处理;
为了得知线程池设置是否合理,故需要增加线程池监控;
常见的实现方式:
本文使用1的方式实现,主要是方便进行配置,可以托管多个任务;
1 | taskName:pool1-monitor. taskCount:820, completedTaskCount:820, largestPoolSize:30, poolSize:30, activeCount:0, corePoolSize:30, maximumPoolSize:50, queueSize:0 |
1 | package com.hisen.thread.monitor.threadpool; |
1 | <!-- ### 线程池监控 开始 ### --> |
这是一本人类大脑可塑性研究先驱与翘楚的故事书,正是让我们用触觉看到世界的巴赫-利塔这类先驱,使得我们正在成为来自地球的神。
这本书对我来讲还是很棒的,刷新了我对大脑的认知;
以前还停留在左右脑分工上,殊不知这是日本鬼子整出来的不严谨的概念;
看完书,感觉对个人技术、学习方面都有帮助,增加信心,因为之前错过了学校的大把学习时间;
运动和学习是互补的,前者产生新的神经干细胞,后者使它们的寿命延长;
这本书我是很推荐看的;
犹如最近看完的reids英文版文档;
每天看一点点,持续的刺激大脑相关区域,收获还是可以;
之前也咨询过英语比较好的同事;
反馈说目前想提高,就拿着领域内的文档硬看,坚持下来会有收获的;
每次看完书都会发个微博,避开朋友圈的尴尬,扩大散播范围,与更多的同好交流;
《重塑大脑,重塑人生》0822~0901
在持续不断噪声环境中长大的孩子都好动和吵闹,白噪声对大脑发育也有影响。
大脑重塑性和多巴胺有关,多巴胺可以使达成目标的那个行为的神经回路固话,连接得更紧。
有人说A片提供的是健康的快乐,使人从性的紧张中解放,其实A片提供的是上瘾、耐药性,他会降低快乐的感受。
所以学习没有一蹴而就之事,它是要下苦功的,我们的每一个经验都在改变大脑的连联结。
一定要指出一点:台湾地区一直受日本的影响,社会上流行着日本人说的右脑革命、右脑开发的谬论。婴儿发展初期,大脑两边很相似,只是后期专职分化了。因此绝对没有日本人七田真说的“右脑先发展到三岁才长出脑梁到左脑”
上学太早对身心情绪发展不好。
大脑每做一次不同的活动时,这些活动都改变了大脑的结构,每次练习都改变了大脑神经回路,使他更适合手边的作业,假如某些部件坏掉了,其他部件有时可以接管这项工作。(有时候头皮有反应、头胀、有点不舒服的感觉就是这个原因?)
大脑比我们能想象的还更开放。
大脑练习:找出弱点区域然后强化这个区域的功能。
一个认知能力的测试可以帮人们更加了解自己的大脑。
他们发现小猫的大脑有关键期:从3~8周,在这期间接受刺激才会正常地发展。
人的大脑也有关键期,例如语言发展有关键期,始于出生,终止于8岁到青春期之间。
当大脑在分配处理的资源时,大脑地图遵循的法则是竞争。资源不足时,大家会抢珍贵的资源,用进废退是唯一的法则。
当我们年龄越大,我们使用母语的频率就越高,母语占据我们语言地图的空间就越大,这也是因为我们的大脑有可塑性,我们学新语言才这么难。
使用双语的孩子两种语言的语音都共享一个大的语言地图。
但事实上,当我们学会一个坏习惯时,它占据了大脑地铁的空间,每次我们重复这个坏习惯,它又占据多点,让好习惯难以立足,这是为什么戒掉一个坏习惯比学它时难10倍,也是为什么同年的教育这么重要:最好一开始就教对,不要等到坏习惯已经做大有竞争优势了再去拔除它。
训练让神经元效率更高。
当动物有动机要学习时,大脑会弹性地对学习的需求作出反应。
一心多用不会使你的大脑地图产生永久改变。
多巴胺增强回馈报酬
乙酰胆碱帮助大脑加深印象,增强记忆。
都是噪声惹的祸:越靠近机场、公路的孩子智商越低。(持续的背景噪声对听觉皮质有很大的刺激)
把20~20000Hz的声音集合起来就是所谓的白噪声,昼夜播放白噪声会使人失去理智,进而发疯。
打开成年人的关键期:关键是要有激励,多巴胺、乙酰胆碱。
有些人只有在看色情影片时才会勃起,他们很少会想不举根他们爱看色情影片有关系。
恋人可以通过以下方式突破耐受性:浪漫的度个假,尝试新奇的活动,穿新的活动,想办法让对方惊喜。
我们的大脑就是演化来对新奇的东西起反应了。
当一个人成为父亲时,会分泌血管压缩素,会改变我们的大脑使你变得适合做父亲。
催产素通常是在草原田鼠交配时分泌(人性交也会),这使它们白头偕老,不会花心。
没有安全感的男人在做完爱后,会迅速离开,因为他害怕留下来,会被她影响;女人比较容易爱上与她性交的男人。
爱情的“去学习”也使我们改变了对自己形象的看法。在爱上一个很有权利欲、喜欢操控和贬低别人以抬高自我的人后,会失去所有的自我,变成自我怀疑、对自己没有信心的人。
《洛丽塔》
把猴子一只手神经切断,另外一只手绑起来,结果后面猴子用切断了神经的手进食。
“大量练习”(两周内集中训练)是为了引发启动大脑的可塑性改变,帮助大脑重新组织。
利用大脑可塑性停止忧虑、偏执想法、强迫性行为和坏习惯。
强迫症是:
你越做,就越想做;
越不做就越不会去想做。
幻肢是来自大脑的重组,脸和手的神经比较靠近。
有些女性的耳朵、锁骨和胸骨受到刺激会感到性兴奋,这三者的大脑地图都跟乳头的大脑地图紧邻;有些因阴茎癌而把阴茎切除的男性不但体验到幻阴茎,而且阴茎还会勃起。(性器官的大脑地图是在脚的旁边)
成功切除幻肢,通过镜子让患者看到幻肢,然后就会有信号传回大脑。
控制阀门理论,用电流刺激抑制痛的神经元,帮助疼痛阀门关闭。这个理论让西方科学家比较能接受针灸。
仅仅用想象和视觉错觉来重建构造大脑地图,没有打针、吃药、电流刺激,就将其痛苦、难以忍受的长期痛苦减轻或治愈了
经颅磁刺激可以无痛刺激脑神经。
实验表明,心智练习(靠想象)是用最少的实际练习来学习新肢体技术的有效方式。
用进废退的大脑需要外界刺激来维持它的地图。(心智下棋的例子最多)
专家不存储答案,但是存储重要的事实和策略,用长期记忆来解决问题是很多领域专家的共同特点。
从神经科学的观点来看,想象一个动作和执行其实没有很大差别。
一个人想象他在使用自己的肌肉可以增加肌肉的强度。
要发展一个新的回路,就必须阻挡或管制它的竞争者,即那些通常最常使用这个回路的信息。例如;想提高触觉等能力,就蒙住眼睛。
通常我们会重组我们的记忆以符合新的环境。
孩子要了解情绪,调节情绪,而产生社会化联结,必须在关键期经历几百次互动(母亲通过触觉 听觉 视觉 表现情绪)
两三岁以前靠内隐记忆,非语言的,例如骑自行车。
两三岁以后外显记忆开始发展,收集各种事实,事件,需要语言支持。
有几十个研究显示睡眠帮助我们巩固学习和记忆,而这影响大脑的可塑性改变。
婴儿时期的快速眼动睡眠是大脑可塑性发展的必要条件。
我们常常不自觉得被过去重要人际关系的魅影缠绕而影响现在的人际关系。
计算机听觉训练程序可以帮助老年人训练大脑。
不要因为小事而钻牛角尖,因为压力会产生皮质激素,而这会杀死海马回的神经细胞,海马回有助于短期记忆转为长期记忆
海马回中有神经干细胞。
在刺激丰富的环境中(球类、跑步机等各种玩具)生长的老鼠海马回容积增大15%,神经元数目增加了15%。长期丰富刺激环境对老年人的大脑神经再生有巨大影响。
为了使大脑保持最佳状态,我们必须学习新东西,而不是每天重复已经做的很熟练的事情,终身学习是很有必要的。
运动和学习是互补的,前者产生新的神经干细胞,后者使它们的寿命延长。
学一种新乐器、玩桥牌、打麻将、阅读和跳舞都可以帮助神经元的活化(需要全神贯注的活动才行)。
大脑最怕的就是人呆在相同的环境不动,这样会使大脑萎缩加速,单调不动会减少多巴胺的分泌,破坏维持大脑可塑性的注意力系统。
只有做自己想做的事情才会产生强烈的动机。
半个大脑也可以活的很好。
洗脑遵循了神经可塑性原则,可以用奖励、严厉惩罚以及大量训练的方式达到制约目的。
刚会走路的婴儿每天看电视的时间每增加一小时,他们在7岁时有注意力缺失问题的概率就会增加10%
]]>关键错误信息:
java.lang.RuntimeException: RESTeasy Provider Factory is null, do you have the ResteasyBootstrap listener configured?
java.lang.RuntimeException: Illegal to inject a message body into a singleton into public com.alibaba.fastjson.support.jaxrs.FastJsonProvider(java.lang.String)
resteasy:JBoss的一个开源项目,提供一套完整的框架帮助开发人员构建RESTful Web Service和RESTful Java应用程序。
fastjson:由阿里开发的一个性能很好的Java JSON 解析器和生成器。
引起错误的依赖
1 | <dependency> |
1 | 2019-08-03 11:51:22,491 ERROR - [RMI TCP Connection(2)-127.0.0.1] - Context initialization failed |
tomcat localhost long
1 | 八月 03, 2019 11:51:22 上午 org.apache.catalina.core.ApplicationContext log |
1 | <dependency> |
暂时不知道引起的原因,后期补充
]]>一个接口的关键指标应该就是响应速度,要想提高响应速度,结果在缓存中最好;
所以通过查询时间与缓存中订单的时间进行对比,得出缓存过期时间的最佳值,以平衡性能与成本;
近期在做日志分析,找到比较理想的一个缓存过期时间,使90%的查询都能被缓存覆盖;
ps:提取日志的关键是要日志规范,方便切割,才好算出调用时间(适用于暴利分析,而不是通过调用链等方式);
常见指标:TP50、TP90、TP99、TP999
正式解释:TP=Top Percentile,Top百分数,是一个统计学里的术语,与平均数、中位数都是一类;
通俗理解:TP99 100ms,99%的查询都能在100ms内返回;
计算方式:拿100次调用的耗时,排序,取第99个的耗时,这就是TP99的值;
具体的代码方式就是,先算出耗时,放入List,然后排序,按指定的下标取值即可;
1 | private void calTime(List<Long> timeDurations) { |
项目中看到有一个缓存接口存在多个实现类,
但是在代码中使用@Resource注解注入,
之前有了解过@Autowire @Resource的区别,
于是就尝试着搜索@@Resource,于是就有本文的总结了。
1.1.1 Spring开发;
1.1.2 按照type来注入;
1.2.1 JDK开发;
1.2.2 按照名称注入,若无,则按type来注入(未指定name的情况下);
感觉从业这么久以来,读取文件路径相关问题一直是一个痛
用的很少,之前也解决过相关的问题
但是得用这种路径
1 | src/test/resources/test/test.txt |
上面这种路径如果在代码中的话,src/test/resources是不会存在的,会出现问题
本次学到了一个新的方法,Class.getResourceAsStream();
需要的路径在资源文件夹下面即可,填写路径:/test/test.txt
打包最终的路径会在:WEB-INF/classes/test/test.txt
ps:因maven打包配置不同,最终resources资源文件夹下的路径是不同的,注意src的坑即可
1 | │ └── test |
1 | .class) (value = SpringJUnit4ClassRunner |
volatile是Java提供的一种轻量级的同步机制
保证变量的修改其它线程立马可见,解决部分并发问题
无法解决复合操作,例如 i++ i–这种操作
原因:i++操作分三步
volatile底层依靠指令重排序来实现内存可见性的
具体的规则如下
缓存是针对读多写少的场景典型的以空间换时间的操作
空间:内存
时间:读内存速度快(相对于读磁盘)
这个世界很多事情都符合 2/8 原则
把热点数据缓存起来就大大提高系统效率
先读缓存、再读DB
如果是并发读缓存失效,使用分布式锁只允许单次查询,其它等待,超时返回失败
cache 指的是删除『缓存』
db 指的是『更新/删除数据库』
删除缓存成功,更新数据库失败,不影响数据准确性。
如果在 cache 与 db 短暂的时间内
有访问查询动作(先查缓存,后查 db 并且设置缓存)
那么还缓存中还是会存在过期的数据
如果 db 成功,cache 失败,会导致数据不一致。
可以让 db cache 在一个事务,cache 失败回滚 db,保证一致性。
其实本质上就是个分布式事务问题
怎么保证两个操作同时成功/失败
通过本地事务 / 补偿机制 实现会比较好
解决方案:当查询到某数据不存在时,缓存假数据,例如:(key,key#);
缓存高可用(集群+主备)
循环一致性 Hash,节点组成一个环,如果一个节点挂了,顺着往下走;
常见参数:
垃圾回收器:
各个区大小比例建议
1 | # 活跃空间大小:Full GC后堆中老年代占用空间的大小 |
1.1 https://www.cnblogs.com/honey01/p/9475726.html
1.2 https://www.cnblogs.com/dolphin0520/p/3783345.html
2.1 https://tech.meituan.com/2017/12/29/jvm-optimize.html
除了runtimeException以外的异常,都属于checkedException。
CheckedException(受检异常):编译器会检查这类异常,需要强制捕获,否则无法编译通过。
UnCheckedException(非受检异常):编译器不会检查这类异常,可以不用捕获,可以编译通过。
受检:IOException、SQLException、NumberFormatException、IllegalArgumentException
非受检:OutOfMemoryError、StackOverflowError、NullPointerException、IndexOutOfBoundsException
点击查看所有jdk8 api文档
进去可以看到java.lang.RuntimeException下有很多子类异常
暂时写这些,日后再完善
]]>Apache Curator is a Java/JVM client library for Apache ZooKeeper, a distributed coordination service.
It includes a highlevel API framework and utilities to make using Apache ZooKeeper much easier and more reliable.
It also includes recipes for common use cases and extensions such as service discovery and a Java 8 asynchronous DSL.
特别说明:Guava is to Java What Curator is to ZooKeeper
后期补上自己的一些demo,其实官方文档已经介绍很全了
http://curator.apache.org/getting-started.html
了解这个客户端是在《从Paxos到Zookeeper:分布式一致性原理与实战》这本书里面看到的(书单)
Curator号称是世界上最好用的zk客户端,相比zkClinet来说拥有更好的封装
让我想起Redisson和Jedis的模样
昨天一个做移动端的前同事截图问我那些代码什么意思,用的就是Curator封装的分布式锁
相比于Redis分布式存在超时问题,zookeeper分布式锁利用临时节点可以避免
目前dubbo master上使用的是Curator 4.0.1
]]>Google公司的Bob lee开发的轻量级IoC容器,其特点是:
依赖
1 | <dependency> |
测试类
1 | public class HelloApp extends BaseServer { |
1 | java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V |
github有人遇到同样的问题:https://github.com/SeleniumHQ/selenium/issues/3880
把本地的guava版本由19.0改为21.0成功解决问题
]]>同步与异步主要是针对CPU来说的
阻塞与非阻塞主要是针对I/O来说的
本质上还是同步阻塞I/O
不过是在服务器把socket链接封装成Task提交给线程池处理
因为有队列,所以可以突破C:S=1:1的比例
通过把多个I/O的阻塞复用到一个阻塞上,从而使得系统在单线程情况下可以处理多个客户端的请求。
类似于linux的epoll、select
Selector,核心是通过Selector来轮询注册在其上的Channel
当发现有Channel就绪就返回Channel的选择键集合,进行I/O操作;
对比项 | 同步阻塞I/O(BIO) | 伪异步IO | 非阻塞I/O(NIO) | 异步I/O(AIO) |
---|---|---|---|---|
客户端个数:I/O线程数 | 1:1 | M:N(M>=N) | M:1 | M:O |
I/O类型(是否同步) | 同步 | 同步 | 同步(I/O多路复用) | 异步 |
I/O类型(是否阻塞) | 阻塞 | 阻塞 | 阻塞 | 非阻塞 |
API使用难度 | 简单 | 简单 | 非常复杂 | 复杂 |
调试难度 | 简单 | 简单 | 复杂 | 复杂 |
可靠性 | 非常差 | 差 | 高 | 高 |
吞吐量 | 低 | 中 | 高 | 高 |
脏读:在一个查询事务过程中,读到了其它事务没有提交的数据;
不可重复读:一个事务查询过程中,多次查询得到了不一致的结果,原因是:有别的更新事务提交了;
幻读:一个事务查询过程中,多次查询得到了不一致的结果,原因是:有别的删除事务/插入事务提交了;
name | 名称 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
---|---|---|---|---|---|
Read uncommitted | 读未提交 | Yes | Yes | Yes | No |
Read committed | 读已提交 | No | Yes | Yes | No |
Repeatable read | 可重复读 | No | No | Yes | No |
Serializable | 序列化 | No | No | No | Yes |
默认的隔离级别为:RR,原因:5.1之后版本,如果Binlogog开启语句级别,必须为RR,RC可能会导致Binlog数据错误(详情);
读未提交:每次都是读数据最新的版本(包括事务未提交的数据);
读已提交:MVCC控制;
可重复读:MVCC控制;
序列化:在读取的每一行上加锁,只能按顺序进行读写;
InnoDB引擎下的MVCC,是通过在每一行上增加两个隐藏列实现的;
每发生一个新的事务,系统版本都会递增;
当UPDATE数据的时候,都是先copy出来一行操作,不影响原表数据,提交之后才影响;
一个保存创建时间(非时间值,而是系统版本号);
一个保存删除时间(非时间值,而是系统版本号);
当前查询事务系统ID:5
结果条件:
1可以保证读取到的行,在事务开始之前就已经存在,要么是事务自身插入或者修改的;
2可以保证读取到的行,在事务开始之前未被删除;
为新插入的每一行保存当前系统版本号作为CREATE VERSION;
为删除的每一行保存当前系统版本号作为DELETE VERSION;
插入一行新的记录,保存当前系统版本号作为CREATE VERSION;
同事保存当前系统版本号到原来的行上作为DELETE VERSION;
1 | $ more sort.log | awk '{print $1}' | sort | uniq -c | sort -k1nr | head -3 |
more:一次读取少量的数据,避免一次性载入大文件,比cat好些
awk ‘{print $1}’:以awk默认的分隔符,并且打印第一列
sort:把上一步的结果按ASCII排序
uniq -c:如果重复那么计数,uniq命令可以组合很多其它参数
sort -k1nr:根据第一列的数据进行排序,n是按数值大小排序,r是倒序排序
head -3:显示前面三行数据
1 | $ cat sort.log |
实现命令
1 | find . -type f -size +100M -exec mv {} /tmp/ \; |
find 查找
. 当前目录
-type 文件类型:f 文件,d 目录
-size 文件大小:+100M +:大于 -:小于 空:等于
-exec 管道命令,将前面的查询结果传递给后面的命令
{} 指前面传递过来的的查询结果
\; 结束管道命令
这里讲述的是第一次出生的过程,即之前class没有被加载。
1.1.1.1 通过类的全限定名获取定义此类的二进制字节流(可以从zip包、网络、运行时动态生成);
1.1.1.2 将这个字节流所代表的静态存储结构转化为方法去运行时数据结构;
1.1.1.3 在内存(方法区)中生成一个代表这个类的java.lang.Class对象,作为方法区这个类各种数据访问的入口;
1.1.2.1.1 魔数是否以0xCAFEEBABE开头(咖啡宝贝)
1.1.2.1.2 主、次版本号是否在当前虚拟机处理的范围之内(不同的jdk版本编译出来的版本不一致,可向前兼容)
1.1.2.1.3 常量池是否有不被支持的类型(检查常量tag标志)
1.1.2.1.4 指向常量的各种索引值是否指向不存在或者不符合类型的常量
1.1.2.1.5 CONSTANT_Utf8_info型的常量中是否有不符合UTF-8编码的数据
1.1.2.1.6 Class文件中各个部分以及文件本身是否有被删除或者附加的其它信息
…
这些操作是为了确保Class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身安全
1.1.2.2.1 是否有父类(Object除外)
1.1.2.2.2 是否继续了不允许继承的类(被final修饰的)
1.1.2.2.3 如果当前不是抽象类,是否实现了其父类或接口中要求实现的所有方法
1.1.2.2.4 类中的字段、方法是否与父类产生矛盾(如覆盖父类final字段、不合法的重载)
这些操作是对字节码进行语义分析,确保符合Java语言规范要求
1.1.2.3.1 确保操作数栈的数据类型与指令代码序列能完美配合(反例:操作数栈为int,使用的时候按long加载)
1.1.2.3.2 确保跳转指令不会跳转到方法体以外的字节码指令上
1.1.2.3.3 确保方法体重点类型转换是有效的
这些操作主要是通过数据流和控制流分析,确定程序的语义是合法的、符合逻辑的。
JDK1.6之后有一个优化,利用StackMapTable来验证是否合法
1.1.2.4.1 符号引用中通过字符串描述的全限定名是否能找到对应的类
1.1.2.4.2 符号引用中的类、字段、方法是否可以被当前类访问
在将符号引用转化为直接引用的时候触发符号引用验证
1.1.3.1 仅为类变量分配内存,并且赋值为初始值,例如int为0(被static修饰的)
1.1.3.2 特殊情况,被final修饰的static变量会直接赋值为代码给定的值
准备阶段是正式为类变量分配内存并设置类变量初始值,这些变量所使用的内存都将在方法区中进行分配。
虚拟机将常量池中的符号引用替换为直接引用
符号引用:一组用来描述所引用目标的符号,所引用的目标不一定在内存中
直接引用:直接指向目标的指针、相对偏移量、能间接定位到句柄,直接引用的目标必须在内存中存在
<client>()方法:由编译器自动收集类中所有变量的赋值动作和静态语句块(static{}块)中的语句合并产生
按顺序收集。父类的此方法先执行,虚拟机会保证线程安全
真正开始执行类中定义的Java代码,
指针碰撞:内存规整的,中间指针划分已用、空闲,那么分配就是指针向空闲一方移动对象大小相等的距离
空闲列表:内存不规整,用列表维护一个可用内存地址,从列表中找出一个合适大小的空间分配给实例
<init>()方法:实例构造器
类的初始化是指类加载过程中的初始化阶段对类变量按照程序猿的意图进行赋值的过程;
类的实例化是指在类完全加载到内存中后创建对象的过程。
听候线程的指令,执行相关方法
可达性分析算法:从GC Root节点开始向下搜索,搜索所走过的引用链为引用链,当没有任何引用链时说明对象不可达
经历过两次不可达标记才会被标记为可回收
堆内存回收主要发生在堆上的新生代,为Minor GC,使用的是复制算法
新生代分为:Eden、to Survivor、from Survivor,后两者为Survivor,三者的比例为8:1:1
在Minor GC之前,to Survivor为空,对象存在:Eden、from Survivor
在Minor GC执行
Eden存活着的对象拷贝到to Survivor,同一时候对象年龄+1
from Survivor区中的幸存对象会考虑对象年龄
假设年龄没达到阈值,对象依旧拷贝到to survivor中
假设对象达到阈值那么将被移到老年代
复制阶段完毕后,Eden和from幸存区中仅仅保存死对象,能够视为清空
假设在复制过程中to幸存区被填满了,剩余的对象将被放到老年代
在Minor GC之后
from survivor和to survivor会调换一下名字,下次Minor GC时,to survivor变为from Survivor
目前写的不是太完善,有机会写的透彻明白一些。
]]>题意:一个数组有奇数个元素,其中只有一个元素出现一次,其它都出现了2次
方案A:利用hashMap存储出现的次数,然后遍历,复杂度O(3/2N)=O(N);
方案B:利用bitmap,根据数组元素的大小确定位置,做取反(0->1->0);
方案C:利用异或的特性快速找出,最简单,高效;
a^a=0
0^a=a
异或支持:交换率、结合率
因此:
a^b^c^b^c=a^(b^b)^(c^c)=a
1 | public static void main(String[] args) { |
这只是一个场景的妙用,实际当中很难遇到这种情况。
所以不管什么时候还是得多去刷题,没事刷几道,熟然生巧。
举个例子:快到吃饭的点了,你有两种选择:1)自己做,2)叫外卖
1.1.1 自己做你嫌麻烦,那就叫外卖,只管收外卖其它不关注(解耦);
1.1.2 自己做的不好吃,那厨师上门,厨师给你增强菜的味道(增强);
官方定义:对其他对象提供一种代理以控制对这个对象的访问。
1.2.1 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时我们就可以通过代理对类进行增强。
1.2.2 我们在使用RPC框架的时候,框架本身并不能提前知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用通过动态代理的方式来建立一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。
1.2.3 Spring的AOP机制就是采用动态代理的机制来实现切面编程。
2.1.1 JDK:只能代理接口
2.1.2 CGlib:直接代理类
完整代码:https://github.com/hisenyuan/IDEAPractice/tree/master/src/main/java/com/hisen/jdk/agent
1 | public static void main(String[] args) { |
http://www.cnblogs.com/puyangsky/p/6218925.html
https://blog.csdn.net/u011784767/article/details/78281384
今天中午一个朋友问我一个问题没来得及回,现在折腾一下;
问题:有一个包含以N个空格分割的字符串,求最大子串的长度,要求时间空间复杂度最优;
封装的代码比较复杂,目前来看不在么好分析时间复杂度和空间复杂度;
于是就直观得对比了一下时间;
1 | // output |
有时间再深入了解下StringTokenizer的源码
1 | String oriStr = "aa aa aaaa aaa a a a aa aa a"; |
1 | /** |
近几年一直在使用dubbo进行支付系统的开发;
作为国内比较受欢迎的一个SOA框架,Dubbo使用简单设计优雅;
里面用到的思想和技术,基本上涵盖大部分互联网公司用到的技术;
记得直属领导说过一句话,看完Dubbo他觉得设计者简直就是天才;
而且看完dubbo的源码,对他的影响很大,处处模仿dubbo的思想;
中文文档:用户文档、开发者指南、源码导读、运维管理
http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
用户手册(比较完整):
https://dubbo.gitbooks.io/dubbo-user-book/demos/routing-rule.html
官方博客:
http://dubbo.apache.org/zh-cn/blog/index.html
最后更新于2014年
https://javatar.iteye.com/
权重算法一般在路由里面用的比较多,分布式环境下对等的服务有多个,加权随机选出一个服务来调用;
可能还有其他方面的用途,下面的代码简单的实现了这个权重,本质上就用到了数组,随机下标;
1 | public static void main(String[] args) { |
github:show all code
1 | package com.hisen.algorithms; |
有时候上线会出现合错代码,比如功能,或者maven的pom文件;
人都不是十全十美的人,只要是人就会犯错
关键是要想办法去避免,只有工具才不犯错
所以尽量想办法利用工具来防止我们犯错,git来说有很多办法;
简单的命令,或者gitlab的compare报告;
每次上线之前,开发自己看一遍当前版本与线上版本的区别,确认每一个点都是正确的改动;
2.1 入口:工程首页 -> Repository -> Compare
2.2 选择:上一个版本,当前版本,点击Compare
2.2 结果:一次能看到两个版本的所有commit、改动点
1 | # 显示版本之间改动的文件名 |
1 | com.alibaba.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 14277263, max payload: 8388608, channel: NettyChannel [channel=[id: 0x12a13c8f, /172.0.0.1:49402 => /172.0.0.2:23888]] |
dubbo默认使用Netty传输协议
并且默认的大小限制为:默认为8M,即8388608
修改接口
出现这种情况是因为一个接口查某个表的所有数据(几万条)
一般这种接口肯定是需要分页的
更改配置信息
在dubbo.properties 中增加如下
1 | dubbo.protocol.dubbo.payload=11557050 |
理论原因:JVM在编译的时候能找到调用方法或静态变量所在的类,但在运行的时候找不到此类而引发的错误。
真实原因:(仅针对当前问题)
项目A依赖公共服务C-1.0.1版本
项目B依赖项目A,B中dependencyManagement强制指定C-1.0.0
此时编译可以通过,运行时如果有用的C的新版本功能就会会出现上述问题
解决办法:对项目B中C的版本升级,使用1.0.1
扩展阅读:
https://blog.csdn.net/qq_27576335/article/details/77102385
https://blog.csdn.net/jamesjxin/article/details/46606307
1 | select res.*, CONCAT(truncate((res.succ / res.`all`) * 100, 2), '%') as 'success rate' |
USER_NO | TYPE | all | succ | fail | other | success rate |
---|---|---|---|---|---|---|
456 | 10 | 1 | 0 | 0 | 1 | 0.00% |
123 | 10 | 29 | 23 | 0 | 6 | 79.31% |
1 | com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '2039-01-07 12:58:20.625' for column |
由于程序没有控制好,计算下一次更新时间失误,造成数值过大。
1 | update table_a |
以下是MySQL官方的说法,就是时间超过了范围。
1 | The TIMESTAMP data type is used for values that contain both date and time parts. |
想用docker搭建一个lnmp环境
使用这个脚本:
1 | https://github.com/buxiaomo/docker-compose/tree/master/lnmp |
执行命令之后报错
1 | docker-compose -f lnmp.yml up -d |
查看当前机器时间文件真实位置(/etc/localtime 这个路径是不让共享给docker的)
1 | ls -la /etc/localtime |
设置位置 :Docker -> Preferences… -> File Sharing
1 | docker-compose -f lnmp.yml up -d |
1 | public void process(MainTable mainTable) { |
但是刚刚看书上写出来的这个程序,居然不知道怎么在goland里面运行…
于是曲线救国,了解到打印输入的参数。
这断代码就是为了找出输入数据中的重复行
直接启动,不带参数,启动之后输入参数
1 | 参数0: /private/var/folders/lk/p8gbq87n6rvfndk7wlk23y8r0000gn/T/___go_build_dup2_go |
在命令行启动,带
1 | $ go run dup2.go 'hisen.txt' |
1 | package main |
id | name |
---|---|
1 | hisen |
2 | hisen |
3 | hisen |
4 | hisenyuan |
5 | hisenyuan |
删除重复的name,保留id最小的。
思路就是先找出重复数据,然后再找出需要保留的数据(重复中id最小的)
然后删除id不在需要保留的id中的所有数据
1 | delete |
1 | Could not initialize class io.jsonwebtoken.impl.DefaultJwtBuilder |
原因,因为jackson-databindb版本冲突,直接去掉了依赖
jwt必须依赖Jackson所以报错了
出错时候的配置
1 | <dependency> |
解决办法
1 | <dependency> |
具体的内容可以看下面的程序代码(虽然是抄书)
1 | package main |
1 | package main |
国庆假期没有什么安排,看了几部电影之后感觉蛮愧疚,又浪费了大把的时间
于是乎在书架上找了本决定看起来压力不那么大的书来看
这本书感觉整体上写的一般,可能定位就是通俗易懂吧
但是对于了解一些细节,还是很有帮助
由于目前待在创业公司,看到很多文字的时候还是很有感触的
如果你想成功,积极乐观地看待任何问题
1 | 马云在校教书,兼职创业:海博翻译社 |
1.1 使用Homebrew安装go环境(如果很慢,可以换个源)
1 | brew install go |
1.2 查看安装信息
1 | go env |
主要关注如下输出
1 | GOROOT="/usr/local/Cellar/go/1.10.3/libexec" # 安装目录 |
1.3 配置环境变量
1 | vi ~/.bash_profile # 没有的话会新建一个文件 |
输入如下内容,第一行是安装的目录,第三行是工作目录(可以改成自己喜欢的路径)
1 | GOROOT=/usr/local/Cellar/go/1.10.3/libexec |
1.4 让配置文件生效并且查看环境变量
1 | source ~/.bash_profile |
我是习惯了用jetbrains的idea
发现它家也有go语言的IDE GoLand
于是就去官网下载,安装,找个注册码,修改一下host防止注册码失效
这里就不再累赘了
买了一本《Go语言程序设计》
有些程序需要从标准输入获取信息,然后进行处理,例如dup2
运行之后不知道该肿么办,百度一番之后发现了方法
命令行:Ctl + D
GoLand:command + D
贴一段程序和运行的结果
1 | package main |
在支付业务当中,每一笔交易都得进行记账。
两种情况:
上面的两种情况各自都是在一个事物当中。
在同一个商户进行并发操作的时候,交易有成功有失败;
因为在各自的事物当中更新两条记录的信息,并且使用了for update(innodb引擎)
ß
在某一瞬间:成功的先锁A账户,失败的先锁了B记录
接下来就两个事物各自持有对方想要的资源,并且不释放已经占有的资源,就造成了死锁
在程序里面,更新两个账户的钱的时候,始终先更新ID更小的那条记录,那样不管多少个事务同时进来
都会按照固定的顺序去持有资源,比如先A再B,这样就不会出现各自持有对方想要的资源
1 | ID ACCOUNT |
每个事务都是先锁定A再锁定B,拿不到锁就一直等待
]]>最近在做app后台相关接口
自建通知中心目前不能很好的支持给APP推送消息
长连接可以保持推送速度,目前app中内嵌了H5,所以考虑使用websocket
之前没有接触过websocket,百度了一堆之后,页面上可以正常使用
但是没有发现可用使用Java后台进行消息的发送,于是乎就琢磨了一上午,解决了这个问题
现在把这个小工程分享给大家,少走点弯路==
ps:很多不能在后台发送消息,是因为缺少java的客户端
建立一个maven web 工程
添加依赖
1 | <dependency> |
websocket服务端主逻辑
为了实现简单的非群发操作,在连接websocket的时候,加上了一些get参数
例如:ws://localhost:8080/websocket?sendTo=hisen&method=methodSingle&user=hisenyuan
然后在后端判断,根据参数做出不同的动作
demo完整工程:https://github.com/hisenyuan/IDEAPractice/tree/master/websocket-demo
配置完Tomcat,即可使用,在java后台运行测试类(com.hisen.ws.client.ClientApp4Java)可发送消息到页面
1 | package com.hisen.ws.server; |
今天头给我们开会,说到团队对外沟通的问题。
谈到对外需要积极给人解决问题,而不是各种推脱,即使自己不知道,也可以给个眼神找到对的人。
继而谈到需要安排人轮流负责跟外部接洽
由于这个活呢,大伙儿认为不是什么好差事,那就抓阄决定吧
于是乎就感觉可以写一个简单的排班系统小bug,不过我这里只是提供一个简单的思路
主要的逻辑在这,当然并没有考虑数据持久化的问题
性能等其他的问题,纯粹是一个思路,用hashCode取模主要是打的比较散,很均匀
加上日期什么的,就一个排班表出来了。
1 | /** |
然后就搜了下自动连接远程服务,于是就发现了一个不错的脚步
整个设置过程还是比较顺畅,
操作步骤:
新建一个sh文件
1 | vi auto_ssh.sh |
输入如下内容,[lindex $argv 0] 这个为第一个参数的占位符
1 | !/usr/bin/expect |
复制脚本到bin下并且赋予执行权限
1 | sudo cp auto_ssh.sh /usr/local/bin/ |
设置
在iTerm2中Command+o呼出profile
1 | # 界面右下角,点击: |
fileChannelIn.read(byteBuffer) != -1
EOF = End Of File,其默认值就是-1
这是一个约定好的结束符,不是认为改变的
建议使用大文件进行测试,看效果比较明显
1 |
|
然后就在研究怎么方便的写博客
首先就是找了几款markdown编辑器,发现GitHub出品的Atom还不错
插件很丰富,然而下载了第一个terminal插件但是无效,一度折腾了很久
后来搜索了一下,发现这个插件很不错:platformio-ide-terminal
利用快捷键:control + 点(1左边那个)
就可以在当前界面呼出终端,而且是当前目录
也就是在_post目录下,写完了之后执行命令就上传了
还是很方便的。后续还需要慢慢熟悉更多的插件与工具
]]>1 | public void testCreate() { |
需求就是正常情况下能redirect到指定的页面
异常的情况下,能够返回JSON格式的错误信息
正常情况和异常情况都需要设置HTTP Code
1 | "/test", method = RequestMethod.POST) (value = |
在各种系统需要加签的时
一般都会把参与签名的数据以get请求参数拼接起来
并且要求有序,这个方法会比较方便
1 | public String getSortedStr(Map<String, String> unSortedStr) { |
1 | private Map<String,String> getMapData(String getStr){ |
对于get类字符串没有发现比较好的方法转换为map
]]>等号后面的为需要翻译的英文
1 | http://fanyi.youdao.com/openapi.do?keyfrom=xinlei&key=759115437&type=data&doctype=json&version=1.1&q=hisen |
把全世界200+国家和地区的名字翻译为英文,并且入库
1 | @Autowired |
插播:Java8 对List进行求和、分组、提取对象单个属性:https://www.jianshu.com/p/c71eaeaaf30c
下面的例子仅供参考
github:https://github.com/hisenyuan
1 | package com.hisen.collection.list.duplicate; |
1 | grep -r hisen ./ |
上面这条命令。直接查找当前目录下所有内容中包含 hisen 的文件
]]>1 | effective java # 2 |
Builder模式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,
得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,
来设置每个相关可选的参数,最后调用无参的build来生成不可变的对象。
完整代码+测试:github:完整代码+测试
1 | public class NutritionFacts { |
1 | 单元素的枚举类型已经成为实现Singleton的最佳方法 |
理由:
单例模式模式:完整代码+测试
主要代码:
1 | public class EnumSingleton { |
后面觉得挺好玩,也试了很多次,找过很多的教程。
搭建了一个zookeeper的集群(docker-compose)
然后当我需要搭建redis集群的时候,发现里面很多的概念还不是很懂
比如:volume network
然后加了docker的群,遇到了在以前idea群里面熟的一个人
花了一天的时间看完他传的一本书,昨天买的几本书晚上也到了。
(docker从入门到实践、java并发编程的艺术、effective java中文版 2)
这本书总体来说还行,就是过时了,还在用link,毕竟三年前的东西
有些例子也报错,主要是ruby相关的不行,提醒需要2.2以上的版本
1 | # 所有容器,不加-a只显示正在运行的;-1 列出最后一次运行的 |
1 | <!-- POI start --> |
1 | package com.hisen.jars.poi; |
1 | package com.hisen.jars.poi; |
利用redis操作的原子性,实现java 多线程并发的情况下实现计数器。
我本机测试多个线程操作之后,结果会出现一定的延迟,但是最终数字是ok的
应该是redis内部做了一个类似于队列的功能。
需要注意的是,得使用redis连接的线程池,不然会出现异常
这里有一个:JedisUtil 下面用到了
1 | package com.hisen.thread.count_click_by_redis; |
1 | package com.hisen.thread.count_click_by_redis; |
2.3 主线程 - 启动类
1 | package com.hisen.thread.count_click_by_redis; |
1 | echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list |
1 | # 打开管理页面功能 |
ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN.
帐号密码错误,建议使用2.3配置的账户,guest账户不靠谱
connection error
ip或者port错误,确认信息是否正确,虚拟机的话看看端口映射是否正常
1 | # 添加普通用户 |
1 | <dependency> |
1 | package com.hisen.jars.rabbitmq; |
1 | package com.hisen.jars.rabbitmq; |
这是一个菜鸟的脚本,执行命令应该是使用 & 连接,一个RUN命令搞定
1 | FROM ubuntu |
这条命令的输出结果能够让我们了解MySQL 优化器是如何执行
执行下面的SQL
1 | explain select * FROM book where name like '活%' |
得到下面的数据
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
编号 | 查询方式 | 表名 | 分区 | 连接方式 | 索引(可能) | 索引 | 索引长度 | 作用列 | 行数 | 百分比 | 额外 |
1 | SIMPLE | book | null | ALL | null | null | null | null | 114 | 11.11 | Using where |
1 | #创建个人信息表 |
###执行计划样例
1 | explain select zipcode,firstname,lastname from hisen_test_explain_people; |
###参考
]]>如有有天你想喝一瓶矿泉水,你可以去小区便利店,告诉老板你要买矿泉水,然后老板卖给你。
但是你可能需要想这下雨天怎么去小卖部?是否要带伞?去了之后是否有我想要的水等一系列问题。
解决这个问题:
是不是和Spring的做法很类似呢?Spring就是小卖部,你就是A对象,水就是B对象
第一:在Spring中声明一个类:A
第二:告诉Spring,A需要B
假设A是UserAction类,而B是UserService类
1 | <bean id="userService" class="org.leadfar.service.UserService"/> |
在Spring这个商店(工厂)中,有很多对象/服务:userService,documentService,orgService
也有很多会员:userAction等等
声明userAction需要userService即可,
Spring将通过你给它提供的通道主动把userService送上门来,因此UserAction的代码示例类似如下所示:
1 | package org.leadfar.web; |
在这段代码里面,你无需自己创建UserService对象(Spring作为背后无形的手,把UserService对象通过你定义的setUserService()方法把它主动送给了你,这就叫依赖注入!)
Spring依赖注入的实现技术是:动态代理
你只要做你关注的事情,其他的事情一概不管,让AOP帮你去做
你可以灵活组合各种杂七杂八的事情交给AOP去做,而不会干扰你关注的事情。
从Spring的角度看,AOP最大的用途就在于提供了事务管理的能力。
事务管理就是一个关注点,你的正事就是去访问数据库,而你不想管事务(太烦)
所以,Spring在你访问数据库之前,自动帮你开启事务,当你访问数据库结束之后,自动帮你提交/回滚事务!
通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);
将依赖关系作为构造子参数传入的做法称为构造子注入(Constructor Injection)。
其实当你真正花些时间读一读源码就知道它的一些技术实现其实是建立在一些最基本的技术之上而已;
例如:
zookeeper用来注册服务和进行负载均衡,哪一个服务由哪一个机器来提供必需让调用者知道,简单来说就是ip地址和服务名称的对应关系。
当然也可以 通过硬编码的方式把这种对应关系在调用方业务代码中实现,但是如果提供服务的机器挂掉调用者无法知晓,如果不更改代码会继续请求挂掉的机器提供服务。
zookeeper通过心跳机制可以检测挂掉的机器并将挂掉机器的ip和服务对应关系从列表中删除。至于支持高并发,简单来说就是横向扩展,在不更改代码 的情况通过添加机器来提高运算能力。
通过添加新的机器向zookeeper注册服务,服务的提供者多了能服务的客户就多了。
是管理中间层的工具,在业务层到数据仓库间有非常多服务的接入和服务提供者需要调度,dubbo提供一个框架解决这个问题。
注意这里的dubbo只是一个框架,至于你架子上放什么是完全取决于你的,就像一个汽车骨架,你需要配你的轮子引擎。
这个框架中要完成调度必须要有一个分布式的注册中心,储存所有服务的元数据,你可以用zk,也可以用别的,只是大家都用zk。
Dubbo的将注册中心进行抽象,是得它可以外接不同的存储媒介给注册中心提供服务,有ZooKeeper,Memcached,Redis等。
引入了ZooKeeper作为存储媒介,也就把ZooKeeper的特性引进来。
参考:https://www.cnblogs.com/qiumingcheng/p/5259892.html
####例子
1 | //Hashtable |
####性能对比
使用ExecutorService来并发运行5个线程,每个线程添加/获取500K个元素。
从数据可以看出,ConcurrentHashMap效率最高
代码如下
1 | package com.hisen.collection.map; |
http://blog.csdn.net/u014044812/article/details/51004754
http://blog.csdn.net/bitcarmanlee/article/details/51004767 (含流程图)
]]>√:可能会出现
×:为不会出现
name | 名称 | 级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
Read uncommitted | 读未提交 | 1 | √ | √ | √ |
Read committed | 读提交 | 2 | × | √ | √ |
Repeatable read | 重复读 | 3 | × | × | √ |
Serializable | 序列化 | 4 | × | × | × |
Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE.
Oracle 默认的事务隔离级别为: READ COMMITED
Mysql 支持 4 中事务隔离级别.
Mysql 默认的事务隔离级别为: REPEATABLE READ
最多有两棵子树的有序树,称为二叉树。二叉树是一种特殊的树。
这里规定二叉树的根结点的层次为1。
n0 = n2 + 1
https://github.com/hisenyuan/btree
1 | package com.hisen.interview.tiger20171110.btree; |
1 | package com.hisen.interview.tiger20171110.btree; |
1 | #删除原有的规则 |
带来的问题就是:
内网的数据库,在启动之后。时不时会自动断开,导致影响正常工作,时不时得重启程序才能测试
在idea中也可以,而且还比较高级,哈哈
idea -> 右上角 -> Edit -> Column Selection Mode -> 移动光标到你想要弄的行
完事在重复一次,就可以退出列编辑模式
]]>其中一个最小的公倍数是他们的最小公倍数
同样地,若干个整数公有的倍数中最小的正整数称为它们的最小公倍数
求最小公倍数算法:
最小公倍数=两整数的乘积÷最大公约数
求最大公约数算法:
有两整数a和b:
例如:求27和15的最大公约数过程为
因此,3即为最大公约数
代码实现:
1 | /** |
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
中文 | 英文 | 解释 |
---|---|---|
镜像 | Docker Images | Docker 镜像是用于创建 Docker 容器的模板。 |
容器 | Docker Container | 容器是独立运行的一个或一组应用。 |
客户端 | Docker Client | Docker 客户端通过命令行或者其他工具使用 Docker API (查看API) 与 Docker 的守护进程通信。 |
主机 | Docker Host | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
仓库 | Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(查看镜像) 提供了庞大的镜像集合供使用。 |
工具 | Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
1 | hisen@hisen-pc:~$ wget -qO- https://get.docker.com/ | sh |
1 | #启动 |
1 | #启动某个指定的镜像,运行hello-world |
docker run ubuntu:15.10 /bin/echo “Hello world”
参数 | 解释 |
---|---|
docker | Docker 的二进制执行文件 |
run | 与前面的 docker 组合来运行一个容器 |
ubuntu:15.10 | 指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。 |
/bin/echo “Hello world” | 在启动的容器里执行的命令 |
以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果。
1 | root@hisen-pc:/home/hisen# docker run -i -t ubuntu:15.10 /bin/bash |
-t:在新容器内指定一个伪终端或终端。
-i:允许你对容器内的标准输入 (STDIN) 进行交互。
1 | root@hisen-pc:/home/hisen# docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done" |
后台启动完成,会返回一串容器的ID
1 | ##查看是否有容器启动 |
CONTAINER ID:容器ID(这里是:==8c2a84327360==)
NAMES:自动分配的容器名称
1 | ## 查看上面那个ID的容器的log |
docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。
1 | ## 调出帮助 |
运行一个 Python Flask 应用 来搭建一个web应用
1 | ## -d:让容器在后台运行。 |
0.0.0.0:32768->5000/tcp
docker使用的端口5000
映射到本地端口32768
本地可以访问:127.0.0.1:32768
1 | ## 访问:http://localhost:32768/ |
1 | ## 带上 -f 参数,动态输出日志 |
1 | ## top后面是跟着id或者name |
1 | ## 会输出一大串JSON形式的字符串 |
1 | docker stop 0d68d3d4baf6 |
1 | root@hisen-pc:/home/hisen# docker images |
1 | ## 获取一个镜像 |
新建一个配置文件:Dockerfile,并添加内容
每个指令都会在镜像上创建一个新的层
每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么
1 | root@hisen-pc:/home/hisen# vi Dockerfile |
以前没有遇到过,就搜索了一下,找了一会给找到了
1 | select to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss ff') from dual; |
输出:年-月-日 时:分:秒 微秒
1 | 2017-9-24 10:38:27 129368 |
很少问题是搜索引擎找不到的,学会如何描述问题才是关键
]]>布隆过滤器的作用是加快判定一个元素是否在集合中出现的方法。
因为其主要是过滤掉了大部分元素间的精确匹配,故称为过滤器。
其应用场景为需要频繁在一个海量的集合中查找某个元素是否存在。
并且通常,这个值不在集合中。
比如Google chrome用此方法检查一个url是否在恶意url库中。
假设有一些字符串,假设有一个字符串a,要在集合B中查找其是否在集合B中。最笨的方法是遍历集合B中的每个元素bi,精确匹配a是否等于bi。若集合B中有N个元素,则最坏情况下需要执行N次精确匹配。
一个改进的方法是将a和B中每个字符串按照特定规则映射为数字,称为hash值。规则可以任意设置。比如取各字符串的首字母和尾字母的编码之乘积,取奇数个字符的编码执行异或,等。将比较字符串问题变成一个比较数字的问题。比较字符串需要从头到尾比较,而数字的比较会快很多。
需要注意的是,当两个字符串相同时,采用相同的映射规则得到的数字一定相同。但当两个字符串不同时,得到的字符串不一定不同。所以,当我们发现两个字符串的hash值相同时,两个字符串不一定相同,所以需要进一步去精确匹配两个字符串是否相同。但采用hash值方法已经能够过滤掉一部分以前需要精确匹配的计算量。仅当hash值相同(假设hash值通过字符串首尾字母计算得来,则当两个字符串首尾字母相同时hash值相同)时才去比较字符串本身。若选择hash值合理,则性能将大幅提高。
布隆过滤器通过将一个字符串使用多个不同的hash值计算方法,映射为多个不同的hash值,当所有这些hash值完全相同时,才认为两个字符串相同。从而进一步降低了放生hash值相同的可能性,从而进一步提高了过滤的性能。
1 | package com.hisen.interview; |
1 | wget --no-check-certificate -O shadowsocks-libev-debian.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-libev-debian.sh |
默认设置:
1 | 服务器端口:自己设定(如不设定,默认为 8989) |
管理命令:
1 | 启动:/etc/init.d/shadowsocks start |
修改配置文件(端口、密码)
1 | vi /etc/shadowsocks-libe/config.json |
卸载命令
1 | ./shadowsocks-libev-debian.sh uninstall |
在使用的过程中发现,搜索框历史、提交svn后的消息提示乱码
最后发现是由于更改了idea界面的字体,字体对中文支持不佳导致
解决办法:更改为支持中文的字体(比如:微软雅黑 Microsoft YaHei)
设置路径:Settings -> Appearance & Behavior -> UI Options -> override default fonts by
选择何时的字体即可,也可以把勾勾去掉,使用默认的。
]]>有时间多学习
多线程基础 & 进阶
系统架构
JWT(json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。
欲加密的字符:hisen
加密后的字符:(分三段)
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoiXCJoaXNlblwiIiwiZXhwIjoxNTAyOTY0Mjk2fQ.gzg4JEm8Z-GoU9eNaNll9I1wQQ0cEAbZC9OBUjAAQqI |
完整的头部,json格式:
1 | { |
然后对头部进行base64加密,构成第一段:
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 |
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
1 | { |
然后对头部进行base64加密,构成第二段:
1 | eyJwYXlsb2FkIjoiXCJoaXNlblwiIiwiZXhwIjoxNTAyOTY0Mjk2fQ |
jwt的第三部分是一个签证信息,这个签证信息由三部分组成
1 | gzg4JEm8Z-GoU9eNaNll9I1wQQ0cEAbZC9OBUjAAQqI |
密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和验证,所以需要保护好。
1 | <dependency> |
1 | // 加密,传入一个对象和有效期 |
1 | // 解密,传入一个加密后的token字符串和解密后的类型 |
基于JWT token认证 | JSON Web Tokens | java-jwt 3.2.0 | demo
JWT官方网站:https://jwt.io/
]]>1 | #开启远程登录 |
比如:debian、ubuntu、deepin等
1 | apt-cache search package #搜索包(相当于yum list | grep pkg) |
这个系列的文章还不错
版权归原作者所有
感觉文章不错,一边看一边实践。
有时候从头开始学习也会有另一番风味。
兴趣是最好的老师,唯有坚持才是实现梦想的唯一途径。
]]>背景:一年工作经验,做电子政务
判断字符串是否含有此Url:www.jd.com
11.
1 | Long l1 = new Long(1024L); |
Spring自定义注解、拦截器相关
一个数组 i[] = [-1000 ~ 1000] 中的任意一些数字,求乘积最大的三个数。
1 | /** |
1M 等于多少个1
1 |
|
写出两种单例模式
1 | //懒汉模式 |
判断字符串是否含有此Url:www.jd.com
1 |
|
http://www.jd.com/...username=... 为了防止sql注入,怎么写正则。
1 | 将包含有 单引号('),分号(;) 和 注释符号(--)的语句给替换掉来防止SQL注入 |
mybatis如何防止sql注入
1 | 防护一:sql语句不在使用${}表达式,改为#{} |
mybatis使用变量时怎么表示
1 | #与$的区别 |
使用js遍历json数据
1 | var data=[{name:"a",age:12},{name:"b",age:11},{name:"c",age:13},{name:"d",age:14}]; |
分割线
1 | //插入代码 |
删除线
引用,只能写在一行
1 | markdown语法 |
原来并不用安装spark什么的这些东西
这样就不会那么繁琐,门槛也低了点
具体过程如下
pom.xml添加依赖
1 | <dependency> |
编写java代码
1 | package com.hisen.spark; |
运行main方法:结果:Lines with a: 11146, lines with b: 10760
1 | C:\hisenwork\soft\jdk8\bin\java -Dspark.master=local "-javaagent:C:\hisenwork\IntelliJ IDEA 2017.1.1\lib\idea_rt.jar=59366:C:\hisenwork\IntelliJ IDEA 2017.1.1\bin" -Dfile.encoding=UTF-8 -classpath C:\hisenwork\soft\jdk8\jre\lib\charsets.jar;C:\hisenwork\soft\jdk8\jre\lib\deploy.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\access-bridge-64.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\cldrdata.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\dnsns.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\jaccess.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\jfxrt.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\localedata.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\nashorn.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunec.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunjce_provider.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunmscapi.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunpkcs11.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\zipfs.jar;C:\hisenwork\soft\jdk8\jre\lib\javaws.jar;C:\hisenwork\soft\jdk8\jre\lib\jce.jar;C:\hisenwork\soft\jdk8\jre\lib\jfr.jar;C:\hisenwork\soft\jdk8\jre\lib\jfxswt.jar;C:\hisenwork\soft\jdk8\jre\lib\jsse.jar;C:\hisenwork\soft\jdk8\jre\lib\management-agent.jar;C:\hisenwork\soft\jdk8\jre\lib\plugin.jar;C:\hisenwork\soft\jdk8\jre\lib\resources.jar;C:\hisenwork\soft\jdk8\jre\lib\rt.jar;C:\hisenwork\code\rmitec\SparkTest\target\classes;C:\hisenwork\soft\maven\org\apache\spark\spark-core_2.11\2.0.1\spark-core_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\apache\avro\avro-mapred\1.7.7\avro-mapred-1.7.7-hadoop2.jar;C:\hisenwork\soft\maven\org\apache\avro\avro-ipc\1.7.7\avro-ipc-1.7.7.jar;C:\hisenwork\soft\maven\org\apache\avro\avro\1.7.7\avro-1.7.7.jar;C:\hisenwork\soft\maven\org\apache\avro\avro-ipc\1.7.7\avro-ipc-1.7.7-tests.jar;C:\hisenwork\soft\maven\org\codehaus\jackson\jackson-core-asl\1.9.13\jackson-core-asl-1.9.13.jar;C:\hisenwork\soft\maven\org\codehaus\jackson\jackson-mapper-asl\1.9.13\jackson-mapper-asl-1.9.13.jar;C:\hisenwork\soft\maven\com\twitter\chill_2.11\0.8.0\chill_2.11-0.8.0.jar;C:\hisenwork\soft\maven\com\esotericsoftware\kryo-shaded\3.0.3\kryo-shaded-3.0.3.jar;C:\hisenwork\soft\maven\com\esotericsoftware\minlog\1.3.0\minlog-1.3.0.jar;C:\hisenwork\soft\maven\org\objenesis\objenesis\2.1\objenesis-2.1.jar;C:\hisenwork\soft\maven\com\twitter\chill-java\0.8.0\chill-java-0.8.0.jar;C:\hisenwork\soft\maven\org\apache\xbean\xbean-asm5-shaded\4.4\xbean-asm5-shaded-4.4.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-client\2.2.0\hadoop-client-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-common\2.2.0\hadoop-common-2.2.0.jar;C:\hisenwork\soft\maven\commons-cli\commons-cli\1.2\commons-cli-1.2.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-math\2.1\commons-math-2.1.jar;C:\hisenwork\soft\maven\xmlenc\xmlenc\0.52\xmlenc-0.52.jar;C:\hisenwork\soft\maven\commons-io\commons-io\2.1\commons-io-2.1.jar;C:\hisenwork\soft\maven\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\hisenwork\soft\maven\commons-configuration\commons-configuration\1.6\commons-configuration-1.6.jar;C:\hisenwork\soft\maven\commons-collections\commons-collections\3.2.1\commons-collections-3.2.1.jar;C:\hisenwork\soft\maven\commons-digester\commons-digester\1.8\commons-digester-1.8.jar;C:\hisenwork\soft\maven\commons-beanutils\commons-beanutils\1.7.0\commons-beanutils-1.7.0.jar;C:\hisenwork\soft\maven\commons-beanutils\commons-beanutils-core\1.8.0\commons-beanutils-core-1.8.0.jar;C:\hisenwork\soft\maven\com\google\protobuf\protobuf-java\2.5.0\protobuf-java-2.5.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-auth\2.2.0\hadoop-auth-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-compress\1.4.1\commons-compress-1.4.1.jar;C:\hisenwork\soft\maven\org\tukaani\xz\1.0\xz-1.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-hdfs\2.2.0\hadoop-hdfs-2.2.0.jar;C:\hisenwork\soft\maven\org\mortbay\jetty\jetty-util\6.1.26\jetty-util-6.1.26.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-app\2.2.0\hadoop-mapreduce-client-app-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-common\2.2.0\hadoop-mapreduce-client-common-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-client\2.2.0\hadoop-yarn-client-2.2.0.jar;C:\hisenwork\soft\maven\com\google\inject\guice\3.0\guice-3.0.jar;C:\hisenwork\soft\maven\javax\inject\javax.inject\1\javax.inject-1.jar;C:\hisenwork\soft\maven\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-server-common\2.2.0\hadoop-yarn-server-common-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-shuffle\2.2.0\hadoop-mapreduce-client-shuffle-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-api\2.2.0\hadoop-yarn-api-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-core\2.2.0\hadoop-mapreduce-client-core-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-common\2.2.0\hadoop-yarn-common-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-jobclient\2.2.0\hadoop-mapreduce-client-jobclient-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-annotations\2.2.0\hadoop-annotations-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-launcher_2.11\2.0.1\spark-launcher_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-network-common_2.11\2.0.1\spark-network-common_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\fusesource\leveldbjni\leveldbjni-all\1.8\leveldbjni-all-1.8.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\core\jackson-annotations\2.6.5\jackson-annotations-2.6.5.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-network-shuffle_2.11\2.0.1\spark-network-shuffle_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-unsafe_2.11\2.0.1\spark-unsafe_2.11-2.0.1.jar;C:\hisenwork\soft\maven\net\java\dev\jets3t\jets3t\0.7.1\jets3t-0.7.1.jar;C:\hisenwork\soft\maven\commons-codec\commons-codec\1.3\commons-codec-1.3.jar;C:\hisenwork\soft\maven\commons-httpclient\commons-httpclient\3.1\commons-httpclient-3.1.jar;C:\hisenwork\soft\maven\org\apache\curator\curator-recipes\2.4.0\curator-recipes-2.4.0.jar;C:\hisenwork\soft\maven\org\apache\curator\curator-framework\2.4.0\curator-framework-2.4.0.jar;C:\hisenwork\soft\maven\org\apache\curator\curator-client\2.4.0\curator-client-2.4.0.jar;C:\hisenwork\soft\maven\org\apache\zookeeper\zookeeper\3.4.5\zookeeper-3.4.5.jar;C:\hisenwork\soft\maven\com\google\guava\guava\14.0.1\guava-14.0.1.jar;C:\hisenwork\soft\maven\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-math3\3.4.1\commons-math3-3.4.1.jar;C:\hisenwork\soft\maven\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;C:\hisenwork\soft\maven\org\slf4j\slf4j-api\1.7.16\slf4j-api-1.7.16.jar;C:\hisenwork\soft\maven\org\slf4j\jul-to-slf4j\1.7.16\jul-to-slf4j-1.7.16.jar;C:\hisenwork\soft\maven\org\slf4j\jcl-over-slf4j\1.7.16\jcl-over-slf4j-1.7.16.jar;C:\hisenwork\soft\maven\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\hisenwork\soft\maven\org\slf4j\slf4j-log4j12\1.7.16\slf4j-log4j12-1.7.16.jar;C:\hisenwork\soft\maven\com\ning\compress-lzf\1.0.3\compress-lzf-1.0.3.jar;C:\hisenwork\soft\maven\org\xerial\snappy\snappy-java\1.1.2.6\snappy-java-1.1.2.6.jar;C:\hisenwork\soft\maven\net\jpountz\lz4\lz4\1.3.0\lz4-1.3.0.jar;C:\hisenwork\soft\maven\org\roaringbitmap\RoaringBitmap\0.5.11\RoaringBitmap-0.5.11.jar;C:\hisenwork\soft\maven\commons-net\commons-net\2.2\commons-net-2.2.jar;C:\hisenwork\soft\maven\org\scala-lang\scala-library\2.11.8\scala-library-2.11.8.jar;C:\hisenwork\soft\maven\org\json4s\json4s-jackson_2.11\3.2.11\json4s-jackson_2.11-3.2.11.jar;C:\hisenwork\soft\maven\org\json4s\json4s-core_2.11\3.2.11\json4s-core_2.11-3.2.11.jar;C:\hisenwork\soft\maven\org\json4s\json4s-ast_2.11\3.2.11\json4s-ast_2.11-3.2.11.jar;C:\hisenwork\soft\maven\com\thoughtworks\paranamer\paranamer\2.6\paranamer-2.6.jar;C:\hisenwork\soft\maven\org\scala-lang\scalap\2.11.0\scalap-2.11.0.jar;C:\hisenwork\soft\maven\org\scala-lang\scala-compiler\2.11.0\scala-compiler-2.11.0.jar;C:\hisenwork\soft\maven\org\scala-lang\modules\scala-parser-combinators_2.11\1.0.1\scala-parser-combinators_2.11-1.0.1.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\core\jersey-client\2.22.2\jersey-client-2.22.2.jar;C:\hisenwork\soft\maven\javax\ws\rs\javax.ws.rs-api\2.0.1\javax.ws.rs-api-2.0.1.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\hk2-api\2.4.0-b34\hk2-api-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\hk2-utils\2.4.0-b34\hk2-utils-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\external\aopalliance-repackaged\2.4.0-b34\aopalliance-repackaged-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\external\javax.inject\2.4.0-b34\javax.inject-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\hk2-locator\2.4.0-b34\hk2-locator-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\javassist\javassist\3.18.1-GA\javassist-3.18.1-GA.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\core\jersey-common\2.22.2\jersey-common-2.22.2.jar;C:\hisenwork\soft\maven\javax\annotation\javax.annotation-api\1.2\javax.annotation-api-1.2.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\bundles\repackaged\jersey-guava\2.22.2\jersey-guava-2.22.2.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\osgi-resource-locator\1.0.1\osgi-resource-locator-1.0.1.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\core\jersey-server\2.22.2\jersey-server-2.22.2.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\media\jersey-media-jaxb\2.22.2\jersey-media-jaxb-2.22.2.jar;C:\hisenwork\soft\maven\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\containers\jersey-container-servlet\2.22.2\jersey-container-servlet-2.22.2.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\containers\jersey-container-servlet-core\2.22.2\jersey-container-servlet-core-2.22.2.jar;C:\hisenwork\soft\maven\org\apache\mesos\mesos\0.21.1\mesos-0.21.1-shaded-protobuf.jar;C:\hisenwork\soft\maven\io\netty\netty-all\4.0.29.Final\netty-all-4.0.29.Final.jar;C:\hisenwork\soft\maven\io\netty\netty\3.8.0.Final\netty-3.8.0.Final.jar;C:\hisenwork\soft\maven\com\clearspring\analytics\stream\2.7.0\stream-2.7.0.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-core\3.1.2\metrics-core-3.1.2.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-jvm\3.1.2\metrics-jvm-3.1.2.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-json\3.1.2\metrics-json-3.1.2.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-graphite\3.1.2\metrics-graphite-3.1.2.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\core\jackson-databind\2.6.5\jackson-databind-2.6.5.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\core\jackson-core\2.6.5\jackson-core-2.6.5.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\module\jackson-module-scala_2.11\2.6.5\jackson-module-scala_2.11-2.6.5.jar;C:\hisenwork\soft\maven\org\scala-lang\scala-reflect\2.11.7\scala-reflect-2.11.7.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\module\jackson-module-paranamer\2.6.5\jackson-module-paranamer-2.6.5.jar;C:\hisenwork\soft\maven\org\apache\ivy\ivy\2.4.0\ivy-2.4.0.jar;C:\hisenwork\soft\maven\oro\oro\2.0.8\oro-2.0.8.jar;C:\hisenwork\soft\maven\net\razorvine\pyrolite\4.9\pyrolite-4.9.jar;C:\hisenwork\soft\maven\net\sf\py4j\py4j\0.10.3\py4j-0.10.3.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-tags_2.11\2.0.1\spark-tags_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\scalatest\scalatest_2.11\2.2.6\scalatest_2.11-2.2.6.jar;C:\hisenwork\soft\maven\org\scala-lang\modules\scala-xml_2.11\1.0.2\scala-xml_2.11-1.0.2.jar;C:\hisenwork\soft\maven\org\spark-project\spark\unused\1.0.0\unused-1.0.0.jar com.hisen.spark.SimpleApp |
在resources文件夹下新建:generatorConfig.xml
内容如下:注意修改包名等信息
1 | <?xml version="1.0" encoding="UTF-8"?> |
在pom.xml中添加如下内容:plugins节点内
1 | <build> |
在idea调出mavenProject界面,选择plugins,找到mybatis-generator,双击即可
]]>1 | org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.hisen.dao.UserMapper.insert |
使用mybatis生成插件,产生的mapper,由于路径不对移动了一下mapper.java文件
所以造成mapper.xml里面的namespace错误,无法映射
所以把namespace改为正确的即可
例如:
mapper.UserMapper
改为
com.hisen.dao.UserMapper
]]>Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。
队列是一种数据结构.它有两个基本操作:在队列尾部加入一个元素,和从队列头部移除一个元素(注意不要弄混队列的头部和尾部)就是说,队列以一种先进先出的方式管理数据,如果你试图向一个 已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具。工作者线程可以定期地把中间结果存到阻塞队列中而其他工作者线程把中间结果取出并在将来修改它们。队列会自动平衡负载。如果第一个线程集运行得比第二个慢,则第二个 线程集在等待结果时就会阻塞。如果第一个线程集运行得快,那么它将等待第二个线程集赶上来。下表显示了jdk1.5中的阻塞队列的操作:
排序方法 | 平均情况 | 最好情况 |
---|---|---|
add | 增加一个元素 | 如果队列已满,则抛出一个IllegalSlabEepeplian异常 |
remove | 移除并返回队列头部的元素 | 如果队列为空,则抛出一个NoSuchElementException异常 |
element | 返回队列头部的元素 | 如果队列为空,则抛出一个NoSuchElementException异常 |
offer | 添加一个元素并返回true | 如果队列已满,则返回false |
poll | 移除并返问队列头部的元素 | 如果队列为空,则返回null |
peek | 返回队列头部的元素 | 如果队列为空,则返回null |
put | 返回队列头部的元素 | 如果队列满,则阻塞 |
take | 返回队列头部的元素 | 如果队列为空,则阻塞 |
介绍:
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。
实现高性能,高可用,可伸缩和最终一致性架构。
是大型分布式系统不可缺少的中间件。
目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。
场景:异步处理、应用解耦、流量削锋、日志处理
以上就是关于为什么要使用队列的大致说明
参考:
]]>maven项目,启动tomcat的时候报错:
1 | No MyBatis mapper was found in '[com.hisen.dao]' package |
这是由于把mybatis的mapper配置文件放在了java代码的目录下
1 | ├── java |
这是因为mapper文件的路径问题:maven在打包的时候默认是认为src/main/java目录下只有java源代码,不会管xml文件。
Java 项目分为两个部分,一个是源码,一个是资源,在使用maven等构建工具时,
默认会将源码编译后再加上资源目录的文件放到target目录下作为最后运行的文件(可以是war,jar,或者目录)。
有时为了方便,我们会在src/main/java源码目录下放了资源文件,例如mybatis的mapper文件,方便我们编程时展开查看。
这时,我们需要设置编译时也将这些配置文件放到target目录下,否则最后的target目录式没有这些文件的。
在项目的pom文件里面配置,让maven也从src/main/java目录下读取xml配置文件
1 | <build> |
如果是把mapper文件什么的放在resources目录下
但是为了分类建了不同的文件夹,也需要修改配置文件,不然会读取不到
1 | <build> |
前面的例子我们使用的视图技术主要是JSP。JSP的优点是它是Java EE容器的一部分,几乎所有java EE服务器都支持JSP。缺点就是它在视图表现方面的功能很少,假如我们想迭代一个数组之类的,只能使用<% %>来包括Java语句进行。虽然有标准标签库(JSTL)的补足,但是使用仍然不太方便。另外JSP只能在Java EE容器中使用,如果我们希望渲染电子邮件之类的,JSP就无能为力了。
Java生态圈广泛,自然有很多视图框架,除了JSP之外,还有Freemarker、Velocity、Thymeleaf等很多框架。Thymeleaf的优点是它是基于HTML的,即使视图没有渲染成功,也是一个标准的HTML页面。因此它的可读性很不错,也可以作为设计原型来使用。而且它是完全独立于java ee容器的,意味着我们可以在任何需要渲染HTML的地方使用Thymeleaf。
Thymeleaf也提供了spring的支持,我们可以非常方便的在Spring配置文件中声明Thymeleaf Beans,然后用它们渲染视图。
引入依赖
1 | <!--thymeleaf模版 spring4.x--> |
配置ViewResolver(在spring的xml文件里)
1 | <!-- 配置ViewResolver 使用:thymeleaf 模版引擎--> |
接下来就可以直接使用了,跟之前的jsp没有什么不同
1 | "/listpageplug/{start}", method = RequestMethod.GET) (value = |
到这里就改造完了,接下来就是Thymeleaf的各种用法了
这里举一个循环遍历的例子,后台返回了books对象集合
1 | <!--判断是否为空--> |
工具类 就是封装平常用的方法,不需要你重复造轮子,节省开发人员时间,提高工作效率。谷歌作为大公司,当然会从日常的工作中提取中很多高效率的方法出来。所以就诞生了Guava。
高效设计良好的API,被Google的开发者设计,实现和使用
遵循高效的java语法实践
使代码更刻度,简洁,简单
节约时间,资源,提高生产力 Guava工程
包含了若干被Google的 Java项目广泛依赖 的核心库,例如:
1 | public class CommonUsage { |
部分摘自:点击查看
]]>表A:id,name
表B:id,其他,name(新增字段)
A,B表通过id关联,要把A的name给对应的B的name
以前也没有写过这种update语句
1 | update 表名 set 字段名=字段值 where 条件 |
之前在linux shell用过tree命令感觉不错
发现Git Bash也可以实现,于是就记录一下
下载地址:点击前往
下载文件: Binaries Zip
解压文件:bin目录下找到tree.exe
把这个放到git安装目录下后的路径:C:\Program Files\Git\usr\bin\tree.exe
1 | hisen@HiSEN MINGW64 /c/code/SpringBootCLI/myapp |
它支持运行Groovy脚本,这也就意味着你可以使用类似Java的语法,但不用写很多的模板代码。
Spring Boot不一定非要配合CLI使用,但它绝对是Spring应用取得进展的最快方式.
1 | spring --version |
文件名称:HelloController.groovy
文件内容:
1 | @RestController |
运行程序:cmd进入文件所在文件夹,执行:spring run HelloController.groovy
提醒:Resolving dependencies第一次初始化时间会久一点,耐心等待
1 | spring run HelloController.groovy |
之后在浏览器中输入:http://localhost:8080/
就能看到:Hello World
]]>1 | hisen@ubuntu:~$ mongo |
看倒数第二行,应该是权限的问题,于是
1 | hisen@ubuntu:~$ sudo chown -R hisen /home/hisen/.mongorc.js |
完美解决,用户权限的问题。
]]>顺便用博客记录下,mongodb系列应该会有几篇记录
本篇具体代码:SampleMongoTestNo1.java
1、环境介绍
mongodb安装教程:点击查看
1 | DataBase:MongoDB V 3.2 |
2、初始化连接
1 | private Mongo mg = null; |
3、关闭连接
1 | @After |
1 | /** |
最终指向的都是Reimage Repair,网址zh.reimageplus.com
网上一查,貌似因为插件被污染的原因
我关闭chrome所有的插件,一个一个排查,最后找到了一个插件出问题
本来还想去举报,发现这个插件被下架了
问题排查
1 | 右上角菜单按钮 ---更多工具 --- 扩展程序 --- 关闭所有插件 |
只有自己设置的非root的帐号和密码
但是又要用root密码怎么办呢?
1 | hisen@ubuntu-1:~$ sudo passwd |
上面输入的密码就是你的root密码
检测一下
1 | hisen@ubuntu-1:~$ su |
通过,至此结束
]]>如果还未安装jdk、maven建议查看教程:点击查看
1 | git clone -b develop https://github.com/apache/incubator-rocketmq.git |
Start Name Server
1 | nohup sh bin/mqnamesrv & |
Start Broker
1 | nohup sh bin/mqbroker -n localhost:9876 & |
Send & Receive Messages
1 | Before sending/receiving messages, we need to tell clients the location of name servers. RocketMQ provides multiple ways to achieve this. For simplicity, we use environment variable NAMESRV_ADDR |
Shutdown Servers
1 | sh bin/mqshutdown broker |
今天人家给我个powerdesigner设计好的表
要我去间数据库,直接复制出来去oracle执行,结果报错。
在comment附近,如果把comment去掉则可以正确执行
最后找到罪魁祸首:powerdesigner没有设置对数据库
解决办法,在powerdesigner页面
1 | database-->change curren DBMS |
上面是设置你需要的数据库
下面是为更改前的数据库
]]>在Oracle 11g中,Oracle 又增加了2个查询:pivot(行转列) 和unpivot(列转行)
下面是在mysql中的操作:
1 | mysql> select * from test; |
1 | declare |
这个错误出现的原因有的说是因为jdbc配置文件写错了
正确的写法是:
1 | c3p0.driverClass=com.mysql.jdbc.Driver |
而不是
1 | driver=com.mysql.jdbc.Driver |
但是我遇到的不是如此
后来发现是因为maven出问题了,jar包没有加载进项目
这是在starkoverflow上看到的回答
1 | In my case it was problem that c3p0-0.9.2.1.jar file was not copied by maven into src/main/webapp/web-inf/libs |
最后maven重新install之后就解决了
]]>FileInputStream方式获取出来的大小会有差异
NIO与IO的对比详见:NIOCopy.java
1 | /** |
官网地址:http://try.redis.io/
我的redis是安装在linux虚拟机,通过Xshell操作,显示可能跟cmd不大一样
但是操作都是一样的
1 | #连接redis客户端 |
1 | mysql> describe post; |
1 | mysql> alter table post add index index_post_title (title); |
1 | mysql> drop index index_post_title on post; |
1 | mysql> select count(title) from post group by title; |
现在想把第一行的数据导入到第二行,具体如下
1 | mysql> describe employees; |
employees数据库中的employees表有30万数据
我想把这个数据导出到另外一个数据库hisen中的employee表中
1 | mysql> create table hisen.employee as( |
这种操作是针对所有字段都导出的情形,创建表跟插入数据合二为一
如果导出部分字段或者有其他限制条件写sql即可
这应该是最简单的方法~
]]>Data URL是在本地直接绘制图片,不是从服务器加载,所以节省了HTTP连接,起到加速网页的作用。
也无法获取到图片在服务器上的真实地址
注意:本方法适合于小图片,大图片就不要考虑了,另外IE8以下浏览器不支持这种方法。
用这种方法会加重客户端的CPU和内存负担,总之有利有弊。
前台代码:
1 | <%@ page import="com.hisen.image.ShowImageByBase64" %><%-- |
后台代码:
1 | package com.hisen.image; |
但是之前完全没有把独显用上,在英伟达的设置里选择使用显卡感觉也没有用
后来找到在BIOS里面设置,貌似管用,联想的机子可以看看
其他的机子应该也差不多
连接:http://iknow.lenovo.com/detail/dc_102471.html
1 | 6. IdeaPad Z380/Z480/Z580/U310/U410,Lenovo G480A/V370A/V470A/V570A |
我的默认居然是:UMA Only
]]>以下是安装步骤
1 | #下载(官网为:http://mama.indstate.edu/users/ice/tree/) |
最简单的使用方法,在目录下输入:tree
使用效果
1 | hisen@ubuntu:~/dl$ tree |
使用参数
1 | tree命令行参数: |
1 | https://api.github.com/ |
这里介绍两个api
1 | #获取个人信息 |
key | 含义 | value |
---|---|---|
login | 登录名称 | hisen-yuan |
id | 数字编号 | 16789019 |
avatar_url | 头像地址 | https://avatars1.githubusercontent.com/u/16789019?v=3 |
name | 用户昵称 | hisenyuan |
blog | 博客地址 | http://hisen.me |
location | 地理位置 | China |
bio | 个人说明 | Java R & D |
public_repos | 仓库个数 | 11 |
created_at | 创建时间 | 2016-01-20 01:57:15Z |
updated_at | 最后更新 | 2017-04-20 14:03:27Z |
1 | #获取项目信息 |
key | 含义 | value |
---|---|---|
id | 项目编号 | 88646378 |
name | 项目名称 | dubbo |
html_url | 项目地址 | https://github.com/hisen-yuan/dubbo |
created_at | 创建时间 | 2017-04-18T16:21:57Z |
updated_at | 更新时间 | 2017-04-18T16:23:16Z |
pushed_at | 提交时间 | 2017-04-19T02:33:33Z |
size | 项目大小 | 6514 |
language | 编程语言 | Java |
1 | current_user_url: "https://api.github.com/user", |
sh:代表上海市场
sz:代表深圳市场
后面是加上股票代码,这是因为上海和深圳的股票代码有重复的
1 | http://hq.sinajs.cn/list=sh600877 |
返回的信息
1 | var hq_str_sh600877="中国嘉陵,6.340,6.400,6.360,6.470,6.210,6.340,6.350,15012913,95227966.000,56500,6.340,12100,6.330,16100,6.320,17500,6.310,47400,6.300,13600,6.350,11300,6.360,32400,6.370,39100,6.380,41200,6.390,2017-04-27,15:00:00,00"; |
有效信息为引号里面的数据
下面的数字代表分割数组后所在的下标
下面是数据字段对应的含义
位置 | 含义 | 测试数据 |
---|---|---|
0 | 股票名字 | 中国嘉陵 |
1 | 今日开盘价 | 6.340 |
2 | 昨日收盘价 | 6.400 |
3 | 当前价格 | 6.360 |
4 | 今日最高价 | 6.470 |
5 | 今日最低价 | 6.210 |
6 | 买一报价 | 6.340 |
7 | 卖一报价 | 6.350 |
8 | 成交数量(百股) | 15012913 |
9 | 成交金额(元) | 95227966.000 |
10 | 买一数量(股) | 56500 |
11 | 买一报价 | 6.340 |
12 | 买二数量(股) | 12100 |
13 | 买二报价 | 6.330 |
14 | 买三数量(股) | 16100 |
15 | 买三报价 | 6.320 |
16 | 买四数量(股) | 17500 |
17 | 买四报价 | 6.310 |
18 | 买五数量(股) | 47400 |
19 | 买五报价 | 6.300 |
20 | 卖一数量(股) | 13600 |
21 | 卖一报价 | 6.350 |
22 | 卖二数量(股) | 11300 |
23 | 卖二报价 | 6.360 |
24 | 卖三数量(股) | 32400 |
25 | 卖三报价 | 6.370 |
26 | 卖四数量(股) | 39100 |
27 | 卖四报价 | 6.380 |
28 | 卖五数量(股) | 41200 |
29 | 卖五报价 | 6.390 |
30 | 当前日期 | 2017-04-27 |
31 | 当前时间 | 15:00:00 |
32 | 未知 | 00 |
表示如果cola为空,赋值为0
在mysql中的具体实现如下,
1 | mysql> describe book; |
真实的目录结构如下:
1 | C:\1\hisenyuan\build.png |
压缩包的目录结构如下:
1 | build.png |
1 | package com.hisen.utils; |
只是简单的让例子在IntelliJ IDEA跑起来
目前是最新的版本:2.5.4-SNAPSHOT
本文档更新时间:2017年04月19日01:08:02
参考链接:ubuntu apt-get安装zookeeper
导出项目之后,配置一下tomcat,添加dubbo-admin:war到tomcat中
项目github地址:https://github.com/hisen-yuan/dubbo
默认账号:root
默认密码:root
1 | /dubbo/dubbo-demo/dubbo-demo-consumer/src/test/resources/dubbo.properties |
1 | #dubbo.registry.address=multicast://224.5.6.7:1234 |
1 | /dubbo/dubbo-demo/dubbo-demo-provider/src/test/resources/dubbo.properties |
1 | #dubbo.registry.address=multicast://224.5.6.7:1234 |
即可在后台看到有服务在运行
]]>需求是:查找出每个年级,年纪最大的人的名字。
个人的思维只停留在
1 | mysql> select name, max(age),grade from stu group by grade; |
折腾了一会自己不知道怎么解决,后来倒是解决了。
具体过程如下:
1 | mysql> describe stu; |
Debian 7.7、8.0
CentOS 7.X
Fedora 20、21、22
OracleLinux 6、7
安装方法:
1 | curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh - |
1 | sudo apt-get update |
安装docker包
1 | sudo apt-get install \ |
添加docker官方GPG秘钥,留意最后那个符号也要复制
1 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
1 | sudo add-apt-repository \ |
再次更新源
1 | sudo apt-get update |
安装docker-ce
1 | sudo apt-get install docker-ce |
在阿里云申请一个账号,打开连接https://cr.console.aliyun.com/#/accelerator
拷贝您的专属加速器地址(每个人专属的,登陆需要密码),然后
1 | vi /etc/systemd/system/multi-user.target.wants/docker.service |
可以看到如下内容
1 | [Service] |
找到 ExecStart= 这一行,在这行最后添加加速器地址 –registry-mirror=<加速器地址>
如:ExecStart=/usr/bin/dockerd -H fd:// –registry-mirror=https://xxxxxx.mirror.aliyuncs.com
1 | $ sudo systemctl daemon-reload |
至此docker安装及国内加速器都好了,开始你的docker之旅吧。
1 | sudo docker run hello-world |
看到如下信息
1 | hisen@ubuntu:/$ sudo docker run hello-world |
到此就圆满结束
最后给个彩蛋,阿里云一键安装脚本,执行下面命令即可安装最新版docker
1 | curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh - |
2017年04月12日 18:26:37 星期三
1 | <!DOCTYPE html> |
1 | yourPath\maven-3.3.9\conf\settings.xml |
找到里面的,添加镜像即可
1 | <mirrors> |
这里写的是被镜像的ID
如果写成:* (星号)
所有的请求都会到这个镜像上,包括各种本地库
注意:千万不要配成
否则内网的仓库或者你配的镜像里面没有一下jar包的时候不会去别的地方搜索
1 | <!--阿里云:速度挺快--> |
1 | select * |
第二种:
1 | select * |
第三种:
1 | select * |
redis.clients.jedis.exceptions.JedisConnectionException:java.net.SocketException:Software caused connection abort: recv failed
我是windows上java运行,然后redis是在虚拟机的,通过映射访问
编辑redis配置文件:
1 | sudo vi /etc/redis/redis.conf |
找到
1 | bind 127.0.0.1 |
改成
1 | bind 0.0.0.0 |
改完之后重启redis
1 | service redis restart |
即可。这跟mysql一样,允许任何ip连接!
]]>里面含有几十万条数据。
找了好久也没有找到比较匹配的题目
就找了个匹配度比较高的题来练习,如果你还没有导入Employees Sample Database
请参考:点击导入Employees
本次操作在Xshell中完成,也就是mysql命令行。
1 | #登陆数据库 |
建议看看输出的结果自己写下sql,不要单纯的复制粘贴。
1 | #1.查找整个职员表的所有内容。 |
tail -f test.log
你会看到屏幕不断有内容被打印出来. 这时候中断第一个进程Ctrl-C,
cat -n hisen.log | grep ‘907’
在文件当中查找指定的内容,这里是查询:907
linux 如何显示一个文件的某几行(中间几行)
从第3000行开始,显示1000行。即显示3000~3999行
1 | cat filename | tail -n +3000 | head -n 1000 |
显示1000行到3000行
1 | cat filename| head -n 3000 | tail -n +1000 |
*注意两种方法的顺序
分解:
用sed命令
sed -n ‘5,10p’ filename 这样你就可以只查看文件的第5行到第10行。
例:cat mylog.log | tail -n 1000 #输出mylog.log 文件最后一千行
cat主要有三大功能:
1.一次显示整个文件。$ cat filename
2.从键盘创建一个文件。$ cat > filename
只能创建新文件,不能编辑已有文件.
3.将几个文件合并为一个文件: $cat file1 file2 > file
参数:
-n 或 –number 由 1 开始对所有输出的行数编号
-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 –show-nonprinting
例:
把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里
1 | cat -n textfile1 > textfile2 |
把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。
1 | cat -b textfile1 textfile2 >> textfile3 |
把test.txt文件扔进垃圾箱,赋空值test.txt
1 | cat /dev/null > /etc/test.txt |
注意:>意思是创建,>>是追加。千万不要弄混了。
tac (反向列示)
tac 是将 cat 反写过来,所以他的功能就跟 cat 相反, cat 是由第一行到最后一行连续显示在萤幕上,
而 tac 则是由最后一行到第一行反向在萤幕上显示出来!
在Linux中echo命令用来在标准输出上显示一段字符,比如:
echo “the echo command test!”
这个就会输出“the echo command test!”这一行文字!
echo “the echo command test!”>a.sh
这个就会在a.sh文件中输出“the echo command test!”这一行文字!
该命令的一般格式为: echo [ -n ] 字符串其中选项n表示输出文字后不换行;字符串能加引号,也能不加引号。
用echo命令输出加引号的字符串时,将字符串原样输出;
用echo命令输出不加引号的字符串时,将字符串中的各个单词作为字符串输出,各字符串之间用一个空格分割。
1 | #在整个文件搜索含有907的内容 |
也有自己安装插件,然后写js的,麻烦
后来找到两个插件,安装之后就搞定了
感谢开发的作者!!!
记得要在站点根目录执行下面的安装操作
1.安装 hexo-generator-search
1 | npm install hexo-generator-searchdb --save |
2.安装 hexo-generator-searchdb
1 | npm install hexo-generator-searchdb --save |
编辑站点文件_config.yml,添加以下内容开启搜索
1 | search: |
编辑主题文件_config.yml,启用本地搜索功能:
# Local searchlocal_search: enable: true
第一次点击搜索的时候反应会比较慢
因为是要加载一个xml文件
]]>据我观察这个数据库可视化工具很不错,基于java
以各种驱动来连接数据库,也就是说java支持的数据库都可以用他连接
挺好用的,免费!!!
安装之后新建连接,选择你要链接的数据库,配置一下就好了。
1 | #Shift + Home选中当前光标到行首 |
官网介绍:Employees Sample Database
表名 | 中文 |
---|---|
department | 部门表 |
dept_emp | 部门员工任职期表(按部门&时期) |
dept_manager | 部门经理任职期表(按时期) |
employees | 员工详情表 |
salaries | 员工薪资表(按时期) |
title | 员工职称表(按时期) |
一、导入数据库操作过程
1 | #ubuntu apt-get 安装的mysql默认的配置文件 |
练习题:点击查看练习题
]]>1 | hisen@ubuntu:/var/lib$ su |
解决办法
1 | hisen@ubuntu:$ sudo passwd root |
重新设置一下密码即可,我这边装的时候设置的用户是:hisen
刚刚重新设置的密码就是你装系统的时候设置的用户密码。
]]>保存一份google code的xml,链接有最新的
intellij-java-google-style.xml
设置方法如下:Setting -> Editor -> Code Stytle -> Java
最后一步就选择你存放之前保存的xml
然后就大功告成,来个对比
前
1 | package com.hisen.json; |
后
1 | package com.hisen.json; |
相对地把一个汉字所占的位置称为”全角”。在汉字输入时,系统提供”半角”和”全角”两种不同的输入状态,
但是对于英文字母、符号和数字这些通用字符就不同于汉字,在半角状态它们被作为英文字符处理;
而在全角状态,它们又可作为中文字符处理。
半角和全角切换方法:单击输入法工具条上的按钮或按键盘上的Shift+Space键来切换。
1、全角:指一个字符占用两个标准字符位置。
汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都是全角字符。一般的系统命令是不用全角字符的,只是在作文字处理时才会使用全角字符。
2、半角:指一字符占用一个标准的字符位置。
通常的英文字母、数字键、符号键都是半角的,半角的显示内码都是一个字节。在系统内部,以上三种字符是作为基本代码处理的,所以用户输入命令和参数时一般都使用半角。
3、全角与半角各在什么情况下使用?
全角占两个字节,半角占一个字节。
半角全角主要是针对标点符号来说的,全角标点占两个字节,半角占一个字节,而不管是半角还是全角,汉字都还是要占两个字节。
在编程序的源代码中只能使用半角标点(不包括字符串内部的数据)
在不支持汉字等语言的计算机上只能使用半角标点(其实这种情况根本就不存在半角全角的概念)
对于大多数字体来说,全角看起来比半角大,当然这不是本质区别了。
4、全角和半角的区别
全角就是字母和数字等与汉字占等宽位置的字。半角就是ASCII方式的字符,
在没有汉字输入法起做用的时候输入的字母数字和字符都是半角的。
在汉字输入法出现的时候,输入的字母数字默认为半角,但是标点则是默认为全角,
可以通过鼠标点击输入法工具条上的相应按钮来改变。
5、关于“全角”和“半角”:
全角:是指中GB2312-80(《信息交换用汉字编码字符集·基本集》)中的各种符号。
半角:是指英文件ASCII码中的各种符号。
全角状态下字母、数字符号等都会占两个字节的位置,也就是一个汉字那么宽,半角状态下,
字母数字符号一般会占一个字节,也就是半个汉字的位置,全角半角对汉字没有影响。
有两种方式可以判断:
1:通过正则表达式来进行判断 [^\x00-\xff]
2: 通过字符编码的范围进行判断.
通过打印所有的字符发现:
1 | package com.hisen.String; |
一、idea配置文件
1 | \HOME\IntelliJ IDEA 2016.3.4\bin\idea64.exe.vmoptions |
增加一行:-Dfile.encoding=UTF-8
二、编译参数
1 | File -> Settings -> Build, Execution, Deployment |
在空格里面添加:-encoding utf-8
三、工程编码
1 | File -> Settings -> Editor -> File Encodings |
此页面三个地方都选择UTF-8
四、tomcat参数
1 | Run/debug Configuration tomcat |
VM options:-Dfile.encoding=UTF-8
1 | Application Server was not connected before run configuration stop, |
我遇到这个问题一般是这些原因:
这是下VM option中加了:-URIEncoding=UTF-8
1 | Error: Could not create the Java Virtual Machine. |
1 | --显示数据库当前连接数 |
快捷键设置:file->setting->Keymap->Main menu->Code->Completion->Basic
找到之后右键Add keyboard Shortcut,然后按下:Ctrl + 逗号
现在暂时使用 in 代替解决了
下面的查询是能限制住acct_type
1 | SELECT ew.customer_id,cf.acct_type |
但是在update的时候,会把acct_type=1的也更新了
1 | update ew_quota_info ew |
可以根据数据库中表结构自动生成CRUD代码,可以满足大部分需求。
MyBatis Generator (MBG) 是一个Mybatis的代码生成器 ,
可以根据数据库中表结构自动生成简单的CRUD(插入,查询,更新,删除)操作。
但联合查询和存储过程,需手动手写SQL和对象。
PS:配置过程中请注意自己的工程目录结构
1 | <plugin> |
resources下建generatorConfig.xml,作为mybatis-generator-maven-plugin插件的执行目标。
1 | <?xml version="1.0" encoding="UTF-8"?> |
MyBatis Generator生成代码的运行方式:命令行、使用Ant、使用Maven、Java编码。
本文采用Maven插件mybatis-generator-maven-plugin来运行MyBatis Generator,用的是命令行的方式。
配置插件
选择目录,输入命令:mybatis-generator:generate -e
找到插件。双击执行
即可看到生成的文件
Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,
第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,
因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
说明:这只是一个初步的安装,后续进一步实践
1 | #安装gcc g++的依赖库 |
1 | #启动 |
安装之后就直接监听80端口,浏览器打开127.0.0.1即可访问出现如下页面:
我是使用IDEA,maven
具体的目录结果见github:github
1 | #可以设置级别:debug>info>error |
1 | package com.hisen.log4j.log4j2MySQL; |
我用得是网易邮箱大师,把代码存为本地网页打开全选复制
粘贴到邮箱大师的签名里面即可!亲测有效,还挺好看的
1 | <html> |
作用是有助于系统的垂直拆分,使系统更易拓展。
Java中的RPC框架比较多,各有特色,广泛使用的有RMI、Hessian、Dubbo等。
RPC还有一个特点就是能够跨语言,本文只以JAVA语言里的RPC为例。
其他的框架结构也类似,区别在于对象的序列化方法,传输对象的通讯协议,
以及注册中心的管理与failover设计(利用zookeeper)。
客户端和服务端可以运行在不同的JVM中,Client只需要引入接口,
接口的实现以及运行时需要的数据都在Server端,RPC的主要依赖技术是序列化、反序列化和传输协议,
JAVA里对应的就是对象的序列化、反序列化以及序列化后数据的传输。
RMI的序列化和反序列化是JAVA自带的,Hessian里的序列化和反序列化是私有的,传输协议则是HTTP,
Dubbo的序列化可以多种选择,一般使用Hessian的序列化协议,传输则是TCP协议,使用了高性能的NIO框架Netty。
对于序列化,我还了解一些,像Google的ProBuffer、JBoss Marshalling和Apache Thrift等
JAVA自带的远程方法调用工具,不过有一定的局限性,
毕竟是JAVA语言最开始时的设计,后来很多框架的原理都基于RMI,RMI的使用如下:
对外接口
1 | public interface IService extends Remote { |
1 | import java.rmi.RemoteException; |
RMI客户端
1 |
|
RMI服务端
1 |
|
服务注册管理器写在了Server里,当然也可以抽出来单独作为一个服务,
在其他一些框架中,往往用Zookeeper充当注册管理角色。
基于HTTP协议传输,在性能方面还不够完美,负载均衡和失效转移依赖于应用的负载均衡器,
Hessian的使用则与RMI类似,区别在于淡化了Registry的角色,通过显示的地址调用,
利用HessianProxyFactory根据配置的地址create一个代理对象,另外还要引入Hessian的Jar包。
基于Netty的高性能RPC框架,是阿里巴巴开源的,总体原理如下:
在了解Dubbo之前,要先对Zookeeper有深入的理解,当理解了zookeeper后,Dubbo也就了无秘密了。
Dubbo的详细说明在淘宝开源里说的非常详细,在工作中很多生产项目都用了Dubbo,过程中也发现了很多需要注意的地方.
]]>mybatis:No constructor found in xxx matching [java.lang.Integer, java.lang.String, java.lang.Integer]
原因:xxx 这个bean缺少一个默认的构造方法!
解决:加上默认的构造方法即可
我是在单元测试的时候遇到这个问题
]]>1 | ##显示当月的日历 |
默认所对应的客户端地址只有localhost(也就是服务端的机器),
我们目的是任何地址都可以用root访问mysql服务端。
解决办法:
1 | $ mysql -u root -p |
1.安装
1 | sudo apt-get install mysql-server |
等待完成即可,过程中需要设置密码
2.查看是否成功
1 | sudo netstat -tap | grep mysql |
3.登陆mysql
1 | mysql -u root -p |
这条命令回车之后需要输入mysql密码
1 | $ sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf |
重启:service mysql restart
接下来就可以在navicat里面连接了
因为在网上找的很多教程,都是说改这个配置文件:这个是错误的
1 | /etc/mysql/my.cf |
如果是通过apt-get方式安装的,默认的是第二步那个配置文件
]]>JDBC Type | Java Type |
---|---|
CHAR | String |
VARCHAR | String |
LONGVARCHAR | String |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
BIT | boolean |
BOOLEAN | boolean |
TINYINT | byte |
SMALLINT | short |
INTEGER | int |
BIGINT | long |
REAL | float |
FLOAT | double |
DOUBLE | double |
BINARY | byte[] |
VARBINARY | byte[] |
LONGVARBINARY | byte[] |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
CLOB | Clob |
BLOB | Blob |
ARRAY | Array |
DISTINCT | mapping of underlying type |
STRUCT | Struct |
REF | Ref |
DATALINK | java.net.URL |
这里有一个简单的对比,情况相同的时候,两个sql的时间相差八倍
优:0.077s
1 | SELECT ew.all_amt , |
劣:0.630s
1 | SELECT ew.all_amt , |
上述原因:where子句从后往前执行,应该把大的过滤条件放在后面
记录时间:2017年3月9日 10:44:59
这里我就说一下今天我安装的方法。
下载好ubuntu的镜像,随便放在一个非系统盘的根目录下
改名为:ubuntu.iso
1 | sudo chmod 777 /boot/grub/grub.cfg |
保存退出,重启就会进入系统。
桌面上点击那个安装的图标即可完成重装
]]>解压之后在bin目录下执行
1 | sudo sh idea.sh |
就会进入安装程序,接下来会跳出图形界面,跟windows差不多的步骤
没有激活码可以看之前的文章
关键的一个是我发现网上说的建立桌面快捷方式不行
就这样弄个方便的
1 | cd ~ |
注册地址:https://zeroturnaround.com
注册完了之后在IDEA里面去设置,会提醒激活。
tomcat部署了项目之后,点击JR启动是可以热部署的!!!
改了java代码都不要重新启动项目,哈哈!!!
]]>一直么有重启,后来就安装了个插件重启一下,结果就泪崩了
一直出现这个错误
总以为是环境变量配置的问题,或者是文件损坏了什么
重启,重装jdk,重新配置什么都试过,不管用。
后来替换了配置文件就好了!!!
配置文件路径:
1 | \IDEA HOME\bin\idea64.exe.vmoptions |
默认配置文件内容如下:
32bit
1 | -server |
64bit
1 | -Xms128m |
by the way:
IDEA 写博客真是舒服啊~
完全不用切换来切换去的!
]]>想要真正的理解count函数,我们就必须明白count函数的作用。
作用一:统计某一列非空(not null)值得数量,即统计某列有值得结果数,使用count(col)。
作用二:统计结果集的行数,此时不用管某列是否为null值。即使用count(*).
明白了这点,我们就应该知道MySQL的count(*)并不是想象中的那样,统计每一列的值,而是直接忽视掉所有列,直接统计行数,那么它的效率肯定是很高的。
但是有一点,当col指定了该字段为NOT NULL时实际上,MySQL会自动将count(col)转为count(*),但是这样也同样耗费了些时间,如果col没有指定为NOT NULL的话,那么效率就更低了,MySQL就必须要判断每一行的值是否为空。
所以综上所述,如果是要统计行数最好优先使用select count(*)
当统计某一列等于多少的值得时候可以使用下面两种方法:
1 | SELECT SUM(IF(id = 23,1,0)) FROM table |
刚开始我觉得这样会很麻烦,后来想想以前写博客也是醉了
先新建一个 _post 的快捷方式
进去,然后到博客根目录
打开Git Bash,然后执行
1 | hexo n "你要写的文章题目" |
然后在 _post 快捷方式打开刚刚新建的markdown文件,用markdownpad打开编辑。。。
编辑完了回到Git Bash。。。。想想就很麻烦
于是乎用IDEA打开博客根目录
1 | sources -> _post -> new -> Edit File Templates |
name:markdown extension:md
内容:
1 | --- |
接下来apply -> *.md -> 下面选择markdown
以后新建markdown文件就会默认带上这个模版
效果
1 | title: 利用IDEA写Hexo博客的一些技巧 |
接下来到了发布的时间,于是我们可以设置一下Terminal(在setting里面),设置为bash(git目录下)
设置完了之后Alt + F12 调出 Terminal 即可进行git操作
到此,大功告成,我要去更新博客了
]]>来帮助我们消除一些必须有但看起来很臃肿的代码
比如属性的get/set,及对象的toString等方法,特别是相对于 POJO;
原来的代码用了lombok简单注解
比如maven的pom.xml文件有如下配置
1 | <dependency> |
安装lombok plugin
装完插件之后就舒服了,也不报错
]]>1 | failed to read artifact descriptor for xxx:jar |
一下午那代码里面是各种报错
凡是引入的大部分都报错
原因就是maven管理的jar没有添加上依赖
最后在stackoverflow找到了良药
上面有图片,错误会详细一点,如果你的也相同,可以试一试
1 | maven project -> Execute Maven Goal -> mvn -U clean install |
执行以上命令之后等待完成,应该就好了
参考自stackoverflow:点击查看
]]>例子代码:NIO应用之简单的CS模型
可以用来简单的理解一下java nio
深入的理解可以看看下面的链接。
Java NIO 系列教程:点击查看
如何学习Java的NIO?:点击查看
1 | 27-Feb-2017 12:53:31.268 严重 [RMI TCP Connection(13)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method manageApp |
重要的是:
1 | org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method manageApp |
Project Structure -> Artifacts
查看里面是否有配置相同的Artifacts
删除即可
]]>Linux和UNIX都支持ps命令,显示所有运行中进程的相关信息。
ps命令能提供一份当前进程的快照。如果想状态可以自动刷新,可以使用top命令。
输入下面的ps命令,显示所有运行中的进程:
1 | ps aux | less |
这个命令按 q 退出
后面加了“| less”就会分页显示,如果去掉会一次性显示出所有结果
1 | hisen@hisen-server:~$ ps aux | less |
1 | ps -A |
-A:显示所有进程
a:显示终端中包括其它用户的所有进程
x:显示无控制终端的进程
1 | pstree |
输出
1 | hisen@hisen-server:~$ pstree |
要想从事企业级的项目开发,你必须掌握如下要点:
没有人愿意自己一辈子就满足于掌握了一些代码实现的技巧,
别人告诉你要实现什么,你就用代码堆砌来实现别人的要求!
你必须学会从整个项目的角度去思考!
你必须学会假如你是项目经理,你该如何思考!
你必须学会假如你是架构师,你该如何思考!
你必须掌握针对某个特定问题领域的分析方法!
HttpServlet、doGet、doPost、HttpServletRequest、HttpServletResponse、request.getParameter()、request.setAttribute()、request.getAttribute()、request.getSession()、ServletContext、Filter、web.xml、tomcat、forward与redirect、http协议的无状态性、cookie、JSP Scope Object、<c:out …/>、<c:forEach …>
HTML与JavaScript:你需要能够理解常见的网页标签、理解在网页中引入JavaScript的方法、以及JavaScript的基本语法与使用方法
以上,就是你进一步学习Java所必备的基本知识。
特别是一些个专业术语和名词,看到这些名词,如果你像看到亲爹一样亲切,
那么说明你对Java的基础知识就很熟悉了,记住,仅仅是熟悉了
对于初学者来说,这三大框架被赋予了太多神秘的色彩,似乎它们是重中之重的知识!但是对于拥有多年Java开发经验的专业技术人员来说,对于那些Java牛人来说,却对这三大框架不太感冒!难道它们不重要吗?
现在很多企业都在用这三大框架,所以很多企业也把掌握这三大框架作为招聘的必备条件。不可否认的是,也有很多大型企业没有用这三大框架,这些企业经过多年发展,自身已经有一定的技术积累,也形成了自己独特的技术框架体系。这三大框架既可以说很重要,也可以说不重要。
说重要的原因在于:这三大框架对JavaEE开发中所存在的普遍的问题,提供了优美的解决方案,它们蕴含了这个行业中最NB的开发人员的努力和想法,所以,学习这三大框架,你就可以窥探到这些处于技术巅峰的牛人们究竟对一个问题是怎么想的,通过一种什么样的设计思路去解决问题的。所以,对于你来说,你没有太多项目开发的经验,经验是什么?经验就是你知道可能会遇到哪些问题,针对哪个问题可以有哪些解决方法,在某个情景下,哪种解决方法是较好的,哪种方法不太好等等!如果你没做过什么项目,你根本就不会去意识到你可能会遇到哪些问题,而这些问题往往又是非常关键的!解决得不好,会影响到你的程序的稳定性、可扩展性等等!三大框架就给初学者提供了了解你以后可能会遇到哪些问题,以及针对这些问题的解决方案!
当你了解了这三大框架为什么是重要的,那么你也就能理解,为什么这三大框架也可以说是不重要的。如果你曾经开发过很多项目,你碰到了各种各样的问题,凭着你的技术功底,逐个击破了这些问题,在这些人眼里,三大框架(是不是还有N个框架?呵呵)都是浮云!
你属于哪一种人呢?如果你没有太多项目开发经验,那么三大框架对于你来说就是非常重要的!而且,由此你也知道了该怎么去学这三大框架。对于三大框架的学习而言,着力点在于给你展示问题,并触发你自己主动的思考,我们鼓励你提出自己的想法,也许你的想法很白痴,但那毕竟是你自己的想法,如果你不知道牛人的想法,那你怎么知道自己的想法是很白痴的呢?在这种思想的碰撞过程中,你就会逐渐提高自己!所以,三大框架学完之后,你不应该只是看到一大堆配置文件,你不应该只是看到了一些Action,一些Service,一些映射文件,你不应该只知道session.save/update/delete,你不应该只是知道struts2中有一堆interceptor,你不应该只是看到一堆jar包……
如果你只是知道拷贝一堆jar包,定义一系列配置文件之后,SSH三大框架就能够运行起来了,也可以给你干活了,那么,很悲哀的是,你仍然没有掌握三大框架的精粹!请你回答以下问题:
Struts2:
Spring:
Hibernate:
以上并非SSH中全部重点的问题,但它们能考察你能否灵活运用SSH框架!如果你能深刻理解这些问题,再配以合适的实战项目训练,你也会逐渐成为牛人!
不管你是学Java还是别的技术,你的根本目的在于给客户创造价值!否则,你下大力气学习的东西,随着技术的进步和更新,很快就会过时!所以,技术的核心在于用技术创造有价值的成果!也就是说,客户需要什么,你就要用技术把客户需要的东西给他造出来!一个公司之所以要用各种福利条件极力挽留你,是因为你能够给公司带来极高的利益!那么,你有什么可以给公司利用的呢?公司最看重你的哪方面的能力呢?
做项目需要的能力很多,其中最核心最基础的就是建模能力(现在最主流的就是面向对象建模!)。什么是建模能力呢?
我给大家一个面试题:
一个保险公司的保险卡管理模块:销售人员领取保险卡信息(保险卡数量、卡号、领取日期),然后直接销售给客户,销售完毕后,将保险卡信息录入保险公司系统内部(销售人员信息、购买人信息、购买的保险卡数量、卡号等),客户登录保险公司网站激活保险卡,需要填写(保险卡卡号、激活密码、被保险人信息、受益人信息)
要求就是:如果这个模块交给你来做,你要怎么做?你要解决哪些问题?你可否画个图,给我描述一下你的想法是什么吗?
这只是一个面试题而已,因为只有简单几句话,所以我把它放到这里,让大家感受一下所谓建模要解决什么问题。而业务领域的问题实在是太多了!也许一个几十上百页的需求文档才能把某个业务领域的问题描述清楚,而你的职责就是要把它们实现出来!
某个公司要开发一个考勤管理系统,要求与现有的人力资源系统对接,你是主要的技术负责人,那么,你要做哪些工作呢?
某ERP项目要实现一个排班管理模块,交给你去完成,你如何去完成呢?
不要抱怨项目经理给你的信息太少(只有几句话),不要抱怨客户没有描述清楚他们的需求……你的价值就在于理顺所有的问题,用各种手段获得你想要的信息,按照一定的思路汇总,并在特定的时间里逐个解决它!
你应该意识到学Java不是一个坦克大战、一个网络飞车、一个CMS、一个DRP、一个OA那么简单,你不要沉迷于那些技术细节(虽然也是有必要的,但不要钻牛角尖),不要满足于实现了CRUD式的项目需求(虽然这是基础中的基础),在你的前方,永远有一个目标在那里,需要你去努力追赶!
今后你将面对更加繁杂的需求,你学习项目的唯一目的,就是:学习如何将需求转化为实现,如何对需求进行分析,如何建立概念模型,如何理顺各种概念之间的关系,如何进行设计,如何选择合适的技术来实现你的设计方案,如何对你的实现进行测试,如何解决你所遇到的形形色色的问题(性能、需求变更等)。当你真正到公司里面从事了几年开发之后,你就会同意我的说法!
利用Java找工作,需要的就是项目经验,项目经验就是理解项目开发的基本过程,理解项目的分析方法,理解项目的设计思路,理解项目的实现技巧,理解项目的测试方法,理解项目中各种问题的解决方案。
码农只是复制粘贴,并不注重原理,说不出所以然,所以做了几年还只能是码农。
加油,共勉!
]]>1 | sudo apt-get install zookeeper |
默认信息
1 | #安装路径 |
1 | hisen@hisen-server:/usr/share/zookeeper/bin$ sudo sh zkServer.sh |
如果报错
1 | zkServer.sh: 81: /home/xxx/zookeeper-3.4.6/bin/zkEnv.sh: Syntax error: "(" unexpected (expecting "fi") |
1 | hisen@hisen-server:/usr/share/zookeeper/bin$ sudozkCli.sh -server localhost:2181 |
出现上面的信息说明成功了
1.创建配置文件
1 | sudo vi /etc/init.d/zookeeper |
添加以下信息,注意自己的相关路径是否相同,不同修改之
1 | #!/bin/sh |
2.授权
1 | sudo chmod +x zookeeper |
3.安装开机启动管理软件(一般自带)
1 | sudo apt-get install rcconf |
4.进入管理界面
1 | sudo rcconf |
↑ ↓ 移动光标,空格键选中zookeeper
Tab 使光标移动到OK 回车即可
]]>redis服务路径: /etc/init.d/redis-server
默认是开机启动
1 | #安装 |
1 | [platform] ERROR 2017-02-22 17:46:05,756 [RMI TCP Connection(4)-127.0.0.1] org.springframework.web.context.ContextLoader.() | Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pmTranLimitLiteServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.msds.zkutil.ZkLockFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(mappedName=, shareable=true, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)} |
最重要的是这句
1 | org.springframework.beans.factory.BeanCreationException: |
出现的原因:
缺少相关的jar包或者依赖
建议不要自己配置idea的module和artificts
直接在pom.xml文件添加
1 | <artifactId>hisen-project</artifactId><!--加在这句话后面--> |
其他原因
开始不知道什么问题,后来搜索这个服务。
发现这跟dubbo有关,于是百度搜索进了官网
没想到常见问题里面就有说这个事情
1 | 13. 出现org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxService': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Method must not be null怎么办? |
更多dubbo问题:点击查看
]]>Tomcat只分配了非常小的PermGen内存,这里重新设置一下
直接在配置tomcat的时候,在VM options填入:
1 | -XX:PermSize=97m -XX:MaxPermSize=256m |
1 | cd %userprofile%\.m2\repository |
或者新建一个bat文件,批处理。就不用每次都在cmd敲命令了
1 | @echo off |
linux系统
1 | find /app/maven/localRepository -name "*.lastUpdated" -exec grep -q "Could not transfer" {} \; -print -exec rm {} \; |
通过Oracle VM VirtualBox端口转发,连接了虚拟机的MongoDB
1.用idea创建一个maven项目
2.在pom.xml中添加mongodb java驱动
1 | <dependency> |
3.参考官方:MongoDB Driver Quick Tour
本用例github地址:mongodbTest
1 | package com.hisen.jdbc; |
新建一个start.bat文件,内容如下
1 | @echo off |
2.设置开机启动
把start.bat文件复制到[启动]文件夹里面
[启动]文件夹路径
1 | C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp |
文件管理器地址栏显示大概是这样
1 | Windows > [开始]菜单 > 程序 > 启动 |
放进去之后就可以开机启动了!
启动之后Xshell连接即可
]]>1 > 添加 MongoDB 公共GPG钥匙
1 | sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 |
2 > 创建列表文件
这里把官网repo.mongodb.org
换成了mirrors.aliyun.com
1 | echo "deb http://mirrors.aliyun.com/mongodb/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list |
3 > 重新加载本地包数据库
1 | sudo apt-get update |
4 > 安装MongoDB
1 | sudo apt-get install -y mongodb-org |
5 > 启动MongoDB
1 | sudo service mongod start |
6 > 打开MongoDB客户端
1 | sudo mongo |
7 > 关闭MongoDB
1 | sudo service mongod stop |
展示一下
1 | hisen@hisen-server:~$ sudo service mongod start |
安装成功
MongoDB默认的数据文件和日志文件分别存储在下面的位置
数据文件:/var/lib/mongodb
日志文件:/var/log/mongodb
你可以修改/etc/mongod.conf 文件来改变相应的存储位置。
如果你想改变运行MongoDB的用户
你必须把 /var/lib/mongodb
和 /var/log/mongodb 2个目录的访问权限付给该用户
1允许远程访问
绑定ip
1 | $ sudo vim /etc/mongod.conf |
打开配置文件,添加需要增加的
不建议采用注释掉 bindIP 的方案,非常容易受到攻击
1 | # network interfaces |
接受所有ip
重启
1 | $ sudo service mongod restart |
2.配置防火墙 (不配置也行)
Ubuntu16.04 桌面版默认没有安装好 ipTable,用如下命令安装
1 | sudo apt-get update |
安装过程中,弹窗选择YES
安装完成后:
1 | sudo iptables -A INPUT -p tcp --dport 27017 -j ACCEPT |
没想到安装之后发现一直没法让VirtualBox隐藏到托盘
按正常程序走,打开一个虚拟机会出现两个GUI界面:
第一个可以在打开虚拟机之后关闭,第二个不能关闭也不能隐藏到托盘
痛苦!!!
这里给出解决方案:通过cmd命令行启动并且后台运行
1 | C:\tool\Oracle\VirtualBox> |
1 | C:\tool\Oracle\VirtualBox>VBoxManage list vms |
前面是NAME,后面是UUID,之后的name用这连个代替都可以
1 | C:\tool\Oracle\VirtualBox>VBoxManage startvm "ubuntu" --type headless |
headless是在后台运行,并且默认开启vrdp服务,可以通过远程桌面工具来访问
下面是打开ubuntu之后用Xshell链接的
1 | Connecting to 127.0.0.1:2222... |
下面所有的NAME都可以用二中的name和UUID代替
1 | # 列出所有安装的虚拟机 |
到了图形化界面,打开terminal(终端)执行
1 | sudo init 3 |
就会跳转到命令行界面,并且只有命令行
就是一个全屏的terminal。
在安装ubuntu的时候,有选择是否安装图形化界面的选项,选择不安装,那么系统将不带有图形化界面而默认进入命令行界面。
直接安装Ubuntu Server,目前我就是这样
不过装了之后还是推荐第三个方法!!!
]]>这种配置下,虚拟机能上网,又能跟win连接,感觉很完美
VirtualBox的端口转发很不错,可以转发tomcat什么的
1.给Ubuntu安装openssh-server
1 | sudo apt-get install openssh-server |
2.查看虚拟机ip 我的是:10.0.2.15(看上面那段)
1 | hisen@hisen-VirtualBox:/$ ifconfig -a |
名称 | 协议 | 主机IP | 主机端口 | 子系统IP | 子系统端口 |
---|---|---|---|---|---|
ssh | TCP | 127.0.0.1 | 2222 | 10.0.2.15 | 22 |
子系统ip写你的虚拟机ip即可
在xshell链接Ubuntu虚拟机的时候
ip写上麦的主机ip:127.0.0.1
端口写上面的主机端口:2222
然后上面配置的端口转发就可以转发到虚拟机上,顺利连接!!!
]]>三步完成之后即可!
1 | deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse |
准备工作:
目录约定:
说明以上路径都是解压之后的,请解压之后自行重命名文件夹等工作
下面开始配置环境变量:
1 | sudo vi /etc/profile |
底部添加:
1 | #java的环境变量配置 |
让刚刚的配置生效:
1 | source /etc/profile |
查看maven
1 | mvn -v |
查看java版本
1 | java -version |
如果还是默认的OpenJDK
1 | sudo update-alternatives --install /usr/bin/java java /usr/hisen/soft/java/jdk8/bin/java 300 |
进入tomcat的bin目录
1 | sudo vi catalina.sh |
顶部添加
1 | #让tomcat知道java在哪里 |
之后进入在tomcat bin目录执行
1 | hisen@hisen:/usr/hisen/soft/tomcat/tomcat8/bin$ sudo sh startup.sh |
如果没有在 catalina.sh 添加java路径,会报错
1 | hisen@hisen-VirtualBox:/usr/hisen/soft/tomcat/tomcat8/bin$ sudo sh startup.sh |
CentOS系统更换软件安装源
第一步:备份你的原镜像文件,以免出错后可以恢复。
1、备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
2、下载新的CentOS-Base.repo 到/etc/yum.repos.d/
(如果无wget命令,底部有具体说明)
CentOS 5
1 | wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo |
CentOS 6
1 | wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo |
CentOS 7
1 | wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo |
3、之后运行yum makecache生成缓存
ps:如果你跟我一样苦逼:
1 | -bash: wget: command not found |
然后:
1 | yum -y install wget #失败 |
那么你可以直接选择上面对应系统的文件下载链接
下载好文件之后改名为CentOS-Base.repo
直接放到/etc/yum.repos.d/目录下即可
]]>另外在使用上还有一些小的差异,比如:
在实现上两者已有一些差异,这里简单说明一下:
1 | public Hashtable(int initialCapacity, float loadFactor) { |
HashTable中构造hash数组时initialCapacity默认大小是11,增加的方式是 old*2+1。HashMap中构造hash数组时initialCapacity默认大小是16,而且一定是2的指数。对于哈希值的使用也有所不同,HashTable直接使用对象的hashCode,代码是这样的:
1 | int hash = key.hashCode(); |
而HashMap重新计算hash值,而且用与代替求模:
1 | int hash = hash(k); |
仅供参考,内容来源于互联网
]]>今天导入到IDEA中去,发现编译出问题
ava编译错误:程序包javax.servlet不存在javax.servlet.*
原因大概是myeclipse中可以选择Java EE项目
而idea没有,缺少 servlet-api.jar 这个jar包
解决办法:
即可
]]>这里给出的解决办法是用hexo自动提交插件
需要获取一个自动提交的token
1 | baidu_url_submit: |
加入新的deployer: 原来type前面是没有 - 的
但是不这样处理执行hexo g 会报错
1 | deploy: |
生成效果如下:
1 | $ hexo g |
感谢插件作者:王辉的博客
]]>发现百度搜索网址都搜索不到自己的站点
我只把hexo传到github上,然而去百度站长工具提交网址几条后也没有反应
我就测试了一下百度站长工具 - 抓取诊断
结果是抓取失败:Github把百度的爬虫给干掉了!所以。。。
具体内容如下:
1 | 提交网址:http://hisen.me/20170214-maven%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/ |
返回HTTP头:
1 | HTTP/1.1 403 Forbidden |
我发现居然每次新open一个项目就得配置下maven
因为默认的maven配置文件不行,我自定义的文件用的是阿里云的镜像
那样快一点,于是很郁闷,决定要搞定他!!!
结果这样设置就可以了,全局设置。
1 | File--->Other Setting--->Default Setting |
接下来的设置就是一样的了,各种设置都可以,只要你想全局生效
]]>在底部任务栏空白处:
右键—设置—任务栏—在桌面模式下自动隐藏任务栏(开)—任务栏在屏幕上的位置(上 | 下 | 左 | 右)
这样就设置完毕了,毕竟笔记本太小
用idea的时候居然有些界面很难点击OK什么的!!!
知乎有专门讨论任务栏放置位置分析,有兴趣的可以看看:
]]>重复了一遍以往正常的不能再正常了的导入配置,结果遇到了如下问题:
SEVERE [RMI TCP Connection(3)-127.0.0.1]
1 | 15-Feb-2017 11:05:25.993 严重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Skipped installing application listeners due to previous error(s) |
因为idea要用的东西自己会自动生成
然后就搞定了这个纠结我一天的问题
我是百度搜索这个错误:RMI TCP Connection(3)-127.0.0.1
得到的答案,感谢10100:查看原文
]]>1 | Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00) |
1.自定义下载目录,修改配置文件
1 | C:\hisenwork\soft\maven-3.3.9\conf\settings.xml |
C:\hisenwork\soft\maven-3.3.9为你解压的maven路径
ps:如果不想自己设置,我有现成的settings.xml,直接复制粘贴,覆盖原来的即可
现成的settings.xml内容我放在底部
搜索:localRepository
在注释外添加以下代码,以后下载maven相关文件就会在这
1 | <!--自定义存放目录--> |
2.自定义镜像(推荐阿里云,速度飞快)
搜索:mirrors
在里面添加:
1 | <!--阿里云--> |
3.运行命令初始化maven
1 | mvn help:system |
然后你会看到命令行飞快的移动,在你刚刚设置的目录下会出现很多东西
类似于这样
1 | $ mvn help:system |
创建 Maven 项目
1 | mvn archetype:create |
编译源代码(编译到target文件夹中)
1 | mvn compile |
编译测试代码
1 | mvn test-compile |
运行应用程序中的单元测试
1 | mvn test |
生成项目相关信息的网站
1 | mvn site |
清除目标目录中的生成结果(把默认target文件夹中的数据清理)
1 | mvn clean |
项目打包
1 | mvn package |
将打包好的包安装到本地仓库中,以使其塔项目能够调用
1 | mvn install |
生成 Eclipse 项目文件
1 | mvn eclipse:eclipse |
忽略测试文档编译
1 | mvn -Dmaven.test.skip=true |
部署到私有服务器
1 | cargo:deploy |
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | Registration successful |
Product Code:
1 | 4t46t6vydkvsxekkvf3fjnpzy5wbuhphqz |
serial Number:
1 | 601769 |
password:
1 | xs374ca |
Alt+回车 导入包,自动修正
Ctrl+N 查找类
Ctrl+Shift+N 查找文件
Ctrl+Alt+L 格式化代码
Ctrl+Alt+O 优化导入的类和包
Alt+Insert 生成代码(如get,set方法,构造函数等)
Ctrl+E或者Alt+Shift+C 最近更改的代码
Ctrl+R 替换文本
Ctrl+F 查找文本
Ctrl+Shift+Space 自动补全代码
Ctrl+空格 代码提示
Ctrl+Alt+Space 类名或接口名提示
Ctrl+P 方法参数提示
Ctrl+Shift+Alt+N 查找类中的方法或变量
Alt+Shift+C 对比最近修改的代码
Shift+F6 重构-重命名
Ctrl+Shift+先上键
Ctrl+X 删除行
Ctrl+D 复制行
Ctrl+/ 或 Ctrl+Shift+/ 注释(// 或者/…/ )
Ctrl+J 自动代码
Ctrl+E 最近打开的文件
Ctrl+H 显示类结构图
Ctrl+Q 显示注释文档
Alt+F1 查找代码所在位置
Alt+1 快速打开或隐藏工程面板
Ctrl+Alt+ left/right 返回至上次浏览的位置
Alt+ left/right 切换代码视图
Alt+ Up/Down 在方法间快速移动定位
Ctrl+Shift+Up/Down 代码向上/下移动。
F2 或Shift+F2 高亮错误或警告快速定位
代码标签输入完成后,按Tab,生成代码。
选中文本,按Ctrl+Shift+F7 ,高亮显示所有该文本,按Esc高亮消失。
Ctrl+W 选中代码,连续按会有其他效果
选中文本,按Alt+F3 ,逐个往下查找相同文本,并高亮显示。
Ctrl+Up/Down 光标跳转到第一行或最后一行下
Ctrl+B 快速打开光标处的类或方法
]]>这是在线支付的最普遍形式。
大致支付过程:第三方支付公司作为代理(网关),接入一堆银行。用户在网关页面(可以在商户端,也可以第三方支付平台端)选择银行,页面跳转到第三方支付平台,然后重定向到对应的银行,用户在银行电子银行官网,采用网银(个人网银或企业网银)完成支付。
网关支付分为:B2C、B2B两类。
涉及的概念:网银支付、银行卡支付。
我们一般说的网关支付是指在PC上的在线支付,由于国内银行基本上都要求安装对应的安全控件,且需要银行的网银客户端,这也是大家经常抱怨网银不支持MAC/Linux等操作系统、不支持除IE外的浏览器等兼容性问题。
在手机端也有类似网关支付的形态,但由于操作过程较为麻烦,体验不好,一般都采用快捷支付等支付形式。
快捷支付一般是指首次需要验证卡要素,生成协议号或者TOKEN,后面支付直接凭协议号扣款。走的交易形式是消费。快捷支付相比于我们原先说的无磁无密支付[MOTO]在限额上有劣势,体验上有优势。
一个相当于长期关系,MOTO相当于一次性关系,每次来都要输入卡要素。
代收代付业务是我社利用自身的结算便利,接受客户的委托代为办理指定款项的收付事宜的业务。
由中介公司或第三方代为收取和支付费用。
顾名思义,代收代付是指先付出去,然后再收回来,金额必须相等。
比如代办运输业务,如果是收取一定比率的手续费,就改变了性质。
代收代付业务分录:
代付时,借:其他应收款 贷:银行存款
收回时,借:银行存款 贷:其他应收款
待完善
微信扫码业务流程说明:
日后需要用到这方面的东西,先整理一番
系统的学习或者理解之后再来说说深层次的东西。
]]>看了几个小时,感觉还是不错
都按规范来写,可以避免很多错误
亲测有效:2017年2月13日 18:07:25
邮箱:
1 | Soar360@live.com |
1 | GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M5SN6bnxn2kSE8qHqNY5QaaRxmO3YSMHxlv2EYpjdwLcPwfeTG7kUdnhKE0vVy4RidP6Y2wZ0q74f47fzsZo45JE2hfQBFi2O9Jldjp1mW8HUpTtLA2a5/sQytXJUQl/QKO0jUQY4pa5CCx20sV1ClOTZtAGngSOJtIOFXK599sBr5aIEFyH0K7H4BoNMiiDMnxt1rD8Vb/ikJdhGMMQr0R4B+L3nWU97eaVPTRKfWGDE8/eAgKzpGwrQQoDh+nzX1xoVQ8NAuH+s4UcSeQ== |
通过搜索发现有不错的方法可以解决这个问题
那就是安装一个插件!名字叫:hexo-neat
命令行进入博客根目录,执行以下命令
1 | npm install hexo-neat --save |
如果使用的是淘宝的cnmp执行以下命令
1 | cnpm install hexo-neat --save |
1 | #hexo-neat 优化提速插件 |
安装好之后,就直接正常使用(跟以前没有装的时候一样使用),
重新生成博客就可以发现html源码已经压缩了
只是在生成博客的过程中可能要浪费一丁点时间
访问速度有所提升!
参考:点击查看
]]>总能发现以前自己没有怎么在意的细节
静态代码块是在类中独立于类成员的static语句块,可以有多个。
如果要初始化静态变量,可以声明一个静态块。
格式如下:
1 | static { |
静态块存在单独的内存中,仅在该类被加载时执行,示例如下:
1 | package com.hisen.javaGaiShu.page91test20; |
1 | 我学习了很多语言 |
静态代码块在运行main方法时可以直接调用而不用创建实例。
静态代码块直接是按顺序执行的。
]]>1 | <使用new关键字创建对象> |
1 | package com.hisen.javaGaiShu.page73test5; |
所有基本数据类型的大小(所占用的字节数)都是明确规定好的,
在各种平台上都保持不变,这一特性有助于提高Java程序的可移植性。
引用数据类型包括字符串、数组、类和接口。
引用数据类型是用户自定义、用来限制其他数据类型。
引用数据类型的变量在内存中存储的是数据的引用,并不是数据本身,
引用类型是使用间接方法去获取数据
java中int为什么占用4个字节?
回答1:
现在流行的编译器,都是规定的int是四个字节~
像tc这样老版的编译器,int才是两个字节,
然后也是一样,由于一个字节占八位,最高为符号位,又人为规定,1000000000000000……这个补码编码为-2^31所以,范围就是-2^31~2^31-1
回答2:
JAVA是采用Unicode编码。每一个字节占8位。
你电脑系统应该是32位系统(工具),这样每个int就是 4个字节
其中一个字节由8个二进制位组成
回答3:
int常见为4个字节,跟操作系统有关系。
turbo c(以及Turbo c的一些衍生编译器,他们用的一套编译程序)是dos时代的编译器,
是上世纪80年代的产物,严重过时,属于老掉牙的产品,
他们编译出来的程序是16位操作系统dos下的程序,所以长度为16位,即两个字节。
windows为了兼容dos,所以turbo c生成的文件也可以在windows中运行。
其他一般就都是4个字节了。
操作系统16位的时候,int 2字节,操作系统32位的时候,int 4字节,由于32位系统之前占主流地位,实际现在就算是64位系统,出于兼容性考虑,int也是4字节的
1 | VK7JG-NPHTM-C97JM-9MPGT-3V66T |
这里是创建post的模板。
我的默认设置成这样:
1 | --- |
tags: [关键词1,关键词2]
]]>记录类型 | 主机记录 | 记录值 |
---|---|---|
CNAME | @ | hisen-yuan.github.io |
主机记录:@ 代表顶级域名,例如hisen.me 如果想要www.hisen.me把@改成www
记录值:你的博客原始地址
3.在\blog\source下添加CNAME文件,没有后缀名,内容为你的域名,注意不要带http://
我的域名解析为 hisen.me 文件内容为 hisen.me
等待解析生效即可!
]]>修改这个文件:
1 | themes/landscape/layout/_partial/after-footer.ejs |
将17行左右的
1 | <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> |
改为
1 | <script src="http://apps.bdimg.com/libs/jquery/2.0.3/jquery.min.js"></script> |
重新生成博客之后就把谷歌的cdn替换成百度的cdn了
]]>在head加上这两行代码,可以做到原样输出
1 | <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> |
1 | [root]# virt-what |
1 | wget http://people.redhat.com/~rjones/virt-what/files/virt-what-1.12.tar.gz |
1 | apt-get install virt-what |
答:Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,
它们可以储存和操作字符串。其中String是只读字符串,
也就意味着String引用的字符串内容是不能被改变的。
而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改。
StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,
区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,
因此它的效率也比StringBuffer要高。
简而言之:
String:不能被修改
StringBuffer:可以随意修改,有synchronized修饰,是线程安全的,效率略低
StringBuilder:可以随意修改,无synchronized修饰,不是线程安全的,效率高
1 | classStringEqualTest { |
存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。
String的intern()方法就是扩充常量池的一个方法;
当一个String实例str调用intern()方法时,
Java查找常量池中是否有相同Unicode的字符串常量,
如果有,则返回其的引用,
如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用
什么情况下用+运算符进行字符串连接比调用StringBuffer/StringBuilder对象的append方法连接字符串性能更好?
答:
如果使用少量的字符串操作,使用 (+运算符)连接字符串;
如果频繁的对大量字符串进行操作,则使用
1:全局变量或者需要多线程支持则使用StringBuffer;
2:局部变量或者单线程不涉及线程安全则使有StringBuilder。
]]>在关键字之前加上:BINARY,会使关键字强制转换为二进制字符串
1 | select id form t where chinese like **BINARY** %汉字% |
把关键字的类型改成:BINARY
1 | new ImageIcon("1.jpg") |
正确:
1 | new ImageIcon("src/com/hisen/thread/progressbar/1.jpg") |
图片路径:
1 | test\src\com\hisen\thread\progressbar\1.jpg |
所谓的相对路径,是相对于这个工程而言的,而不是当前文件夹而言。
]]>host位置:
1 | C:\Windows\System32\drivers\etc |
host文件最后一行加上下面内容即可
1 | 192.30.253.112 github.com |
Window -> preferences -> general -> Contents Types -> Text(展开)
-> Java Aroperties File(点击) -> *.properties(locked)(点击)
-> 把iso-8859-1改为 UTF-8 -> Update -> OK
然后就可以正常显示中文了
]]>1 | ###设置 |
log4j详细使用方法:点击查看
]]>主要是交流比较多,不是先笔试
直接是把这些问题带入到具体的情景当中去
可能这样更能考验出一个人真正的技术水平
1,很多文件,读出数字,加1写回,谈谈你的想法
2,能继承string类?
1 | 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。 |
3,能有个包名一样的String类?如果有一样的会调用哪个?
4,一个主线程等待其他线程完成,如果其中有线程出错怎么办?
1 | 把线程可能会出现的问题处理掉 |
5,Oracle默认端口?
1521
6,b继承a,b的对象能强转成a嘛?
不能把一个对象强制转换成另外一个对象
7,数据库去重,删除所有重复记录,只留下一条
1 | DELETE |
8,try c里面,没打印出错误来,是为什么?
1 | 1.可能是程序执行是正确的 |
9,JAVA数据类型
简单类型 | 二进制位数 | 封装器类 |
---|---|---|
boolean | 1 | Boolean |
byte | 8 | Byte |
char | 16 | Character |
short | 16 | Short |
Int | 32 | Integer |
long | 64 | Long |
float | 32 | Float |
double | 64 | Double |
void | – | Void |
10,银行金额字段
金融数字是BigDecimal类型
11,用什么解析XML,有什么优缺点
1 | DOM4J(Document Object Model for Java) |
12,阿贾克斯熟悉吗?能发起请求下载文档吗?返回类型有哪些,遇到错误怎么提示用户
1 | 不能发起文档下载,返回的类型只有字符型, |
13,jquery选择器
1 | jQuery 元素选择器 |
14,空指针异常,怎么定位错误
1 | 定位到出现错误的行数 |
1 | tail -100 /access.log |
2、进入目录相关
1 | #进入一个目录 |
3、看倒数多少行
1 | #看倒数10行 |
4、过滤特定行,保存结果到新文件
1 | cat /root/old.text | grep -v "yourstring"> /root/new.text |
以上
]]>只在基于规则的优化器中有效,ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.
ORACLE采用自下而上(从后往前)的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾
ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.需要什么字段就查询什么字段,永远不要查询出不需要的字段来
ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等;尽量使用缓存技术;
在SQLPlus , SQLForms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表,因为decode函数有短路效应,类似java中短路与,有合适的就会返回而不继续扫描后面的内容
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系),原因见[4]
因为这里使用的是rowid
1 | DELETE |
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. (注: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:
COMMIT所释放的资源:
避免使用HAVING子句, HAVING在检索出所有记录后对结果集进行过滤。这个处理需要排序,总计等操作。 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. (非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里
在含有子查询的SQL语句中,要特别注意减少对表的查询。例子:
1 | SELECT TAB_NAME |
复杂的SQL往往牺牲了执行效率。能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。一般把复杂的sql分解再拼起来。
当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率。在子查询中,NOT IN子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历).。为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.
高效:
1 | SELECT * |
低效:
1 | SELECT * |
虽然目前各种关于SQL优化的图形化工具层出不穷
但是写出自己的SQL工具来解决问题始终是一个最好的方法:
1 | SELECT EXECUTIONS, |
索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构。通常,通过索引查询数据比全表扫描要快。 当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引。同样在联结多个表时使用索引也可以提高效率。另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证。那些LONG或LONG RAW数据类型,你可以索引几乎所有的列。 通常,在大型表中使用索引特别有效。当然,你也会发现,在扫描小表时,使用索引同样能提高效率。虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O 。 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的。
1 | ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME> |
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。一般可以考虑用EXIST替换,EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。
低效:
1 | SELECT DISTINCT DEPT_NO, |
高效:
1 | SELECT DEPT_NO, |
因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行
一般来说StringBuilder(非线程安全)是一个不错的选择
我们要避免在索引列上使用NOT,NOT会产生在和在索引列上使用函数相同的影响。当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描。
WHERE子句中,如果索引列是函数的一部分。优化器将不使用索引而使用全表扫描。
举例:
低效:
1 | SELECT … FROM DEPT WHERE SAL * 12 > 25000; |
高效:
1 | SELECT … FROM DEPT WHERE SAL > 25000/12; |
高效:
1 | SELECT * FROM EMP WHERE DEPTNO >=4 |
低效:
1 | SELECT * FROM EMP WHERE DEPTNO >3 |
两者的区别在于,前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。
通常情况下,用UNION替换WHERE子句中的OR将会起到较好的效果。对索引列使用OR将造成全表扫描。注意,以上规则只针对多个索引列有效。如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低。在下面的例子中, LOC_ID 和REGION上都建有索引。
高效:
1 | SELECT LOC_ID, |
低效:
1 | SELECT LOC_ID, |
如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面
这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的。
低效:
1 | SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30 |
高效:
1 | SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30); |
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。对于单列索引,如果列包含空值,索引中将不存在此记录。对于复合索引,如果每个列都为空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中。
举例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入)。然而如果所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空。 因此你可以插入1000 条具有相同键值的记录,当然它们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引。
低效: (索引失效)
1 | SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL; |
高效: (索引有效)
1 | SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0; |
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引。这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引
当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序。如果用UNION ALL替代UNION, 这样排序就不是必要了。效率就会因此得到提高。需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录。因此各位还是要从业务需求分析使用UNION ALL的可行性。 UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存。对于这块内存的优化也是相当重要的。下面的SQL可以用来查询排序的消耗量。
低效:
1 | SELECT ACCT_NUM, |
高效:
1 | SELECT ACCT_NUM, |
ORDER BY 子句只在两种严格的条件下使用索引
ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序
ORDER BY中所有的列必须定义为非空
WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列
例如:
表DEPT包含以下列:
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效: (索引不被使用)
1 | SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE |
高效: (使用索引)
1 | SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0 |
当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换
假设 EMPNO是一个数值类型的索引列.
1 | SELECT … FROM EMP WHERE EMPNO = '123' |
实际上,经过ORACLE类型转换, 语句转化为:
1 | SELECT … FROM EMP WHERE EMPNO = TO_NUMBER('123') |
幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变
现在,假设EMP_TYPE是一个字符类型的索引列
1 | SELECT … FROM EMP WHERE EMP_TYPE = 123 |
这个语句被ORACLE转换为:
1 | SELECT … FROM EMP WHERETO_NUMBER(EMP_TYPE)=123 |
因为内部发生的类型转换, 这个索引将不会被用到!
为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来。 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型
某些SELECT 语句中的WHERE子句不使用索引
这里有一些例子
在下面的例子里,
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎
执行耗费资源的排序(SORT)功能。
DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序。
通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写。
如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑的, 毕竟它们的可读性很强。
提高GROUP BY 语句的效率,可以通过将不需要的记录在GROUP BY 之前过滤掉。
下面两个查询返回相同结果但第二个明显就快了许多。
低效:
1 | SELECT JOB, |
高效:
1 | SELECT JOB, |
本文参考其他文章整理而来
出处:http://www.cnblogs.com/rootq/archive/2008/11/17/1334727.html
不过互联网上这篇文章很多,都没有版权注明。我也不知道原创是谁!
]]>1 | String str = new String("java"); |
答案:最少一个,最多两个
1 | --找出重复 |
安装好上面三个工具
可能会遇到的问题:
1、Git Bash执行node -v
提示无效 或者 npm install
报 command not found
解决办法:在环境变量 - 用户变量中 - 新建用户变量 - 添加nodejs安装路径
如:C:\tool\nodejs
2、ERROR Deployer not found : github
解决办法:
3使用淘宝镜像加快安装速度
安装cnpm,使用命令:
1 | npm install cnpm -g --registry=https://registry.npm.taobao.org |
npm install -g hexo
#等待安装完成,这个过程可能会快也可能很慢,耐心等待mkdir blog && cd blog
#上面这个代码是创建一个博客存放的目录hexo init
#初始化cnpm install
#安装依赖包hexo g
#生成静态页面hexo s
#启动服务器,打开http://localhost:4000 就是本地博客本地博客安装完成,下面介绍发布到github上
yourgithubname.github.io
Setting
_config.yml
配置文件1 | deploy: |
最后执行
hexo g
#重新生成静态博客hexo d
#将本地静态博客部署到github现在你在浏览器打开:http://yourname.github.io就可以访问你的博客了
到此为止就搭建完了一个博客
开始写第一篇文章:
执行:hexo new “你的文章标题”
然后你在blog/source/_posts
文件夹下面有文件,用markdownpad打开编辑
执行:
hexo g
#重新生成hexo s
#本地查看效果hexo d
#上传到githubhexo d -g
1 | package com.hisen.interview; |
官方发布了这个问题的解决办法
详见:点击前往 页面中搜索:This view has crashed
windows 10系统 需要下载 一个 awesomium_v1.6.6_sdk_win
这是一个 HTML UI ENGINE
下载地址:http://markdownpad.com/download/awesomium_v1.6.6_sdk_win.exe
]]>默认所对应的客户端地址只有localhost(也就是服务端的机器),
我们目的是任何地址都可以用root访问mysql服务端。
解决办法:
$ mysql -u root -p |
[platform] ERROR 2017-02-22 17:46:05,756 [RMI TCP Connection(4)-127.0.0.1] org.springframework.web.context.ContextLoader.() | Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pmTranLimitLiteServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.msds.zkutil.ZkLockFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(mappedName=, shareable=true, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)} |
最重要的是这句
org.springframework.beans.factory.BeanCreationException: |
出现的原因:
缺少相关的jar包或者依赖
建议不要自己配置idea的module和artificts
直接在pom.xml文件添加
<artifactId>hisen-project</artifactId><!--加在这句话后面--> |
其他原因
开始不知道什么问题,后来搜索这个服务。
发现这跟dubbo有关,于是百度搜索进了官网
没想到常见问题里面就有说这个事情
13. 出现org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxService': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Method must not be null怎么办? |
更多dubbo问题:点击查看
]]>作为一个软件开发工程师,日常很多机会和英文打交道。
特别是上一份工作,做全球支付项目,需要用到英文与国际友人沟通。
奈何自己的英语水平捉襟见肘,于是经常会有意地去收集相关的文章。
今天心血来潮,再次看了一下之前收藏的相关文章,感觉收获不少。
于是就想写一篇文章归集一下相关的内容,方便日后翻阅,顺便分享给有需要的人。
复旦大学中文系教授严峰
严老师的英语学习硬核秘诀
学习英语最重要的还是兴趣,推荐听广播,背课文,背单词。
学外语有什么用
关于学习外语的一些用途,方便大家思考自己学习的目的。
程序员圈”名”人王垠 :
解谜英语语法
语法、动词比较重要
推荐:练习造句。分析句子。
语法树的概念蛮好理解,我让我明白了什么叫宾补~
英语学习的一些经验
语法和句子结构是关键,其次才是词汇量。
如果你的词汇量足够阅读技术文档,那就可以开始看了。
遇到不懂的单词,查询之,使用英英字典,记录在本子上,加强记忆。
GitHub 上的成功人士:
还是得坚持看文档,背单词。
]]>举个例子:快到吃饭的点了,你有两种选择:1)自己做,2)叫外卖
1.1.1 自己做你嫌麻烦,那就叫外卖,只管收外卖其它不关注(解耦);
1.1.2 自己做的不好吃,那厨师上门,厨师给你增强菜的味道(增强);
官方定义:对其他对象提供一种代理以控制对这个对象的访问。
1.2.1 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时我们就可以通过代理对类进行增强。
1.2.2 我们在使用RPC框架的时候,框架本身并不能提前知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用通过动态代理的方式来建立一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。
1.2.3 Spring的AOP机制就是采用动态代理的机制来实现切面编程。
2.1.1 JDK:只能代理接口
2.1.2 CGlib:直接代理类
完整代码:https://github.com/hisenyuan/IDEAPractice/tree/master/src/main/java/com/hisen/jdk/agent
public static void main(String[] args) { |
http://www.cnblogs.com/puyangsky/p/6218925.html
https://blog.csdn.net/u011784767/article/details/78281384
项目中看到有一个缓存接口存在多个实现类,
但是在代码中使用@Resource注解注入,
之前有了解过@Autowire @Resource的区别,
于是就尝试着搜索@@Resource,于是就有本文的总结了。
1.1.1 Spring开发;
1.1.2 按照type来注入;
1.2.1 JDK开发;
1.2.2 按照名称注入,若无,则按type来注入(未指定name的情况下);
Data URL是在本地直接绘制图片,不是从服务器加载,所以节省了HTTP连接,起到加速网页的作用。
也无法获取到图片在服务器上的真实地址
注意:本方法适合于小图片,大图片就不要考虑了,另外IE8以下浏览器不支持这种方法。
用这种方法会加重客户端的CPU和内存负担,总之有利有弊。
前台代码:
<%@ page import="com.hisen.image.ShowImageByBase64" %><%-- |
后台代码:
package com.hisen.image; |
Apache Curator is a Java/JVM client library for Apache ZooKeeper, a distributed coordination service.
It includes a highlevel API framework and utilities to make using Apache ZooKeeper much easier and more reliable.
It also includes recipes for common use cases and extensions such as service discovery and a Java 8 asynchronous DSL.
特别说明:Guava is to Java What Curator is to ZooKeeper
后期补上自己的一些demo,其实官方文档已经介绍很全了
http://curator.apache.org/getting-started.html
了解这个客户端是在《从Paxos到Zookeeper:分布式一致性原理与实战》这本书里面看到的(书单)
Curator号称是世界上最好用的zk客户端,相比zkClinet来说拥有更好的封装
让我想起Redisson和Jedis的模样
昨天一个做移动端的前同事截图问我那些代码什么意思,用的就是Curator封装的分布式锁
相比于Redis分布式存在超时问题,zookeeper分布式锁利用临时节点可以避免
目前dubbo master上使用的是Curator 4.0.1
]]>这是一个菜鸟的脚本,执行命令应该是使用 & 连接,一个RUN命令搞定
FROM ubuntu |
Could not initialize class io.jsonwebtoken.impl.DefaultJwtBuilder |
原因,因为jackson-databindb版本冲突,直接去掉了依赖
jwt必须依赖Jackson所以报错了
出错时候的配置
<dependency> |
解决办法
<dependency> |
很多时候我们调用接口并不是需要接口返回的所有信息;
就像查询数据库很少使用 select * from table; 一样;
为了使现有的存储结构以及代码逻辑改动最少
想办法在最外层的接口对返回的对象进行精简
目的使为了提高接口性能:减少 RPC 传输时间、节省网络带宽、节省序列化开销
前面两种比较呆板,属于定制化开发;
Spring BeanWrapper 方案处理非集合对象比较完美,输出对象小不少;
基本数据类型有默认值,无法去除,不过这种对大小影响不大;
完整代码:github.com
public static void main(String[] args) { |
输出 src:
{ |
输出dst
{ |
目前 Spring BeanWrapper 处理集合类型比较费劲,需要告知一个个具体的路径
比如:productInfos[1].name
如果能做到 productInfos[any].name 这种,然后取出所有 index 的属性,就比较完美
(目前解决方法:通过自定义处理,遇到 any 标识,自动补全所有 index 的 key 即可,只是不那么优雅)
缺陷原因:内部逻辑直接用 key 转换为 index ,没有 any 逻辑。
else if (value instanceof List) { |
代码位置:org.springframework.beans.AbstractNestablePropertyAccessor#getPropertyValue
Spring 官方文档:Bean Manipulation and the BeanWrapper
]]>Debian 7.7、8.0
CentOS 7.X
Fedora 20、21、22
OracleLinux 6、7
安装方法:
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh - |
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
中文 | 英文 | 解释 |
---|---|---|
镜像 | Docker Images | Docker 镜像是用于创建 Docker 容器的模板。 |
容器 | Docker Container | 容器是独立运行的一个或一组应用。 |
客户端 | Docker Client | Docker 客户端通过命令行或者其他工具使用 Docker API (查看API) 与 Docker 的守护进程通信。 |
主机 | Docker Host | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
仓库 | Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(查看镜像) 提供了庞大的镜像集合供使用。 |
工具 | Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
hisen@hisen-pc:~$ wget -qO- https://get.docker.com/ | sh |
#启动 |
#启动某个指定的镜像,运行hello-world |
docker run ubuntu:15.10 /bin/echo “Hello world”
参数 | 解释 |
---|---|
docker | Docker 的二进制执行文件 |
run | 与前面的 docker 组合来运行一个容器 |
ubuntu:15.10 | 指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。 |
/bin/echo “Hello world” | 在启动的容器里执行的命令 |
以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果。
root@hisen-pc:/home/hisen# docker run -i -t ubuntu:15.10 /bin/bash |
-t:在新容器内指定一个伪终端或终端。
-i:允许你对容器内的标准输入 (STDIN) 进行交互。
root@hisen-pc:/home/hisen# docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done" |
后台启动完成,会返回一串容器的ID
##查看是否有容器启动 |
CONTAINER ID:容器ID(这里是:==8c2a84327360==)
NAMES:自动分配的容器名称
## 查看上面那个ID的容器的log |
docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。
## 调出帮助 |
运行一个 Python Flask 应用 来搭建一个web应用
## -d:让容器在后台运行。 |
0.0.0.0:32768->5000/tcp
docker使用的端口5000
映射到本地端口32768
本地可以访问:127.0.0.1:32768
## 访问:http://localhost:32768/ |
## 带上 -f 参数,动态输出日志 |
## top后面是跟着id或者name |
## 会输出一大串JSON形式的字符串 |
docker stop 0d68d3d4baf6 |
root@hisen-pc:/home/hisen# docker images |
## 获取一个镜像 |
新建一个配置文件:Dockerfile,并添加内容
每个指令都会在镜像上创建一个新的层
每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么
root@hisen-pc:/home/hisen# vi Dockerfile |
据我观察这个数据库可视化工具很不错,基于java
以各种驱动来连接数据库,也就是说java支持的数据库都可以用他连接
挺好用的,免费!!!
安装之后新建连接,选择你要链接的数据库,配置一下就好了。
#Shift + Home选中当前光标到行首 |
近几年一直在使用dubbo进行支付系统的开发;
作为国内比较受欢迎的一个SOA框架,Dubbo使用简单设计优雅;
里面用到的思想和技术,基本上涵盖大部分互联网公司用到的技术;
记得直属领导说过一句话,看完Dubbo他觉得设计者简直就是天才;
而且看完dubbo的源码,对他的影响很大,处处模仿dubbo的思想;
中文文档:用户文档、开发者指南、源码导读、运维管理
http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
用户手册(比较完整):
https://dubbo.gitbooks.io/dubbo-user-book/demos/routing-rule.html
官方博客:
http://dubbo.apache.org/zh-cn/blog/index.html
最后更新于2014年
https://javatar.iteye.com/
在各种系统需要加签的时
一般都会把参与签名的数据以get请求参数拼接起来
并且要求有序,这个方法会比较方便
public String getSortedStr(Map<String, String> unSortedStr) { |
private Map<String,String> getMapData(String getStr){ |
对于get类字符串没有发现比较好的方法转换为map
]]>最近做项目有一个地址库文件需要放在后端
由于文件在 jar 包中的问题,一些读取文件的姿势失效(方便的 Guava Files)
最后通过 getResourceAsStream 解决
接下来遇到了一件奇怪的事情,部分汉字乱码了,
调整编码,重新编辑汉字都试过了,无法解决。
最后求助于百度搜索,得到了一些有效的信息。
汉字是两个字节的,如果每次读固定个字节,可能会把汉字截断,造成乱码。
再次印证了基础知识的重要性!
private static String getAddressJson(String path) throws IOException { |
据说现在很多人没法纯手写通过流读取文件了…(说的就是我!)
private static String getAddressJson(String path) throws IOException { |
CSDN
]]>早几天在领导 JG 的朋友圈看到这篇文章
简单几个字的标题,让我产生了兴趣
一来这个标题是挺吸引人,典型的自媒体文章
二来JG 之前推过一些书很不错
三来一般领导朋友圈都不会推垃圾信息
全文看来其实感觉还是挺切合我的认知:
离开学校
大部分时间都是围绕着工作
有些人可能觉得当前的工作不满意
然后想着学点什么高大上的东西为以后的工作做准备
极端情况下这种选择是对的,大部分情况会让自己进退两难
正确的选择应该是:过好当下,瞭望远方,持续学习,总结反思,慢慢进步
架构师同事 SGLS 说过:做好当下的事情才是最重要的,不管现在是做什么项目,设计和实现是我们自己可以控制的。
以下为原文
审视是一个特别好的词。当一个人开始审视世界、审视经历、审视自己的时候,更容易做出有担当的选择。 |
什么是促使人成长的本质原因?
王慧文一直在渴求突破,也一直在探究这个问题。
王慧文修行的开端,就是校内网。
2006年3月,王慧文、王兴和另外四名同伴绞尽脑汁、黑白颠倒,终于让校内网收获了一百多万用户。
王兴开始四处找投资,但在多数投资人眼里看来,他们仍是群“生瓜蛋子”、“杂牌军”,校内网不过是几个大学生做的小打小闹的玩意儿。
但在这时,千橡集团董事长陈一舟出现了,他愿意拿出一千多万人民币,收购校内网。《九败一胜:美团创始人王兴创业十年》中这样描述
陈一舟说,如果你们不卖,我们可以拿这钱砸到市场上推广。当然,校内网的这群狂妄的小子被这句话激怒了,拒绝跟陈一舟谈。 |
不论校内网是成功的,还是失败的,在王慧文和王兴的心里,它永远都是遗憾的。
回首往事,王慧文已经不再执着,反而觉得这段遗憾对自己的人生是件好事。他说:
如果校内网做成了,我会变成让别人非常讨厌的人,刚愎、自负,因为挫折,所以我才懂得反省自己,能更理智客观冷静地看待自己。
还有人问王慧文,如果当初不卖的话,校内网能不能做得成?王慧文答:
这取决于我们遇到什么样的投资商,如果投资商能够在很多地方帮助我们,是可能做成的;如果投完钱就不怎么管,让我们自己随便搞,那就不行,因为我们还不够成熟。
管理者的自我反思,会反馈在他的战略、领导力、管理、业务实操等能力上。
人必须反思,是因为事物是时刻变化的,不断反思,才能不断跟上变化。
王慧文在一次采访中说:美团的持续高速增长,不是我们在推动着业务发展,而是业务快速发展,我们努力地跟上,不是我们做了什么事情,只是我们跟上了,没掉队。
在一个快速发展的行业里,在一个快速变化的时代里, 创业者、管理者如果没有自我反思,是很难生存下来的。
在第一次创业修行中,王慧文就悟出一个道理:人,把事做成不易,不断成长、突破自己边界更难。
“君子不器”是王慧文的人生原则之一。
2019年,在极客公园创新大会上,极客公园创始人、总裁张鹏问王慧文:你觉得美团的基因是什么?
王慧文当时就说出了“君子不器”四个字,他面对张鹏侃侃而谈:孔子说,君子不器,君子不是一个器皿,人不要搞自我定义,自我定义就是自我设限,我不倾向于用美团的基因来自我设限。
他还用“基因突变”举例,基因变化变错的概率比变对的概率高几百万倍,所以大家都很恐惧基因变化,抵触变化。
但王慧文认为变化不可怕,自我设限才最可怕,他还幽默地说:一旦变对了呢?一旦长出翅膀了呢?
这种不自我设限,就是“美团无边界,专注而不专一”的根源。
君子不器,有两个含义:
一是人想要成长就不能有固化思维,事物是变化的,人也要具备动态发展的眼光,反思过去,展望未来;
二是人不能像器皿那样自我设限,器皿只有某一方面的用途和才能,而人应该博学多识。
孔子的这两点要求,王慧文都做到了,他的生活和工作就是如此。
《财经天下》周刊记者朱晓培这样形容“百变的王慧文”
在王慧文的朋友圈里,总能看见他忽然想到一个问题,比如:是不是20世纪在唯心主义和唯物主义领域都没有出现过大师?如果地球上没有美洲,哥伦布的船直接西行到了亚洲,今天的世界格局又会是什么样子?为什么射雕英雄传的五绝里只有反派欧阳锋没有广招门徒? |
正如王慧文在内部信中所说,他个人的兴趣“散乱不稳定”。
当年创业时,王慧文和王兴都不会敲代码,但他们都觉得:没事,我们可以学。同样,后来在美团时,有一段时间王慧文要研究零售,他几乎每天都看一本关于零售的书,并且跟很多人谈论自己的心得。
王慧文敬佩爱因斯坦,爱因斯坦曾说:科学和艺术一样,都让我们的世界更加绚丽多彩。 |
王慧文从中体会到:爱因斯坦经常从艺术和审美的视角去探讨科学命题,人如果永远只站在一个视角来看待人生,人生就会变得特别狭隘,不够丰富,而站在不同视角来看待问题,不设限地长大,才非常重要。
不自我定义、不自我设限、不抗拒变化、不沉溺过去的王慧文,与“无边界”的美团极为匹配。
2012年底,美团实现盈亏平衡后,王慧文认为团购领域大局已定,又开始把目光聚焦在了外卖领域。 |
如果管理者认为自己就是一个器皿,那么你就会认为自己的状态永远不会改变,也没有改变的必要。如果王慧文这样想,就不会为美团的基业立下赫赫战功。
只有当你明白“君子不器”的道理时,才会意识到成长的必要性,也才会清醒地看到自己过去的弱点。
不自我设限,多元思考人生,始终相信自己有更多机会,这样的管理者才能持续地自我突破,才能在激烈的竞争中拼杀出属于自己的战场。
造就能征善战的王慧文
王慧文信奉曾国藩的九字箴言:练强兵,结硬寨,打呆仗。
“练强兵”很容易理解,当时清朝腐败,太平天国武装起义,清朝的正规军竟无力抵抗,只好调动地方军事力量,多亏有曾国藩统率的湘军,才能击败太平军。此后,湘军成为了清朝军事上强有力的骨干。
没有强兵,则无法作战。但强兵如何练成?
曾国藩治理湘军,主要凭思想纪律,而不是战术技巧。
王慧文“练强兵”,看重三点:人聪明,接地气,学习能力强(不是考试能力强)。
其次,王慧文主张:管理者的一个重要责任,就是——担当。
王慧文有一句话曾经火遍全网:
有担当的管理者,要把下属从“愚昧之巅”推向“绝望之谷”,至于下属能否爬上“开悟之坡”,看个人造化。
王慧文解释,这句话的核心词是“担当”。
他向来不喜欢说“责任”,因为他认为:责任可以逃避,只有有担当的管理者才不会逃避责任。
那么,什么是“愚昧之巅”、“绝望之谷”、“开悟之坡”?
这些词语源于 达克效应 ,王慧文说:我思考我个人的成长和周围同事的成长,每个人都希望自己最后成为智者(大师),但是,我们要承认一个事实,大部分人没有走上去。
愚昧之巅——人的智慧极低,但是自信度极高;
绝望之谷——认识到自己的不足,智慧有所增长,自信度大幅降低;
开悟之坡——智慧继续增长,自信度开始反弹增长;
持续平稳高原——智慧达到顶级,自信心也持续平稳,走上大师之路。
王慧文说:大部分人没能从愚昧之巅走到绝望之谷,大部分人都在这个部分遇到了困难。
王慧文借用“达克效应”理论,不是为了拆穿别人的智慧不足,而是为了强调管理者的担当,他认为:
大部分人都知道别人处在愚昧之巅,但是很少有人知道自己处在愚昧之巅,这就产生了非常大的信息不对称。 |
王慧文觉得他们在离开美团的环境后,很可能更没希望得到他人的有效反馈了,所以他有好几次,在同事或下属离职时,告诉了对方正处于愚昧之巅的真相,但是转眼就被拉黑了。
尽管王慧文承认他们是一个好人、正直的人,也是一个想成长的、对美团有过贡献的人,将来也会成为对社会有贡献的人,王慧文希望对方成长得更好,才戳破真相,但是要戳破真相、给他人有效反馈,就必须承担得罪人的风险。
也正因此,管理者才更需要担当。
王慧文说:你给别人反馈的时候,也可能你自己是一个傻×,可能我自己是在愚昧之巅,其实人家是对的,这个可能性也是很大的,通过这个行为反而证明了你可能在愚昧之巅的事实。
管理者能不能从善意出发,帮下属敲响警钟?又能不能在被误解时,甘愿承受来自下属的伤害?或者是在发现自己比下属更愚昧的时候,还能不能调整心态,通过努力学习来提升自己的智慧和自信?
回答这些问题的最好方式,就是努力向一个有担当的管理者去逼近。
担当,是管理者们最稀缺的能力,但却是“练强兵”必不可少的素质。
“结硬寨,打呆仗”,是曾国藩的兵法内核。字面意思是,把军营扎得坚如磐石,打仗时不讲究技巧而是追求笨方法。
曾国藩带兵打仗有个规矩,他到任何地方安营扎寨之后,不论当时是刮风还是下雨,首先命令士兵们挖掘战壕,壕深约两米,而且还要筑墙,墙高约八尺高,墙外再挖一道沟。这就确保整个营盘固若金汤。
湘军总是要挖沟、筑墙,行军速度非常慢。由于这种打法显得特别笨,所以才叫“结硬寨,打呆仗”。
王慧文的工作速度并不慢,但他也爱下笨功夫,一个细节一个细节得打磨,确保每个业务流程都能稳扎稳打。
美团前员工这样评价王慧文:老王可能是我见过在互联网行业,大佬级别中所谓“比你聪明还更拼搏”,并且会关注很多业务细节的人。
工作起来,王慧文就像变成了拼命三郎,让很多比他年轻的人都心生畏惧。
据美团前员工回忆:每周六下午,是大团队的业务管理会,每个分支业务的负责人要详细地讲解业务进度,用数据说话,以结果为导向,绝对不让周报变成“流水账”;
在这个过程中,王慧文会非常认真地听每个人的讲解,绝不走过场,绝不讲废话;
某个员工在周报中提及“某个数据变化属于正常波动”,这是产品负责人没有特别认真思考或经验欠缺、全局感不强而惯用的一个理由,而此时王慧文则会一针见血地指出是因为什么问题、什么原因导致的数据变化,让人心服口服。
王兴在内部信里这样评价王慧文:
美团精神,老王身体力行、堪称典范。回顾老王过去九年多的工作,既有冲锋在前的勇猛,又有安营扎寨的稳健;既有舍我其谁的担当,又有功成不必在我的潇洒;既有“天下兴亡,匹夫有责”的责任感,又有“我们什么都没有,但是我们有兄弟和勇气”的真性情;既长期有耐心地保持战略定力,又坚持时不我待、只争朝夕地忘情投入。 |
2013年6月,美团收购猛买网,猛买网创始人张智勇在加入美团之后,曾发微博说:牛x都是苦x堆出来的,你看美团网牛x,没看到的都是苦x。原来公司没有比它做得好,就是我不够苦x,是因为我管理不好。在这里,每月每周都能学到东西,蛮好的。辛苦没关系,能学到东西就行,最怕加班没结果。
对王慧文来说,周六全天开会,周日半天高管会,每周留给自己的时间或许只有一个下午而已。但王慧文向外界和美团内部员工展现的,永远是一副精力充沛、充满激情的样子。
这就像将军带兵打仗,“跟我上”和“给我上”,一字之差,但全军的战斗力却会有天壤之别。
前者能把团队里每个人的心思都拧成一股绳,无往不胜;后者却永远苦于团队像一盘散沙。
造就未来不可限量的王慧文
王慧文在今年年初的内部信里,把自己在美团拼搏的17年激情燃烧岁月,轻描淡写地说成了“我运气实在太好”。
低调、收敛,不是王慧文今天才有的风格,而是他始终具备的性格底色。
王慧文经常开玩笑地说,我是农民的孩子,只会拼命工作。玩笑的背后,是他专注做事的态度,以及不居功自傲的格局和胸襟。
管理者要常常怀有“清零思维”,过去的错误要变成未来的前车之鉴,不能用来惩罚自己;过去的成就要变成未来的经验和警示,不能用来炫耀自己、骄傲自满。
如果管理者觉得自己“满了”,也就意味着,你认为自己的成长之路到头了。
清零思维也是一种包容心。《九败一胜:美团创始人王兴创业十年》写道:王慧文曾去过无锡,见到88米高的灵山大佛,从远处看大佛,跟山一样高,走近大佛,人还没有大佛的脚趾头高。
王慧文心想,如果这尊大佛有脚臭的话,那么来观光的人就只能闻到大佛的脚臭味,而看不见整个大佛的巍巍如山。只有包容的人,心胸宽广,眼界开阔,才看得到大佛的宝相庄严。
该书的作者李志刚说:也只有包容的CEO,才能听到下面的真实心声,兼听则明,才能有各种奇人异士来帮你做事。
王慧文这17年来,已经为美团培养了大批人才,也为人才梯度建设付出了贡献,他离职后,自然也不需要人才来帮自己做事了,但是这种包容心会始终伴随他,让他的未来无法限量。
王慧文也包容对手,他和王兴都不认为美团是在跟同行们“争”,美团是在“竞”,他说:我们不认为千团大战是我们打赢了别人,而是我们跟上了行业节奏,他们没有跟上,这个认知是跟打仗不一样的;同向为竞,相向为争。
包容,就是不眷恋。
王慧文不眷恋名利荣誉,他说“我运气实在太好,不宜继续贪天之功,知止不殆”;
王慧文不眷恋自己的能力,他说“感谢我的家人,承受很多困难,无怨无尽地给我支持和包容”,还感谢了时代、王兴和所有同事;
王慧文不眷恋他的江湖,他说“美团十年,豪兴不浅。他日江湖相逢,再当杯酒言欢”。
金庸先生曾写:天上白云,散了又聚,聚了又散,人生离合,亦复如斯。
今天,我们预测王慧文的人生“下半场”会有怎样的风景,已经是徒劳,因为他早已选择了一条“不确定”的人生旅程。
王慧文说过,固定靶比移动靶更难打中。人生就像一个移动靶,我们谁也不知道自己的未来将穿梭至何处,也几乎不可能帮别人预测。
我们只能希望,当自己修炼出清零思维、包容心、不眷恋的人生态度时,能够跟上时代变化莫测的脚步,不要掉队。
不论人生的下半场将会如何,至少王慧文已经可以潇洒地说出一句——“这十年激烈精彩,不负年华”。
最近在做重构的项目
进入阶段性收尾阶段
总结记录下相关的内容
方便大家遇到类似问题可以想起有某个地方可以参考
目前的 AOP 应用,由于公司生态体系不够完善
利用 AOP + ThreadLocal(transmittable-thread-local,ttl)
做一部分链路追踪的事情( 耗时打印,traceId 处理 )
这部分倒是很简单,只是之前用的很少
PS:链路追踪蛮重要,针对排查问题,性能监控等大有帮助,多关注开源协议/实现( 如 CNCF )
目前做的项目当中,有一个 IDC 负载均衡的工具
有设置当前机器所属机房的方法,但是没有提供从配置文件读取的能力
因为 IDC 路由不生效,会造成跨机房访问,导致访问延迟偏高( 回头再写性能优化相关内容 )
当时发现这个问题的时候已经上线,以稳定性为主,不想升级 jar 版本
于是乎当时想通过 AOP 或者字节码的方式去做一个增强
当然,由于知识浅薄,AOP 写对了,但是不生效,工具初始化的先于 AOP 的作用时间。
接下来就通过搜索引起各种找,偶然发现 BeanPostProcess (之前也通过一些 spring 回调做应用预热)
于是就开始一番操作,果然给解决问题了。
public class Idc implements BeanPostProcessor { |
之前一直在做业务开发
也很少做从零到一的项目
即使看过一些 spring 的书籍和文档
但是还是没有理解太深,没有太注意
果然是书到用时方恨少哇,以后还是万事深挖一步
spring 生命周期,启动流程,各种回调,有必要看看,跑 demo 试试。
之前在linux shell用过tree命令感觉不错
发现Git Bash也可以实现,于是就记录一下
下载地址:点击前往
下载文件: Binaries Zip
解压文件:bin目录下找到tree.exe
把这个放到git安装目录下后的路径:C:\Program Files\Git\usr\bin\tree.exe
hisen@HiSEN MINGW64 /c/code/SpringBootCLI/myapp |
wget --no-check-certificate -O shadowsocks-libev-debian.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-libev-debian.sh |
默认设置:
服务器端口:自己设定(如不设定,默认为 8989) |
管理命令:
启动:/etc/init.d/shadowsocks start |
修改配置文件(端口、密码)
vi /etc/shadowsocks-libe/config.json |
卸载命令
./shadowsocks-libev-debian.sh uninstall |
工具类 就是封装平常用的方法,不需要你重复造轮子,节省开发人员时间,提高工作效率。谷歌作为大公司,当然会从日常的工作中提取中很多高效率的方法出来。所以就诞生了Guava。
高效设计良好的API,被Google的开发者设计,实现和使用
遵循高效的java语法实践
使代码更刻度,简洁,简单
节约时间,资源,提高生产力 Guava工程
包含了若干被Google的 Java项目广泛依赖 的核心库,例如:
public class CommonUsage { |
部分摘自:点击查看
]]>另外在使用上还有一些小的差异,比如:
在实现上两者已有一些差异,这里简单说明一下:
public Hashtable(int initialCapacity, float loadFactor) { |
HashTable中构造hash数组时initialCapacity默认大小是11,增加的方式是 old*2+1。HashMap中构造hash数组时initialCapacity默认大小是16,而且一定是2的指数。对于哈希值的使用也有所不同,HashTable直接使用对象的hashCode,代码是这样的:
int hash = key.hashCode(); |
而HashMap重新计算hash值,而且用与代替求模:
int hash = hash(k); |
仅供参考,内容来源于互联网
]]>Google公司的Bob lee开发的轻量级IoC容器,其特点是:
依赖
<dependency> |
测试类
public class HelloApp extends BaseServer { |
java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V |
github有人遇到同样的问题:https://github.com/SeleniumHQ/selenium/issues/3880
把本地的guava版本由19.0改为21.0成功解决问题
]]>也有自己安装插件,然后写js的,麻烦
后来找到两个插件,安装之后就搞定了
感谢开发的作者!!!
记得要在站点根目录执行下面的安装操作
1.安装 hexo-generator-search
npm install hexo-generator-searchdb --save |
2.安装 hexo-generator-searchdb
npm install hexo-generator-searchdb --save |
编辑站点文件_config.yml,添加以下内容开启搜索
search: |
编辑主题文件_config.yml,启用本地搜索功能:
# Local search
+local_search:
+ enable: true
+
第一次点击搜索的时候反应会比较慢
因为是要加载一个xml文件
]]>修改这个文件:
themes/landscape/layout/_partial/after-footer.ejs |
将17行左右的
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> |
改为
<script src="http://apps.bdimg.com/libs/jquery/2.0.3/jquery.min.js"></script> |
重新生成博客之后就把谷歌的cdn替换成百度的cdn了
]]>今天头给我们开会,说到团队对外沟通的问题。
谈到对外需要积极给人解决问题,而不是各种推脱,即使自己不知道,也可以给个眼神找到对的人。
继而谈到需要安排人轮流负责跟外部接洽
由于这个活呢,大伙儿认为不是什么好差事,那就抓阄决定吧
于是乎就感觉可以写一个简单的排班系统小bug,不过我这里只是提供一个简单的思路
主要的逻辑在这,当然并没有考虑数据持久化的问题
性能等其他的问题,纯粹是一个思路,用hashCode取模主要是打的比较散,很均匀
加上日期什么的,就一个排班表出来了。
/** |
记录类型 | 主机记录 | 记录值 |
---|---|---|
CNAME | @ | hisen-yuan.github.io |
主机记录:@ 代表顶级域名,例如hisen.me 如果想要www.hisen.me把@改成www
记录值:你的博客原始地址
3.在\blog\source下添加CNAME文件,没有后缀名,内容为你的域名,注意不要带http://
我的域名解析为 hisen.me 文件内容为 hisen.me
等待解析生效即可!
]]>发现百度搜索网址都搜索不到自己的站点
我只把hexo传到github上,然而去百度站长工具提交网址几条后也没有反应
我就测试了一下百度站长工具 - 抓取诊断
结果是抓取失败:Github把百度的爬虫给干掉了!所以。。。
具体内容如下:
提交网址: http://hisen.me/20170214-maven%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/ |
返回HTTP头:
HTTP/1.1 403 Forbidden |
通过搜索发现有不错的方法可以解决这个问题
那就是安装一个插件!名字叫:hexo-neat
命令行进入博客根目录,执行以下命令
npm install hexo-neat --save |
如果使用的是淘宝的cnmp执行以下命令
cnpm install hexo-neat --save |
#hexo-neat 优化提速插件 |
安装好之后,就直接正常使用(跟以前没有装的时候一样使用),
重新生成博客就可以发现html源码已经压缩了
只是在生成博客的过程中可能要浪费一丁点时间
访问速度有所提升!
参考:点击查看
]]>通过Oracle VM VirtualBox端口转发,连接了虚拟机的MongoDB
1.用idea创建一个maven项目
2.在pom.xml中添加mongodb java驱动
<dependency> |
3.参考官方:MongoDB Driver Quick Tour
本用例github地址:mongodbTest
package com.hisen.jdbc; |
包含全球200+国家和地区的信息
本列表属于之前有外国人整理过
利用有道翻译API翻译了国家名
涉及到全球的业务应该会用的上
SET FOREIGN_KEY_CHECKS=0; |
1,AF,AFG,AFGHANISTAN,阿富汗,Afghanistan,4,93 |
来帮助我们消除一些必须有但看起来很臃肿的代码
比如属性的get/set,及对象的toString等方法,特别是相对于 POJO;
原来的代码用了lombok简单注解
比如maven的pom.xml文件有如下配置
<dependency> |
安装lombok plugin
装完插件之后就舒服了,也不报错
]]>[Byte Buddy] BEFORE_INSTALL net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer@87f383f on sun.instrument.InstrumentationImpl@4eb7f003 |
/** |
会改变程序执行的堆栈
/** |
不会改变代码堆栈流
这种方式也可以增强系统类
/** |
然后就在研究怎么方便的写博客
首先就是找了几款markdown编辑器,发现GitHub出品的Atom还不错
插件很丰富,然而下载了第一个terminal插件但是无效,一度折腾了很久
后来搜索了一下,发现这个插件很不错:platformio-ide-terminal
利用快捷键:control + 点(1左边那个)
就可以在当前界面呼出终端,而且是当前目录
也就是在_post目录下,写完了之后执行命令就上传了
还是很方便的。后续还需要慢慢熟悉更多的插件与工具
]]>failed to read artifact descriptor for xxx:jar |
一下午那代码里面是各种报错
凡是引入的大部分都报错
原因就是maven管理的jar没有添加上依赖
最后在stackoverflow找到了良药
上面有图片,错误会详细一点,如果你的也相同,可以试一试
maven project -> Execute Maven Goal -> mvn -U clean install |
执行以上命令之后等待完成,应该就好了
参考自stackoverflow:点击查看
]]>我发现居然每次新open一个项目就得配置下maven
因为默认的maven配置文件不行,我自定义的文件用的是阿里云的镜像
那样快一点,于是很郁闷,决定要搞定他!!!
结果这样设置就可以了,全局设置。
File--->Other Setting--->Default Setting |
接下来的设置就是一样的了,各种设置都可以,只要你想全局生效
]]>快捷键设置:file->setting->Keymap->Main menu->Code->Completion->Basic
找到之后右键Add keyboard Shortcut,然后按下:Ctrl + 逗号
一、idea配置文件
\HOME\IntelliJ IDEA 2016.3.4\bin\idea64.exe.vmoptions |
增加一行:-Dfile.encoding=UTF-8
二、编译参数
File -> Settings -> Build, Execution, Deployment |
在空格里面添加:-encoding utf-8
三、工程编码
File -> Settings -> Editor -> File Encodings |
此页面三个地方都选择UTF-8
四、tomcat参数
Run/debug Configuration tomcat |
VM options:-Dfile.encoding=UTF-8
保存一份google code的xml,链接有最新的
intellij-java-google-style.xml
设置方法如下:Setting -> Editor -> Code Stytle -> Java
最后一步就选择你存放之前保存的xml
然后就大功告成,来个对比
前
package com.hisen.json; |
后
package com.hisen.json; |
在使用的过程中发现,搜索框历史、提交svn后的消息提示乱码
最后发现是由于更改了idea界面的字体,字体对中文支持不佳导致
解决办法:更改为支持中文的字体(比如:微软雅黑 Microsoft YaHei)
设置路径:Settings -> Appearance & Behavior -> UI Options -> override default fonts by
选择何时的字体即可,也可以把勾勾去掉,使用默认的。
]]>在idea中也可以,而且还比较高级,哈哈
idea -> 右上角 -> Edit -> Column Selection Mode -> 移动光标到你想要弄的行
完事在重复一次,就可以退出列编辑模式
]]>Alt+回车 导入包,自动修正
Ctrl+N 查找类
Ctrl+Shift+N 查找文件
Ctrl+Alt+L 格式化代码
Ctrl+Alt+O 优化导入的类和包
Alt+Insert 生成代码(如get,set方法,构造函数等)
Ctrl+E或者Alt+Shift+C 最近更改的代码
Ctrl+R 替换文本
Ctrl+F 查找文本
Ctrl+Shift+Space 自动补全代码
Ctrl+空格 代码提示
Ctrl+Alt+Space 类名或接口名提示
Ctrl+P 方法参数提示
Ctrl+Shift+Alt+N 查找类中的方法或变量
Alt+Shift+C 对比最近修改的代码
Shift+F6 重构-重命名
Ctrl+Shift+先上键
Ctrl+X 删除行
Ctrl+D 复制行
Ctrl+/ 或 Ctrl+Shift+/ 注释(// 或者/…/ )
Ctrl+J 自动代码
Ctrl+E 最近打开的文件
Ctrl+H 显示类结构图
Ctrl+Q 显示注释文档
Alt+F1 查找代码所在位置
Alt+1 快速打开或隐藏工程面板
Ctrl+Alt+ left/right 返回至上次浏览的位置
Alt+ left/right 切换代码视图
Alt+ Up/Down 在方法间快速移动定位
Ctrl+Shift+Up/Down 代码向上/下移动。
F2 或Shift+F2 高亮错误或警告快速定位
代码标签输入完成后,按Tab,生成代码。
选中文本,按Ctrl+Shift+F7 ,高亮显示所有该文本,按Esc高亮消失。
Ctrl+W 选中代码,连续按会有其他效果
选中文本,按Alt+F3 ,逐个往下查找相同文本,并高亮显示。
Ctrl+Up/Down 光标跳转到第一行或最后一行下
Ctrl+B 快速打开光标处的类或方法
]]>可以根据数据库中表结构自动生成CRUD代码,可以满足大部分需求。
MyBatis Generator (MBG) 是一个Mybatis的代码生成器 ,
可以根据数据库中表结构自动生成简单的CRUD(插入,查询,更新,删除)操作。
但联合查询和存储过程,需手动手写SQL和对象。
PS:配置过程中请注意自己的工程目录结构
<plugin> |
resources下建generatorConfig.xml,作为mybatis-generator-maven-plugin插件的执行目标。
<?xml version="1.0" encoding="UTF-8"?> |
MyBatis Generator生成代码的运行方式:命令行、使用Ant、使用Maven、Java编码。
本文采用Maven插件mybatis-generator-maven-plugin来运行MyBatis Generator,用的是命令行的方式。
配置插件
选择目录,输入命令:mybatis-generator:generate -e
找到插件。双击执行
即可看到生成的文件
JWT(json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。
欲加密的字符:hisen
加密后的字符:(分三段)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoiXCJoaXNlblwiIiwiZXhwIjoxNTAyOTY0Mjk2fQ.gzg4JEm8Z-GoU9eNaNll9I1wQQ0cEAbZC9OBUjAAQqI |
完整的头部,json格式:
{ |
然后对头部进行base64加密,构成第一段:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 |
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
{ |
然后对头部进行base64加密,构成第二段:
eyJwYXlsb2FkIjoiXCJoaXNlblwiIiwiZXhwIjoxNTAyOTY0Mjk2fQ |
jwt的第三部分是一个签证信息,这个签证信息由三部分组成
gzg4JEm8Z-GoU9eNaNll9I1wQQ0cEAbZC9OBUjAAQqI |
密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和验证,所以需要保护好。
<dependency> |
// 加密,传入一个对象和有效期 |
// 解密,传入一个加密后的token字符串和解密后的类型 |
基于JWT token认证 | JSON Web Tokens | java-jwt 3.2.0 | demo
JWT官方网站:https://jwt.io/
]]><!-- POI start --> |
package com.hisen.jars.poi; |
package com.hisen.jars.poi; |
Tomcat只分配了非常小的PermGen内存,这里重新设置一下
直接在配置tomcat的时候,在VM options填入:
-XX:PermSize=97m -XX:MaxPermSize=256m |
最近在看代码,发现一个 Date 格式化为 String 的方法。
public String dateFormatString() { |
看到这个方法想到
带着以上三个疑问,就想着做个对比测试。
恰巧最近在 perfma 社区看 jvm 相关内容时,刷到了『性能调优必备利器之 JMH』
优点:不用自己写相关统计代码,而且统计方式有多种
性能从低到高
Benchmark Mode Cnt Score Error Units |
说明:
Error 列是空的,看 Score 和 Units 即可
ops/s:一秒钟执行多少次操作
<dependency> |
插件中心搜索:JMH
安装量最高的那个就是
import org.apache.commons.lang.time.DateFormatUtils; |
安装了 JMH 插件之后,直接对着类名右键,选择运行即可。
JMH 会默认执行当前类下面的所有的基准测试。
ETA 00:10:50 代表整个测试需要近11分钟
# JMH version: 1.23 |
<使用new关键字创建对象> |
package com.hisen.javaGaiShu.page73test5; |
作用是有助于系统的垂直拆分,使系统更易拓展。
Java中的RPC框架比较多,各有特色,广泛使用的有RMI、Hessian、Dubbo等。
RPC还有一个特点就是能够跨语言,本文只以JAVA语言里的RPC为例。
其他的框架结构也类似,区别在于对象的序列化方法,传输对象的通讯协议,
以及注册中心的管理与failover设计(利用zookeeper)。
客户端和服务端可以运行在不同的JVM中,Client只需要引入接口,
接口的实现以及运行时需要的数据都在Server端,RPC的主要依赖技术是序列化、反序列化和传输协议,
JAVA里对应的就是对象的序列化、反序列化以及序列化后数据的传输。
RMI的序列化和反序列化是JAVA自带的,Hessian里的序列化和反序列化是私有的,传输协议则是HTTP,
Dubbo的序列化可以多种选择,一般使用Hessian的序列化协议,传输则是TCP协议,使用了高性能的NIO框架Netty。
对于序列化,我还了解一些,像Google的ProBuffer、JBoss Marshalling和Apache Thrift等
JAVA自带的远程方法调用工具,不过有一定的局限性,
毕竟是JAVA语言最开始时的设计,后来很多框架的原理都基于RMI,RMI的使用如下:
对外接口
public interface IService extends Remote { |
import java.rmi.RemoteException; |
RMI客户端
|
RMI服务端
|
服务注册管理器写在了Server里,当然也可以抽出来单独作为一个服务,
在其他一些框架中,往往用Zookeeper充当注册管理角色。
基于HTTP协议传输,在性能方面还不够完美,负载均衡和失效转移依赖于应用的负载均衡器,
Hessian的使用则与RMI类似,区别在于淡化了Registry的角色,通过显示的地址调用,
利用HessianProxyFactory根据配置的地址create一个代理对象,另外还要引入Hessian的Jar包。
基于Netty的高性能RPC框架,是阿里巴巴开源的,总体原理如下:
在了解Dubbo之前,要先对Zookeeper有深入的理解,当理解了zookeeper后,Dubbo也就了无秘密了。
Dubbo的详细说明在淘宝开源里说的非常详细,在工作中很多生产项目都用了Dubbo,过程中也发现了很多需要注意的地方.
]]>常见参数:
垃圾回收器:
各个区大小比例建议
# 活跃空间大小:Full GC后堆中老年代占用空间的大小 |
1.1 https://www.cnblogs.com/honey01/p/9475726.html
1.2 https://www.cnblogs.com/dolphin0520/p/3783345.html
2.1 https://tech.meituan.com/2017/12/29/jvm-optimize.html
真实的目录结构如下:
C:\1\hisenyuan\build.png |
压缩包的目录结构如下:
build.png |
package com.hisen.utils; |
sh:代表上海市场
sz:代表深圳市场
后面是加上股票代码,这是因为上海和深圳的股票代码有重复的
http://hq.sinajs.cn/list=sh600877 |
返回的信息
var hq_str_sh600877="中国嘉陵,6.340,6.400,6.360,6.470,6.210,6.340,6.350,15012913,95227966.000,56500,6.340,12100,6.330,16100,6.320,17500,6.310,47400,6.300,13600,6.350,11300,6.360,32400,6.370,39100,6.380,41200,6.390,2017-04-27,15:00:00,00"; |
有效信息为引号里面的数据
下面的数字代表分割数组后所在的下标
下面是数据字段对应的含义
位置 | 含义 | 测试数据 |
---|---|---|
0 | 股票名字 | 中国嘉陵 |
1 | 今日开盘价 | 6.340 |
2 | 昨日收盘价 | 6.400 |
3 | 当前价格 | 6.360 |
4 | 今日最高价 | 6.470 |
5 | 今日最低价 | 6.210 |
6 | 买一报价 | 6.340 |
7 | 卖一报价 | 6.350 |
8 | 成交数量(百股) | 15012913 |
9 | 成交金额(元) | 95227966.000 |
10 | 买一数量(股) | 56500 |
11 | 买一报价 | 6.340 |
12 | 买二数量(股) | 12100 |
13 | 买二报价 | 6.330 |
14 | 买三数量(股) | 16100 |
15 | 买三报价 | 6.320 |
16 | 买四数量(股) | 17500 |
17 | 买四报价 | 6.310 |
18 | 买五数量(股) | 47400 |
19 | 买五报价 | 6.300 |
20 | 卖一数量(股) | 13600 |
21 | 卖一报价 | 6.350 |
22 | 卖二数量(股) | 11300 |
23 | 卖二报价 | 6.360 |
24 | 卖三数量(股) | 32400 |
25 | 卖三报价 | 6.370 |
26 | 卖四数量(股) | 39100 |
27 | 卖四报价 | 6.380 |
28 | 卖五数量(股) | 41200 |
29 | 卖五报价 | 6.390 |
30 | 当前日期 | 2017-04-27 |
31 | 当前时间 | 15:00:00 |
32 | 未知 | 00 |
要想从事企业级的项目开发,你必须掌握如下要点:
没有人愿意自己一辈子就满足于掌握了一些代码实现的技巧,
别人告诉你要实现什么,你就用代码堆砌来实现别人的要求!
你必须学会从整个项目的角度去思考!
你必须学会假如你是项目经理,你该如何思考!
你必须学会假如你是架构师,你该如何思考!
你必须掌握针对某个特定问题领域的分析方法!
HttpServlet、doGet、doPost、HttpServletRequest、HttpServletResponse、request.getParameter()、request.setAttribute()、request.getAttribute()、request.getSession()、ServletContext、Filter、web.xml、tomcat、forward与redirect、http协议的无状态性、cookie、JSP Scope Object、<c:out …/>、<c:forEach …>
HTML与JavaScript:你需要能够理解常见的网页标签、理解在网页中引入JavaScript的方法、以及JavaScript的基本语法与使用方法
以上,就是你进一步学习Java所必备的基本知识。
特别是一些个专业术语和名词,看到这些名词,如果你像看到亲爹一样亲切,
那么说明你对Java的基础知识就很熟悉了,记住,仅仅是熟悉了
对于初学者来说,这三大框架被赋予了太多神秘的色彩,似乎它们是重中之重的知识!但是对于拥有多年Java开发经验的专业技术人员来说,对于那些Java牛人来说,却对这三大框架不太感冒!难道它们不重要吗?
现在很多企业都在用这三大框架,所以很多企业也把掌握这三大框架作为招聘的必备条件。不可否认的是,也有很多大型企业没有用这三大框架,这些企业经过多年发展,自身已经有一定的技术积累,也形成了自己独特的技术框架体系。这三大框架既可以说很重要,也可以说不重要。
说重要的原因在于:这三大框架对JavaEE开发中所存在的普遍的问题,提供了优美的解决方案,它们蕴含了这个行业中最NB的开发人员的努力和想法,所以,学习这三大框架,你就可以窥探到这些处于技术巅峰的牛人们究竟对一个问题是怎么想的,通过一种什么样的设计思路去解决问题的。所以,对于你来说,你没有太多项目开发的经验,经验是什么?经验就是你知道可能会遇到哪些问题,针对哪个问题可以有哪些解决方法,在某个情景下,哪种解决方法是较好的,哪种方法不太好等等!如果你没做过什么项目,你根本就不会去意识到你可能会遇到哪些问题,而这些问题往往又是非常关键的!解决得不好,会影响到你的程序的稳定性、可扩展性等等!三大框架就给初学者提供了了解你以后可能会遇到哪些问题,以及针对这些问题的解决方案!
当你了解了这三大框架为什么是重要的,那么你也就能理解,为什么这三大框架也可以说是不重要的。如果你曾经开发过很多项目,你碰到了各种各样的问题,凭着你的技术功底,逐个击破了这些问题,在这些人眼里,三大框架(是不是还有N个框架?呵呵)都是浮云!
你属于哪一种人呢?如果你没有太多项目开发经验,那么三大框架对于你来说就是非常重要的!而且,由此你也知道了该怎么去学这三大框架。对于三大框架的学习而言,着力点在于给你展示问题,并触发你自己主动的思考,我们鼓励你提出自己的想法,也许你的想法很白痴,但那毕竟是你自己的想法,如果你不知道牛人的想法,那你怎么知道自己的想法是很白痴的呢?在这种思想的碰撞过程中,你就会逐渐提高自己!所以,三大框架学完之后,你不应该只是看到一大堆配置文件,你不应该只是看到了一些Action,一些Service,一些映射文件,你不应该只知道session.save/update/delete,你不应该只是知道struts2中有一堆interceptor,你不应该只是看到一堆jar包……
如果你只是知道拷贝一堆jar包,定义一系列配置文件之后,SSH三大框架就能够运行起来了,也可以给你干活了,那么,很悲哀的是,你仍然没有掌握三大框架的精粹!请你回答以下问题:
Struts2:
Spring:
Hibernate:
以上并非SSH中全部重点的问题,但它们能考察你能否灵活运用SSH框架!如果你能深刻理解这些问题,再配以合适的实战项目训练,你也会逐渐成为牛人!
不管你是学Java还是别的技术,你的根本目的在于给客户创造价值!否则,你下大力气学习的东西,随着技术的进步和更新,很快就会过时!所以,技术的核心在于用技术创造有价值的成果!也就是说,客户需要什么,你就要用技术把客户需要的东西给他造出来!一个公司之所以要用各种福利条件极力挽留你,是因为你能够给公司带来极高的利益!那么,你有什么可以给公司利用的呢?公司最看重你的哪方面的能力呢?
做项目需要的能力很多,其中最核心最基础的就是建模能力(现在最主流的就是面向对象建模!)。什么是建模能力呢?
我给大家一个面试题:
一个保险公司的保险卡管理模块:销售人员领取保险卡信息(保险卡数量、卡号、领取日期),然后直接销售给客户,销售完毕后,将保险卡信息录入保险公司系统内部(销售人员信息、购买人信息、购买的保险卡数量、卡号等),客户登录保险公司网站激活保险卡,需要填写(保险卡卡号、激活密码、被保险人信息、受益人信息)
要求就是:如果这个模块交给你来做,你要怎么做?你要解决哪些问题?你可否画个图,给我描述一下你的想法是什么吗?
这只是一个面试题而已,因为只有简单几句话,所以我把它放到这里,让大家感受一下所谓建模要解决什么问题。而业务领域的问题实在是太多了!也许一个几十上百页的需求文档才能把某个业务领域的问题描述清楚,而你的职责就是要把它们实现出来!
某个公司要开发一个考勤管理系统,要求与现有的人力资源系统对接,你是主要的技术负责人,那么,你要做哪些工作呢?
某ERP项目要实现一个排班管理模块,交给你去完成,你如何去完成呢?
不要抱怨项目经理给你的信息太少(只有几句话),不要抱怨客户没有描述清楚他们的需求……你的价值就在于理顺所有的问题,用各种手段获得你想要的信息,按照一定的思路汇总,并在特定的时间里逐个解决它!
你应该意识到学Java不是一个坦克大战、一个网络飞车、一个CMS、一个DRP、一个OA那么简单,你不要沉迷于那些技术细节(虽然也是有必要的,但不要钻牛角尖),不要满足于实现了CRUD式的项目需求(虽然这是基础中的基础),在你的前方,永远有一个目标在那里,需要你去努力追赶!
今后你将面对更加繁杂的需求,你学习项目的唯一目的,就是:学习如何将需求转化为实现,如何对需求进行分析,如何建立概念模型,如何理顺各种概念之间的关系,如何进行设计,如何选择合适的技术来实现你的设计方案,如何对你的实现进行测试,如何解决你所遇到的形形色色的问题(性能、需求变更等)。当你真正到公司里面从事了几年开发之后,你就会同意我的说法!
利用Java找工作,需要的就是项目经验,项目经验就是理解项目开发的基本过程,理解项目的分析方法,理解项目的设计思路,理解项目的实现技巧,理解项目的测试方法,理解项目中各种问题的解决方案。
码农只是复制粘贴,并不注重原理,说不出所以然,所以做了几年还只能是码农。
加油,共勉!
]]>这里讲述的是第一次出生的过程,即之前class没有被加载。
1.1.1.1 通过类的全限定名获取定义此类的二进制字节流(可以从zip包、网络、运行时动态生成);
1.1.1.2 将这个字节流所代表的静态存储结构转化为方法去运行时数据结构;
1.1.1.3 在内存(方法区)中生成一个代表这个类的java.lang.Class对象,作为方法区这个类各种数据访问的入口;
1.1.2.1.1 魔数是否以0xCAFEEBABE开头(咖啡宝贝)
1.1.2.1.2 主、次版本号是否在当前虚拟机处理的范围之内(不同的jdk版本编译出来的版本不一致,可向前兼容)
1.1.2.1.3 常量池是否有不被支持的类型(检查常量tag标志)
1.1.2.1.4 指向常量的各种索引值是否指向不存在或者不符合类型的常量
1.1.2.1.5 CONSTANT_Utf8_info型的常量中是否有不符合UTF-8编码的数据
1.1.2.1.6 Class文件中各个部分以及文件本身是否有被删除或者附加的其它信息
…
这些操作是为了确保Class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身安全
1.1.2.2.1 是否有父类(Object除外)
1.1.2.2.2 是否继续了不允许继承的类(被final修饰的)
1.1.2.2.3 如果当前不是抽象类,是否实现了其父类或接口中要求实现的所有方法
1.1.2.2.4 类中的字段、方法是否与父类产生矛盾(如覆盖父类final字段、不合法的重载)
这些操作是对字节码进行语义分析,确保符合Java语言规范要求
1.1.2.3.1 确保操作数栈的数据类型与指令代码序列能完美配合(反例:操作数栈为int,使用的时候按long加载)
1.1.2.3.2 确保跳转指令不会跳转到方法体以外的字节码指令上
1.1.2.3.3 确保方法体重点类型转换是有效的
这些操作主要是通过数据流和控制流分析,确定程序的语义是合法的、符合逻辑的。
JDK1.6之后有一个优化,利用StackMapTable来验证是否合法
1.1.2.4.1 符号引用中通过字符串描述的全限定名是否能找到对应的类
1.1.2.4.2 符号引用中的类、字段、方法是否可以被当前类访问
在将符号引用转化为直接引用的时候触发符号引用验证
1.1.3.1 仅为类变量分配内存,并且赋值为初始值,例如int为0(被static修饰的)
1.1.3.2 特殊情况,被final修饰的static变量会直接赋值为代码给定的值
准备阶段是正式为类变量分配内存并设置类变量初始值,这些变量所使用的内存都将在方法区中进行分配。
虚拟机将常量池中的符号引用替换为直接引用
符号引用:一组用来描述所引用目标的符号,所引用的目标不一定在内存中
直接引用:直接指向目标的指针、相对偏移量、能间接定位到句柄,直接引用的目标必须在内存中存在
<client>()方法:由编译器自动收集类中所有变量的赋值动作和静态语句块(static{}块)中的语句合并产生
按顺序收集。父类的此方法先执行,虚拟机会保证线程安全
真正开始执行类中定义的Java代码,
指针碰撞:内存规整的,中间指针划分已用、空闲,那么分配就是指针向空闲一方移动对象大小相等的距离
空闲列表:内存不规整,用列表维护一个可用内存地址,从列表中找出一个合适大小的空间分配给实例
<init>()方法:实例构造器
类的初始化是指类加载过程中的初始化阶段对类变量按照程序猿的意图进行赋值的过程;
类的实例化是指在类完全加载到内存中后创建对象的过程。
听候线程的指令,执行相关方法
可达性分析算法:从GC Root节点开始向下搜索,搜索所走过的引用链为引用链,当没有任何引用链时说明对象不可达
经历过两次不可达标记才会被标记为可回收
堆内存回收主要发生在堆上的新生代,为Minor GC,使用的是复制算法
新生代分为:Eden、to Survivor、from Survivor,后两者为Survivor,三者的比例为8:1:1
在Minor GC之前,to Survivor为空,对象存在:Eden、from Survivor
在Minor GC执行
Eden存活着的对象拷贝到to Survivor,同一时候对象年龄+1
from Survivor区中的幸存对象会考虑对象年龄
假设年龄没达到阈值,对象依旧拷贝到to survivor中
假设对象达到阈值那么将被移到老年代
复制阶段完毕后,Eden和from幸存区中仅仅保存死对象,能够视为清空
假设在复制过程中to幸存区被填满了,剩余的对象将被放到老年代
在Minor GC之后
from survivor和to survivor会调换一下名字,下次Minor GC时,to survivor变为from Survivor
目前写的不是太完善,有机会写的透彻明白一些。
]]>总能发现以前自己没有怎么在意的细节
静态代码块是在类中独立于类成员的static语句块,可以有多个。
如果要初始化静态变量,可以声明一个静态块。
格式如下:
static { |
静态块存在单独的内存中,仅在该类被加载时执行,示例如下:
package com.hisen.javaGaiShu.page91test20; |
我学习了很多语言 |
静态代码块在运行main方法时可以直接调用而不用创建实例。
静态代码块直接是按顺序执行的。
]]>相对地把一个汉字所占的位置称为”全角”。在汉字输入时,系统提供”半角”和”全角”两种不同的输入状态,
但是对于英文字母、符号和数字这些通用字符就不同于汉字,在半角状态它们被作为英文字符处理;
而在全角状态,它们又可作为中文字符处理。
半角和全角切换方法:单击输入法工具条上的按钮或按键盘上的Shift+Space键来切换。
1、全角:指一个字符占用两个标准字符位置。
汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都是全角字符。一般的系统命令是不用全角字符的,只是在作文字处理时才会使用全角字符。
2、半角:指一字符占用一个标准的字符位置。
通常的英文字母、数字键、符号键都是半角的,半角的显示内码都是一个字节。在系统内部,以上三种字符是作为基本代码处理的,所以用户输入命令和参数时一般都使用半角。
3、全角与半角各在什么情况下使用?
全角占两个字节,半角占一个字节。
半角全角主要是针对标点符号来说的,全角标点占两个字节,半角占一个字节,而不管是半角还是全角,汉字都还是要占两个字节。
在编程序的源代码中只能使用半角标点(不包括字符串内部的数据)
在不支持汉字等语言的计算机上只能使用半角标点(其实这种情况根本就不存在半角全角的概念)
对于大多数字体来说,全角看起来比半角大,当然这不是本质区别了。
4、全角和半角的区别
全角就是字母和数字等与汉字占等宽位置的字。半角就是ASCII方式的字符,
在没有汉字输入法起做用的时候输入的字母数字和字符都是半角的。
在汉字输入法出现的时候,输入的字母数字默认为半角,但是标点则是默认为全角,
可以通过鼠标点击输入法工具条上的相应按钮来改变。
5、关于“全角”和“半角”:
全角:是指中GB2312-80(《信息交换用汉字编码字符集·基本集》)中的各种符号。
半角:是指英文件ASCII码中的各种符号。
全角状态下字母、数字符号等都会占两个字节的位置,也就是一个汉字那么宽,半角状态下,
字母数字符号一般会占一个字节,也就是半个汉字的位置,全角半角对汉字没有影响。
有两种方式可以判断:
1:通过正则表达式来进行判断 [^\x00-\xff]
2: 通过字符编码的范围进行判断.
通过打印所有的字符发现:
package com.hisen.String; |
$ more sort.log | awk '{print $1}' | sort | uniq -c | sort -k1nr | head -3 |
more:一次读取少量的数据,避免一次性载入大文件,比cat好些
awk ‘{print $1}’:以awk默认的分隔符,并且打印第一列
sort:把上一步的结果按ASCII排序
uniq -c:如果重复那么计数,uniq命令可以组合很多其它参数
sort -k1nr:根据第一列的数据进行排序,n是按数值大小排序,r是倒序排序
head -3:显示前面三行数据
$ cat sort.log |
redis.clients.jedis.exceptions.JedisConnectionException:java.net.SocketException:Software caused connection abort: recv failed
我是windows上java运行,然后redis是在虚拟机的,通过映射访问
编辑redis配置文件:
sudo vi /etc/redis/redis.conf |
找到
bind 127.0.0.1 |
改成
bind 0.0.0.0 |
改完之后重启redis
service redis restart |
即可。这跟mysql一样,允许任何ip连接!
]]>等号后面的为需要翻译的英文
http://fanyi.youdao.com/openapi.do?keyfrom=xinlei&key=759115437&type=data&doctype=json&version=1.1&q=hisen |
把全世界200+国家和地区的名字翻译为英文,并且入库
@Autowired |
所有基本数据类型的大小(所占用的字节数)都是明确规定好的,
在各种平台上都保持不变,这一特性有助于提高Java程序的可移植性。
引用数据类型包括字符串、数组、类和接口。
引用数据类型是用户自定义、用来限制其他数据类型。
引用数据类型的变量在内存中存储的是数据的引用,并不是数据本身,
引用类型是使用间接方法去获取数据
java中int为什么占用4个字节?
回答1:
现在流行的编译器,都是规定的int是四个字节~
像tc这样老版的编译器,int才是两个字节,
然后也是一样,由于一个字节占八位,最高为符号位,又人为规定,1000000000000000……这个补码编码为-2^31所以,范围就是-2^31~2^31-1
回答2:
JAVA是采用Unicode编码。每一个字节占8位。
你电脑系统应该是32位系统(工具),这样每个int就是 4个字节
其中一个字节由8个二进制位组成
回答3:
int常见为4个字节,跟操作系统有关系。
turbo c(以及Turbo c的一些衍生编译器,他们用的一套编译程序)是dos时代的编译器,
是上世纪80年代的产物,严重过时,属于老掉牙的产品,
他们编译出来的程序是16位操作系统dos下的程序,所以长度为16位,即两个字节。
windows为了兼容dos,所以turbo c生成的文件也可以在windows中运行。
其他一般就都是4个字节了。
操作系统16位的时候,int 2字节,操作系统32位的时候,int 4字节,由于32位系统之前占主流地位,实际现在就算是64位系统,出于兼容性考虑,int也是4字节的
grep -r hisen ./ |
上面这条命令。直接查找当前目录下所有内容中包含 hisen 的文件
]]>亲测有效:2017年2月13日 18:07:25
邮箱:
Soar360@live.com |
GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M5SN6bnxn2kSE8qHqNY5QaaRxmO3YSMHxlv2EYpjdwLcPwfeTG7kUdnhKE0vVy4RidP6Y2wZ0q74f47fzsZo45JE2hfQBFi2O9Jldjp1mW8HUpTtLA2a5/sQytXJUQl/QKO0jUQY4pa5CCx20sV1ClOTZtAGngSOJtIOFXK599sBr5aIEFyH0K7H4BoNMiiDMnxt1rD8Vb/ikJdhGMMQr0R4B+L3nWU97eaVPTRKfWGDE8/eAgKzpGwrQQoDh+nzX1xoVQ8NAuH+s4UcSeQ== |
yourPath\maven-3.3.9\conf\settings.xml |
找到里面的,添加镜像即可
<mirrors> |
这里写的是被镜像的ID
如果写成:* (星号)
所有的请求都会到这个镜像上,包括各种本地库
注意:千万不要配成
否则内网的仓库或者你配的镜像里面没有一下jar包的时候不会去别的地方搜索
<!--阿里云:速度挺快--> |
顺便用博客记录下,mongodb系列应该会有几篇记录
本篇具体代码:SampleMongoTestNo1.java
1、环境介绍
mongodb安装教程:点击查看
DataBase:MongoDB V 3.2 |
2、初始化连接
private Mongo mg = null; |
3、关闭连接
@After |
/** |
2019
1.【完成】换一份合适的工作
2.【完成】信息系统项目管理师
3.【完成】坚持阅读,数量质量超过2018
2020
1.羽毛球/骑行/等锻炼项目
2.通过一项含金量较高的考试项目
3.持续阅读/5本华章CS/其它不限
4.深入了解公司内部组件/知其所以然
2019预料之中夹着惊喜,正反馈激励我前行。
2020充实得度过每一天,有所追求有所进步。
自己想要什么样的生活?
最近几年一直在思考这两个问题
如今已经慢慢勾勒出了自己想要的生活
大概就是舒服的活着,向身边人学习,帮助他人成长,体现自己的社会价值(马斯洛需求层次理论的4~5之间)
想清楚自己想要什么样的生活之后
接下来就是给自己设定一系列目标
例如:长期目标、5年规划、3年规划
抛砖引玉:
全部书单
从17年开始阅读量稍微上来一点到如今已经走过了快3个年头
在阅读中观摩了不少他人的经历、接触了各种不同的思维方式、看了很多恍然大悟的见解、领略了技术的魅力
有一句话说的不错:书是一面镜子,折射出一个人的方方面面
翻越自己的书单,也能看到一个变化的过程,从兴趣开始,逐步转向个人提升以及对精神世界的追求
目前发现不少的书籍内容有部分的”重叠”,所以有些书还是看的比较快,有些书值得重复阅读,特别是技术书
2019 Top8 (非权威排行)
《贫穷的本质》
《重塑大脑,重塑人生》
《领域驱动设计》(系列)
《代码简洁之道:程序员的职业素养》
《枪炮、病菌与钢铁:人类社会的命运》
《可伸缩服务架构:框架与中间件》
《Java并发编程的艺术》
《深入理解Java虚拟机》
关键字:绿植、养鱼、骑行、羽毛球、辣椒
绿植和养鱼
看书累了/下班回家浇浇水赏赏鱼放空下自己挺好
偶尔还会收获成长的喜悦、以及把控感
骑行和羽毛球
运动方面实际行动比较多的今年是羽毛球
技术不咋地,野路子,打算2020培训下
骑行看季节看队友,春秋时节郊区遛遛挺好
辣椒
作为一个江西人,应该是无辣不欢的体质,无惧新型社交绝症
2019
起床:06:30
午休:20分钟
入睡:01:00
2020
起床:05:00
午休:20分钟
入睡:23:30
起床热身,煮早餐,基本上八点半左右出门
步行过程中耳机听互联网广播(目前是:36氪随身听)
地铁上耳机切换至音乐模式看书(kindle/纸书)
2020走养生路线,早睡早起!
中午看20分钟的书
早上看约1~3小时
晚上看书0~1小时
关注周围的事情,了解动态,吸取营养,输出影响力
表A:id,name
表B:id,其他,name(新增字段)
A,B表通过id关联,要把A的name给对应的B的name
以前也没有写过这种update语句
update 表名 set 字段名=字段值 where 条件 |
技术方面今年感觉成长不是太明显
有所改变的是会深入洞察需求
逐步完善设计之后开始 coding,而不是着急开始。
本年度阅读图书 38 本
由于上半年部分时间在准备换工作
以及 6 月份换了工作之后花在工作的时间比较多
所以今年的阅读量下降地厉害,但是还是会坚持每天都翻几页
收获较多的为以下几本:
唯一的变化可能是多了 2 只鳄鱼龟。
夜深人静之时,回到家,给乌龟喂食互动下也挺有意思。
下半年由于工作原因,晚睡较多,很少早起。
需要找准自己的节奏,调节步伐,逐步早起。
这些年能坚持下来的也就只有下面两个了~
其它的可能不太适合长时间跟踪
插播:Java8 对List进行求和、分组、提取对象单个属性:https://www.jianshu.com/p/c71eaeaaf30c
下面的例子仅供参考
github:https://github.com/hisenyuan
package com.hisen.collection.list.duplicate; |
#开启远程登录 |
cd %userprofile%\.m2\repository |
或者新建一个bat文件,批处理。就不用每次都在cmd敲命令了
@echo off |
linux系统
find /app/maven/localRepository -name "*.lastUpdated" -exec grep -q "Could not transfer" {} \; -print -exec rm {} \; |
表示如果cola为空,赋值为0
在mysql中的具体实现如下,
mysql> describe book; |
需求是:查找出每个年级,年纪最大的人的名字。
个人的思维只停留在
mysql> select name, max(age),grade from stu group by grade; |
折腾了一会自己不知道怎么解决,后来倒是解决了。
具体过程如下:
mysql> describe stu; |
现在想把第一行的数据导入到第二行,具体如下
mysql> describe employees; |
employees数据库中的employees表有30万数据
我想把这个数据导出到另外一个数据库hisen中的employee表中
mysql> create table hisen.employee as( |
这种操作是针对所有字段都导出的情形,创建表跟插入数据合二为一
如果导出部分字段或者有其他限制条件写sql即可
这应该是最简单的方法~
]]>在关键字之前加上:BINARY,会使关键字强制转换为二进制字符串
select id form t where chinese like **BINARY** %汉字% |
把关键字的类型改成:BINARY
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '2039-01-07 12:58:20.625' for column |
由于程序没有控制好,计算下一次更新时间失误,造成数值过大。
update table_a |
以下是MySQL官方的说法,就是时间超过了范围。
The TIMESTAMP data type is used for values that contain both date and time parts. |
--找出重复 |
这条命令的输出结果能够让我们了解MySQL 优化器是如何执行
执行下面的SQL
explain select * FROM book where name like '活%' |
得到下面的数据
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
编号 | 查询方式 | 表名 | 分区 | 连接方式 | 索引(可能) | 索引 | 索引长度 | 作用列 | 行数 | 百分比 | 额外 |
1 | SIMPLE | book | null | ALL | null | null | null | null | 114 | 11.11 | Using where |
#创建个人信息表 |
###执行计划样例
explain select zipcode,firstname,lastname from hisen_test_explain_people; |
###参考
]]>tail -100 /access.log |
2、进入目录相关
#进入一个目录 |
3、看倒数多少行
#看倒数10行 |
4、过滤特定行,保存结果到新文件
cat /root/old.text | grep -v "yourstring"> /root/new.text |
在resources文件夹下新建:generatorConfig.xml
内容如下:注意修改包名等信息
<?xml version="1.0" encoding="UTF-8"?> |
在pom.xml中添加如下内容:plugins节点内
<build> |
在idea调出mavenProject界面,选择plugins,找到mybatis-generator,双击即可
]]>select res.*, CONCAT(truncate((res.succ / res.`all`) * 100, 2), '%') as 'success rate' |
USER_NO | TYPE | all | succ | fail | other | success rate |
---|---|---|---|---|---|---|
456 | 10 | 1 | 0 | 0 | 1 | 0.00% |
123 | 10 | 29 | 23 | 0 | 6 | 79.31% |
mysql> describe post; |
mysql> alter table post add index index_post_title (title); |
mysql> drop index index_post_title on post; |
mysql> select count(title) from post group by title; |
官网介绍:Employees Sample Database
表名 | 中文 |
---|---|
department | 部门表 |
dept_emp | 部门员工任职期表(按部门&时期) |
dept_manager | 部门经理任职期表(按时期) |
employees | 员工详情表 |
salaries | 员工薪资表(按时期) |
title | 员工职称表(按时期) |
一、导入数据库操作过程
#ubuntu apt-get 安装的mysql默认的配置文件 |
练习题:点击查看练习题
]]>id | name |
---|---|
1 | hisen |
2 | hisen |
3 | hisen |
4 | hisenyuan |
5 | hisenyuan |
删除重复的name,保留id最小的。
思路就是先找出重复数据,然后再找出需要保留的数据(重复中id最小的)
然后删除id不在需要保留的id中的所有数据
delete |
maven项目,启动tomcat的时候报错:
No MyBatis mapper was found in '[com.hisen.dao]' package |
这是由于把mybatis的mapper配置文件放在了java代码的目录下
├── java |
这是因为mapper文件的路径问题:maven在打包的时候默认是认为src/main/java目录下只有java源代码,不会管xml文件。
Java 项目分为两个部分,一个是源码,一个是资源,在使用maven等构建工具时,
默认会将源码编译后再加上资源目录的文件放到target目录下作为最后运行的文件(可以是war,jar,或者目录)。
有时为了方便,我们会在src/main/java源码目录下放了资源文件,例如mybatis的mapper文件,方便我们编程时展开查看。
这时,我们需要设置编译时也将这些配置文件放到target目录下,否则最后的target目录式没有这些文件的。
在项目的pom文件里面配置,让maven也从src/main/java目录下读取xml配置文件
<build> |
如果是把mapper文件什么的放在resources目录下
但是为了分类建了不同的文件夹,也需要修改配置文件,不然会读取不到
<build> |
里面含有几十万条数据。
找了好久也没有找到比较匹配的题目
就找了个匹配度比较高的题来练习,如果你还没有导入Employees Sample Database
请参考:点击导入Employees
本次操作在Xshell中完成,也就是mysql命令行。
#登陆数据库 |
建议看看输出的结果自己写下sql,不要单纯的复制粘贴。
#1.查找整个职员表的所有内容。 |
以下是安装步骤
#下载(官网为:http://mama.indstate.edu/users/ice/tree/) |
最简单的使用方法,在目录下输入:tree
使用效果
hisen@ubuntu:~/dl$ tree |
使用参数
tree命令行参数: |
OpenWrt 官方关于 netgear r8000 的信息
https://openwrt.org/toh/netgear/r8000
“Second data partition (79 MiB) not available in OpenWrt”
128M 的空间,安装 OpenWrt 之后就剩下 21M 的空间可以安装插件
那自然是不够用的了,于是乎就找了些扩大空间的办法,最靠谱的就是利用U盘挂载
插上 U盘 至 USB3 插口
登录 OpenWrt 控制台,查看 USB 在 OpenWrt 中的名称
也就是 /dev/sda
root@OpenWrt:~# cat /proc/scsi/usb-storage/0 |
安装相关软件
因为需要格式化 U盘 至 ext4 的格式
以及挂载U盘空间至 overlay
root@OpenWrt:~# opkg update && opkg install block-mount e2fsprogs kmod-fs-ext4 kmod-usb-storage kmod-usb2 kmod-usb3 |
格式化 U盘 至 ext4
root@OpenWrt:~# mkfs.ext4 /dev/sda |
挂载 U盘 至 overlay
重启之后,就大功告成
放心地去安装各种插件吧
root@OpenWrt:~# mount /dev/sda /mnt |
最近看了不少软路由的东西
于是折腾了一波 OpenWrt
奈何网件 R8000 配置一般,跑起来体验不好。
后续估计是会上 x86 主机了,虽然可能会性能过剩。
在官方原版的 OpenWrt 22.03 版本中
如果直接在 software 中安装 luci_app_passwall
那么安装后会提示没法实现透明代理,还需要安装一些额外的软件才行
opkg install ipset ipt2socks iptables iptables-mod-conntrack-extra iptables-mod-iprange iptables-mod-socket iptables-mod-tproxy kmod-ipt-nat |
安装完成之后,再按教程操作即可.
原因就是新版本的系统中默认不包含上述模块。
问题解决参考自 GitHub issue.
没想到安装之后发现一直没法让VirtualBox隐藏到托盘
按正常程序走,打开一个虚拟机会出现两个GUI界面:
第一个可以在打开虚拟机之后关闭,第二个不能关闭也不能隐藏到托盘
痛苦!!!
这里给出解决方案:通过cmd命令行启动并且后台运行
C:\tool\Oracle\VirtualBox> |
C:\tool\Oracle\VirtualBox>VBoxManage list vms |
前面是NAME,后面是UUID,之后的name用这连个代替都可以
C:\tool\Oracle\VirtualBox>VBoxManage startvm "ubuntu" --type headless |
headless是在后台运行,并且默认开启vrdp服务,可以通过远程桌面工具来访问
下面是打开ubuntu之后用Xshell链接的
Connecting to 127.0.0.1:2222... |
下面所有的NAME都可以用二中的name和UUID代替
# 列出所有安装的虚拟机 |
以前没有遇到过,就搜索了一下,找了一会给找到了
select to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss ff') from dual; |
输出:年-月-日 时:分:秒 微秒
2017-9-24 10:38:27 129368 |
很少问题是搜索引擎找不到的,学会如何描述问题才是关键
]]>只在基于规则的优化器中有效,ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.
ORACLE采用自下而上(从后往前)的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾
ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.需要什么字段就查询什么字段,永远不要查询出不需要的字段来
ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等;尽量使用缓存技术;
在SQLPlus , SQLForms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表,因为decode函数有短路效应,类似java中短路与,有合适的就会返回而不继续扫描后面的内容
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系),原因见[4]
因为这里使用的是rowid
DELETE |
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. (注: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:
COMMIT所释放的资源:
避免使用HAVING子句, HAVING在检索出所有记录后对结果集进行过滤。这个处理需要排序,总计等操作。 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. (非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里
在含有子查询的SQL语句中,要特别注意减少对表的查询。例子:
SELECT TAB_NAME |
复杂的SQL往往牺牲了执行效率。能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。一般把复杂的sql分解再拼起来。
当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率。在子查询中,NOT IN子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历).。为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.
高效:
SELECT * |
低效:
SELECT * |
虽然目前各种关于SQL优化的图形化工具层出不穷
但是写出自己的SQL工具来解决问题始终是一个最好的方法:
SELECT EXECUTIONS, |
索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构。通常,通过索引查询数据比全表扫描要快。 当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引。同样在联结多个表时使用索引也可以提高效率。另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证。那些LONG或LONG RAW数据类型,你可以索引几乎所有的列。 通常,在大型表中使用索引特别有效。当然,你也会发现,在扫描小表时,使用索引同样能提高效率。虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O 。 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的。
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME> |
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。一般可以考虑用EXIST替换,EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。
低效:
SELECT DISTINCT DEPT_NO, |
高效:
SELECT DEPT_NO, |
因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行
一般来说StringBuilder(非线程安全)是一个不错的选择
我们要避免在索引列上使用NOT,NOT会产生在和在索引列上使用函数相同的影响。当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描。
WHERE子句中,如果索引列是函数的一部分。优化器将不使用索引而使用全表扫描。
举例:
低效:
SELECT … FROM DEPT WHERE SAL * 12 > 25000; |
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12; |
高效:
SELECT * FROM EMP WHERE DEPTNO >=4 |
低效:
SELECT * FROM EMP WHERE DEPTNO >3 |
两者的区别在于,前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。
通常情况下,用UNION替换WHERE子句中的OR将会起到较好的效果。对索引列使用OR将造成全表扫描。注意,以上规则只针对多个索引列有效。如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低。在下面的例子中, LOC_ID 和REGION上都建有索引。
高效:
SELECT LOC_ID, |
低效:
SELECT LOC_ID, |
如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面
这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的。
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30 |
高效:
SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30); |
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。对于单列索引,如果列包含空值,索引中将不存在此记录。对于复合索引,如果每个列都为空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中。
举例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入)。然而如果所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空。 因此你可以插入1000 条具有相同键值的记录,当然它们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引。
低效: (索引失效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL; |
高效: (索引有效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0; |
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引。这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引
当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序。如果用UNION ALL替代UNION, 这样排序就不是必要了。效率就会因此得到提高。需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录。因此各位还是要从业务需求分析使用UNION ALL的可行性。 UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存。对于这块内存的优化也是相当重要的。下面的SQL可以用来查询排序的消耗量。
低效:
SELECT ACCT_NUM, |
高效:
SELECT ACCT_NUM, |
ORDER BY 子句只在两种严格的条件下使用索引
ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序
ORDER BY中所有的列必须定义为非空
WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列
例如:
表DEPT包含以下列:
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效: (索引不被使用)
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE |
高效: (使用索引)
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0 |
当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换
假设 EMPNO是一个数值类型的索引列.
SELECT … FROM EMP WHERE EMPNO = '123' |
实际上,经过ORACLE类型转换, 语句转化为:
SELECT … FROM EMP WHERE EMPNO = TO_NUMBER('123') |
幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变
现在,假设EMP_TYPE是一个字符类型的索引列
SELECT … FROM EMP WHERE EMP_TYPE = 123 |
这个语句被ORACLE转换为:
SELECT … FROM EMP WHERETO_NUMBER(EMP_TYPE)=123 |
因为内部发生的类型转换, 这个索引将不会被用到!
为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来。 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型
某些SELECT 语句中的WHERE子句不使用索引
这里有一些例子
在下面的例子里,
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎
执行耗费资源的排序(SORT)功能。
DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序。
通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写。
如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑的, 毕竟它们的可读性很强。
提高GROUP BY 语句的效率,可以通过将不需要的记录在GROUP BY 之前过滤掉。
下面两个查询返回相同结果但第二个明显就快了许多。
低效:
SELECT JOB, |
高效:
SELECT JOB, |
本文参考其他文章整理而来
出处:http://www.cnblogs.com/rootq/archive/2008/11/17/1334727.html
不过互联网上这篇文章很多,都没有版权注明。我也不知道原创是谁!
]]>现在暂时使用 in 代替解决了
下面的查询是能限制住acct_type
SELECT ew.customer_id,cf.acct_type |
但是在update的时候,会把acct_type=1的也更新了
update ew_quota_info ew |
这里有一个简单的对比,情况相同的时候,两个sql的时间相差八倍
优:0.077s
SELECT ew.all_amt , |
劣:0.630s
SELECT ew.all_amt , |
上述原因:where子句从后往前执行,应该把大的过滤条件放在后面
记录时间:2017年3月9日 10:44:59
√:可能会出现
×:为不会出现
name | 名称 | 级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
Read uncommitted | 读未提交 | 1 | √ | √ | √ |
Read committed | 读提交 | 2 | × | √ | √ |
Repeatable read | 重复读 | 3 | × | × | √ |
Serializable | 序列化 | 4 | × | × | × |
Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE.
Oracle 默认的事务隔离级别为: READ COMMITED
Mysql 支持 4 中事务隔离级别.
Mysql 默认的事务隔离级别为: REPEATABLE READ
http://blog.csdn.net/u014044812/article/details/51004754
http://blog.csdn.net/bitcarmanlee/article/details/51004767 (含流程图)
]]>declare |
select * |
第二种:
select * |
第三种:
select * |
它支持运行Groovy脚本,这也就意味着你可以使用类似Java的语法,但不用写很多的模板代码。
Spring Boot不一定非要配合CLI使用,但它绝对是Spring应用取得进展的最快方式.
spring --version |
文件名称:HelloController.groovy
文件内容:
@RestController |
运行程序:cmd进入文件所在文件夹,执行:spring run HelloController.groovy
提醒:Resolving dependencies第一次初始化时间会久一点,耐心等待
spring run HelloController.groovy |
之后在浏览器中输入:http://localhost:8080/
就能看到:Hello World
]]>--显示数据库当前连接数 |
答:Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,
它们可以储存和操作字符串。其中String是只读字符串,
也就意味着String引用的字符串内容是不能被改变的。
而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改。
StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,
区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,
因此它的效率也比StringBuffer要高。
简而言之:
String:不能被修改
StringBuffer:可以随意修改,有synchronized修饰,是线程安全的,效率略低
StringBuilder:可以随意修改,无synchronized修饰,不是线程安全的,效率高
classStringEqualTest { |
存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。
String的intern()方法就是扩充常量池的一个方法;
当一个String实例str调用intern()方法时,
Java查找常量池中是否有相同Unicode的字符串常量,
如果有,则返回其的引用,
如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用
什么情况下用+运算符进行字符串连接比调用StringBuffer/StringBuilder对象的append方法连接字符串性能更好?
答:
如果使用少量的字符串操作,使用 (+运算符)连接字符串;
如果频繁的对大量字符串进行操作,则使用
1:全局变量或者需要多线程支持则使用StringBuffer;
2:局部变量或者单线程不涉及线程安全则使有StringBuilder。
]]>翻看书签的时候偶然发现 RASP 两个收藏
脑子里毫无相关内容,细看之下,收获不小
ps:是不是看看收藏夹,能有意外收获
安全无小事,从点滴做起。要有安全意识。
安全投入的比例,可以根据公司所处的行业公司规模进行相应调整。
安全投入包括:软件安全设计、招人、买设备、买服务、做评估。
RASP( Runtime Application Self-Protection )是一种在运行时检测攻击并且进行自我保护的一种技术。
化繁为简,抓住事情的本质,这就是优势。
做一件事,方式方法有很多,最终的目的都一样。
对于安全来说,攻击方式千变万化,但是”攻击动作”万变不离其宗。
RASP 通过监控”攻击动作”进行自我保护,而不是对攻击方式的识别与防御。
攻击动作
当发生 SQL 注入攻击时,WAF 和 IDS 只能看到 HTTP 请求。
而 RASP 不但能看到完整 SQL 语句,还可以和 HTTP 请求关联,
并结合语义引擎、用户输入识别等能力,实现对 SQL 注入的检测。
ps:WAF 可以理解为安全网关,门卫。IDS 入侵检测系统。
由于某种原因,需要手工处理错误日志提取某些信息。
下载下来的日志文件是压缩包
system_error.log.2020-11-01.20201105200433.zip |
$ unzip -v system_error.log.2020-11-01.20201105200830.zip |
压缩包文件名不一样,但是压缩包中的文件有一样的名字。
例如:system_error.log.2020-11-01
尝试使用如下方式,提示有重复,需要挨个选择如何处理,极度不便。
于是想使用 shell 来解决( 之前没写过 shell )
提示有文件重复,需要处理。
$ unzip '*.zip' |
尝试使用 -n 参数,不覆盖
$ unzip -n '*.zip' |
-n 表示不覆盖,有重名的直接跳过,结果就是 100 个文件只解压的 10 个。
mv A B |
怎么拿到压缩包内的文件名?
# 输出压缩包内的信息 |
1.3 的问题解决了就可以开始写脚本
文件名 uf.sh
!/bin/sh |
注意,目前在目标目录下才能正确运行
chmod 775 uf.sh |
然后解决问题,解压所有 100 个压缩包,并且得到 100 个文件(文件名为 1~100)。
不得不说解决问题是最快的学习方式
第一次写脚本相对耗时,也是一个不错的尝试过程。
对linux系统相关的命令/函数不熟悉,导致到处查资料,有必要系统化的看看书。
Registration successful |
Product Code:
4t46t6vydkvsxekkvf3fjnpzy5wbuhphqz |
serial Number:
601769 |
password:
xs374ca |
需求就是正常情况下能redirect到指定的页面
异常的情况下,能够返回JSON格式的错误信息
正常情况和异常情况都需要设置HTTP Code
"/test", method = RequestMethod.POST) (value = |
前面的例子我们使用的视图技术主要是JSP。JSP的优点是它是Java EE容器的一部分,几乎所有java EE服务器都支持JSP。缺点就是它在视图表现方面的功能很少,假如我们想迭代一个数组之类的,只能使用<% %>来包括Java语句进行。虽然有标准标签库(JSTL)的补足,但是使用仍然不太方便。另外JSP只能在Java EE容器中使用,如果我们希望渲染电子邮件之类的,JSP就无能为力了。
Java生态圈广泛,自然有很多视图框架,除了JSP之外,还有Freemarker、Velocity、Thymeleaf等很多框架。Thymeleaf的优点是它是基于HTML的,即使视图没有渲染成功,也是一个标准的HTML页面。因此它的可读性很不错,也可以作为设计原型来使用。而且它是完全独立于java ee容器的,意味着我们可以在任何需要渲染HTML的地方使用Thymeleaf。
Thymeleaf也提供了spring的支持,我们可以非常方便的在Spring配置文件中声明Thymeleaf Beans,然后用它们渲染视图。
引入依赖
<!--thymeleaf模版 spring4.x--> |
配置ViewResolver(在spring的xml文件里)
<!-- 配置ViewResolver 使用:thymeleaf 模版引擎--> |
接下来就可以直接使用了,跟之前的jsp没有什么不同
"/listpageplug/{start}", method = RequestMethod.GET) (value = |
到这里就改造完了,接下来就是Thymeleaf的各种用法了
这里举一个循环遍历的例子,后台返回了books对象集合
<!--判断是否为空--> |
解压之后在bin目录下执行
sudo sh idea.sh |
就会进入安装程序,接下来会跳出图形界面,跟windows差不多的步骤
没有激活码可以看之前的文章
关键的一个是我发现网上说的建立桌面快捷方式不行
就这样弄个方便的
cd ~ |
利用redis操作的原子性,实现java 多线程并发的情况下实现计数器。
我本机测试多个线程操作之后,结果会出现一定的延迟,但是最终数字是ok的
应该是redis内部做了一个类似于队列的功能。
需要注意的是,得使用redis连接的线程池,不然会出现异常
这里有一个:JedisUtil 下面用到了
package com.hisen.thread.count_click_by_redis; |
package com.hisen.thread.count_click_by_redis; |
2.3 主线程 - 启动类
package com.hisen.thread.count_click_by_redis; |
package com.hisen.interview; |
redis服务路径: /etc/init.d/redis-server
默认是开机启动
#安装 |
业务当中多处用到线程池进行异步处理;
为了得知线程池设置是否合理,故需要增加线程池监控;
常见的实现方式:
本文使用1的方式实现,主要是方便进行配置,可以托管多个任务;
taskName:pool1-monitor. taskCount:820, completedTaskCount:820, largestPoolSize:30, poolSize:30, activeCount:0, corePoolSize:30, maximumPoolSize:50, queueSize:0 |
package com.hisen.thread.monitor.threadpool; |
<!-- ### 线程池监控 开始 ### --> |
sudo apt-get install zookeeper |
默认信息
#安装路径 |
hisen@hisen-server:/usr/share/zookeeper/bin$ sudo sh zkServer.sh |
如果报错
zkServer.sh: 81: /home/xxx/zookeeper-3.4.6/bin/zkEnv.sh: Syntax error: "(" unexpected (expecting "fi") |
hisen@hisen-server:/usr/share/zookeeper/bin$ sudozkCli.sh -server localhost:2181 |
出现上面的信息说明成功了
1.创建配置文件
sudo vi /etc/init.d/zookeeper |
添加以下信息,注意自己的相关路径是否相同,不同修改之
#!/bin/sh |
2.授权
sudo chmod +x zookeeper |
3.安装开机启动管理软件(一般自带)
sudo apt-get install rcconf |
4.进入管理界面
sudo rcconf |
↑ ↓ 移动光标,空格键选中zookeeper
Tab 使光标移动到OK 回车即可
]]>三步完成之后即可!
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse |
到了图形化界面,打开terminal(终端)执行
sudo init 3 |
就会跳转到命令行界面,并且只有命令行
就是一个全屏的terminal。
在安装ubuntu的时候,有选择是否安装图形化界面的选项,选择不安装,那么系统将不带有图形化界面而默认进入命令行界面。
直接安装Ubuntu Server,目前我就是这样
不过装了之后还是推荐第三个方法!!!
]]>只有自己设置的非root的帐号和密码
但是又要用root密码怎么办呢?
hisen@ubuntu-1:~$ sudo passwd |
上面输入的密码就是你的root密码
检测一下
hisen@ubuntu-1:~$ su |
通过,至此结束
]]>1 > 添加 MongoDB 公共GPG钥匙
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 |
2 > 创建列表文件
这里把官网repo.mongodb.org
换成了mirrors.aliyun.com
echo "deb http://mirrors.aliyun.com/mongodb/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list |
3 > 重新加载本地包数据库
sudo apt-get update |
4 > 安装MongoDB
sudo apt-get install -y mongodb-org |
5 > 启动MongoDB
sudo service mongod start |
6 > 打开MongoDB客户端
sudo mongo |
7 > 关闭MongoDB
sudo service mongod stop |
展示一下
hisen@hisen-server:~$ sudo service mongod start |
安装成功
MongoDB默认的数据文件和日志文件分别存储在下面的位置
数据文件:/var/lib/mongodb
日志文件:/var/log/mongodb
你可以修改/etc/mongod.conf 文件来改变相应的存储位置。
如果你想改变运行MongoDB的用户
你必须把 /var/lib/mongodb
和 /var/log/mongodb 2个目录的访问权限付给该用户
1允许远程访问
绑定ip
$ sudo vim /etc/mongod.conf |
打开配置文件,添加需要增加的
不建议采用注释掉 bindIP 的方案,非常容易受到攻击
# network interfaces |
接受所有ip
重启
$ sudo service mongod restart |
2.配置防火墙 (不配置也行)
Ubuntu16.04 桌面版默认没有安装好 ipTable,用如下命令安装
sudo apt-get update |
安装过程中,弹窗选择YES
安装完成后:
sudo iptables -A INPUT -p tcp --dport 27017 -j ACCEPT |
1.安装
sudo apt-get install mysql-server |
等待完成即可,过程中需要设置密码
2.查看是否成功
sudo netstat -tap | grep mysql |
3.登陆mysql
mysql -u root -p |
这条命令回车之后需要输入mysql密码
$ sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf |
重启:service mysql restart
接下来就可以在navicat里面连接了
因为在网上找的很多教程,都是说改这个配置文件:这个是错误的
/etc/mysql/my.cf |
如果是通过apt-get方式安装的,默认的是第二步那个配置文件
]]>准备工作:
目录约定:
说明以上路径都是解压之后的,请解压之后自行重命名文件夹等工作
下面开始配置环境变量:
sudo vi /etc/profile |
底部添加:
#java的环境变量配置 |
让刚刚的配置生效:
source /etc/profile |
查看maven
mvn -v |
查看java版本
java -version |
如果还是默认的OpenJDK
sudo update-alternatives --install /usr/bin/java java /usr/hisen/soft/java/jdk8/bin/java 300 |
进入tomcat的bin目录
sudo vi catalina.sh |
顶部添加
#让tomcat知道java在哪里 |
之后进入在tomcat bin目录执行
hisen@hisen:/usr/hisen/soft/tomcat/tomcat8/bin$ sudo sh startup.sh |
如果没有在 catalina.sh 添加java路径,会报错
hisen@hisen-VirtualBox:/usr/hisen/soft/tomcat/tomcat8/bin$ sudo sh startup.sh |
Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,
第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,
因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
说明:这只是一个初步的安装,后续进一步实践
#安装gcc g++的依赖库 |
#启动 |
安装之后就直接监听80端口,浏览器打开127.0.0.1即可访问出现如下页面:
Application Server was not connected before run configuration stop, |
我遇到这个问题一般是这些原因:
这是下VM option中加了:-URIEncoding=UTF-8
Error: Could not create the Java Virtual Machine. |
如果还未安装jdk、maven建议查看教程:点击查看
git clone -b develop https://github.com/apache/incubator-rocketmq.git |
Start Name Server
nohup sh bin/mqnamesrv & |
Start Broker
nohup sh bin/mqbroker -n localhost:9876 & |
Send & Receive Messages
Before sending/receiving messages, we need to tell clients the location of name servers. RocketMQ provides multiple ways to achieve this. For simplicity, we use environment variable NAMESRV_ADDR |
Shutdown Servers
sh bin/mqshutdown broker |
实现命令
find . -type f -size +100M -exec mv {} /tmp/ \; |
find 查找
. 当前目录
-type 文件类型:f 文件,d 目录
-size 文件大小:+100M +:大于 -:小于 空:等于
-exec 管道命令,将前面的查询结果传递给后面的命令
{} 指前面传递过来的的查询结果
\; 结束管道命令
这里我就说一下今天我安装的方法。
下载好ubuntu的镜像,随便放在一个非系统盘的根目录下
改名为:ubuntu.iso
sudo chmod 777 /boot/grub/grub.cfg |
保存退出,重启就会进入系统。
桌面上点击那个安装的图标即可完成重装
]]>这种配置下,虚拟机能上网,又能跟win连接,感觉很完美
VirtualBox的端口转发很不错,可以转发tomcat什么的
1.给Ubuntu安装openssh-server
sudo apt-get install openssh-server |
2.查看虚拟机ip 我的是:10.0.2.15(看上面那段)
hisen@hisen-VirtualBox:/$ ifconfig -a |
名称 | 协议 | 主机IP | 主机端口 | 子系统IP | 子系统端口 |
---|---|---|---|---|---|
ssh | TCP | 127.0.0.1 | 2222 | 10.0.2.15 | 22 |
子系统ip写你的虚拟机ip即可
在xshell链接Ubuntu虚拟机的时候
ip写上麦的主机ip:127.0.0.1
端口写上面的主机端口:2222
然后上面配置的端口转发就可以转发到虚拟机上,顺利连接!!!
]]>最近做压力测试,不同的系统的机器监控数据差异明显
A 系统:CPU 高 load 低
B 系统:CPU 低 load 高
那么是什么导致 A B 系统出现这种情况?
CPU 高了系统肯定跑不动了,那么 load 多高代表系统跑不动呢?
Linux load averages track not just runnable tasks, but also tasks in the uninterruptible sleep state.
Linux 平均负载不仅跟踪可运行的任务,还跟踪处于不可中断睡眠状态的任务。
On Linux, load averages are (or try to be) “system load averages”, for the system as a whole, measuring the number of threads that are working and waiting to work (CPU, disk, uninterruptible locks). Put differently, it measures the number of threads that aren’t completely idle. Advantage: includes demand for different resources.
在 Linux 上,负载平均值是(或试图是)“系统负载平均值” ,对于整个系统来说,测量正在工作和等待工作的线程数(CPU、磁盘、不可中断锁)。换句话说,它测量的是没有完全空闲的线程数量。优势: 包括对不同资源的需求。
题目要求:
Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
每一行都不能重复1-9
每一列都不能重复1-9
每个33的小格子(99分为9个3*3)不能重复
开始解题的时候可以一个大循环解决一个小问题,后续再把循环合并即可;
开始的时候我是写了三个双重for循环:
当发现每一步都可行之后,尝试着合并,以减少时间复杂度;
public static boolean isValidSudoku(char[][] board) { |
可运行demo
github地址:ValidSudoku.java
新建一个start.bat文件,内容如下
@echo off |
2.设置开机启动
把start.bat文件复制到[启动]文件夹里面
[启动]文件夹路径
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp |
文件管理器地址栏显示大概是这样
Windows > [开始]菜单 > 程序 > 启动 |
放进去之后就可以开机启动了!
启动之后Xshell连接即可
]]>VK7JG-NPHTM-C97JM-9MPGT-3V66T |
如有有天你想喝一瓶矿泉水,你可以去小区便利店,告诉老板你要买矿泉水,然后老板卖给你。
但是你可能需要想这下雨天怎么去小卖部?是否要带伞?去了之后是否有我想要的水等一系列问题。
解决这个问题:
是不是和Spring的做法很类似呢?Spring就是小卖部,你就是A对象,水就是B对象
第一:在Spring中声明一个类:A
第二:告诉Spring,A需要B
假设A是UserAction类,而B是UserService类
<bean id="userService" class="org.leadfar.service.UserService"/> |
在Spring这个商店(工厂)中,有很多对象/服务:userService,documentService,orgService
也有很多会员:userAction等等
声明userAction需要userService即可,
Spring将通过你给它提供的通道主动把userService送上门来,因此UserAction的代码示例类似如下所示:
package org.leadfar.web; |
在这段代码里面,你无需自己创建UserService对象(Spring作为背后无形的手,把UserService对象通过你定义的setUserService()方法把它主动送给了你,这就叫依赖注入!)
Spring依赖注入的实现技术是:动态代理
你只要做你关注的事情,其他的事情一概不管,让AOP帮你去做
你可以灵活组合各种杂七杂八的事情交给AOP去做,而不会干扰你关注的事情。
从Spring的角度看,AOP最大的用途就在于提供了事务管理的能力。
事务管理就是一个关注点,你的正事就是去访问数据库,而你不想管事务(太烦)
所以,Spring在你访问数据库之前,自动帮你开启事务,当你访问数据库结束之后,自动帮你提交/回滚事务!
通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);
将依赖关系作为构造子参数传入的做法称为构造子注入(Constructor Injection)。
其实当你真正花些时间读一读源码就知道它的一些技术实现其实是建立在一些最基本的技术之上而已;
例如:
在底部任务栏空白处:
右键—设置—任务栏—在桌面模式下自动隐藏任务栏(开)—任务栏在屏幕上的位置(上 | 下 | 左 | 右)
这样就设置完毕了,毕竟笔记本太小
用idea的时候居然有些界面很难点击OK什么的!!!
知乎有专门讨论任务栏放置位置分析,有兴趣的可以看看:
]]>最近在做app后台相关接口
自建通知中心目前不能很好的支持给APP推送消息
长连接可以保持推送速度,目前app中内嵌了H5,所以考虑使用websocket
之前没有接触过websocket,百度了一堆之后,页面上可以正常使用
但是没有发现可用使用Java后台进行消息的发送,于是乎就琢磨了一上午,解决了这个问题
现在把这个小工程分享给大家,少走点弯路==
ps:很多不能在后台发送消息,是因为缺少java的客户端
建立一个maven web 工程
添加依赖
<dependency> |
websocket服务端主逻辑
为了实现简单的非群发操作,在连接websocket的时候,加上了一些get参数
例如:ws://localhost:8080/websocket?sendTo=hisen&method=methodSingle&user=hisenyuan
然后在后端判断,根据参数做出不同的动作
demo完整工程:https://github.com/hisenyuan/IDEAPractice/tree/master/websocket-demo
配置完Tomcat,即可使用,在java后台运行测试类(com.hisen.ws.client.ClientApp4Java)可发送消息到页面
package com.hisen.ws.server; |
权重算法一般在路由里面用的比较多,分布式环境下对等的服务有多个,加权随机选出一个服务来调用;
可能还有其他方面的用途,下面的代码简单的实现了这个权重,本质上就用到了数组,随机下标;
public static void main(String[] args) { |
github:show all code
package com.hisen.algorithms; |
电商场景下的订单系统
往往会有很多查询需求
单体数据库无法满足大量数据存储、各种复杂查询
待更新
待更新
]]>过年期间,看到 github 关注的人的动态当中
有人 star 了这个项目 Rust语言圣经
这些年也听说过 Rust,一直没有特意去了解
当我看到大佬也关注了这个课程的时候
感觉应该是一个不错的学习资料
前面介绍学习的好处让我心动了
就跟着学习了前面 4 节课
目前感觉良好
有空继续学
不得不说,环境搭建特别方便!
fn greet_world(){ |
$ cargo run --release |
比如:debian、ubuntu、deepin等
apt-cache search package #搜索包(相当于yum list | grep pkg) |
同事分享《Effective Java》
其中第十章,并发部分例子有争议
变量是否需要(代码如下) static?
几个大佬说需要加,我众目睽睽下反驳不需要,略尴尬
// 是否需要加 static?才能保证单例正确
private volatile Singleton singleton;
public class Singleton { |
|
public class Singleton { |
带 static 的结果符合预期
对象只创建一次,并且返回结果均不为 null
开始执行
new:1
new:2
new:3
false
true
省略几十行….
开始执行
new:1
false
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
关键:static 变量在内存中只有一个副本,由所有对象共享。
不知在哪听说过陆奇的传说
对于一位地位如此之高的华人
甚是敬仰,奈何相关资料甚少,很难深入了解
不像李开复、吴军那样,出过一些书,了解可以多些
榜样的力量或许很虚,关键看自己能悟多少,是否坚持行动。共勉!
大部分人还不了解陆奇,但他值得让我们好好了解一下:
这几年陆奇被格外关注,始于2017年1月17日他被百度任命为百度总裁。这次任命份量极高,到今天百度创立19年,李彦宏给出如此高的权力,陆奇是唯一一个。
但陆奇值得。
陆奇在硅谷非常有名,拥有不错的人脉和江湖地位,凡接触过陆奇的人提起他,几乎是众口一词地称赞。
1998年陆奇加入雅虎,2007年任雅虎执行副总裁。
2008年他辞职时,杨致远当场洒泪,告别会上所有工程师穿上统一的T恤,T恤上印着“我曾与陆奇一起工作,你呢?”,以此纪念陆奇在雅虎的日子。
2008年加入微软,任全球执行副总裁,这是有史以来,华人在科技领域获得的最高职位。
2016年9月离职时,比尔·盖茨极力挽留甚至承诺:“你想要做什么业务,我们去搞个业务给你。或者你先休假一年两年,然后再回来当首席技术官,我们等着你就是了。”
微软现任 CEO 纳德拉曾对微软员工说:“五个人,对微软贡献巨大。一是创始人比尔·盖茨,二是CEO史蒂夫·鲍尔默,三是董事会主席约翰·汤普森,四是诗人奥斯卡·王尔德,最后一个就是陆奇。”
其实早在2005年前后,李彦宏就曾试图说服陆奇加入百度,只是当时并未如愿。
2017年陆奇加入百度后,李彦宏曾公开给了他很高的评价:陆奇上上下下有口皆碑,大家都很喜欢他,他有非常强的技术能力,又有很强的管理能力,并且工作极其玩命。
陆奇身上有太多值得我们学习的地方。
前段时间《晚点》采访时就问陆奇:
你对20、30、40岁的年轻人各有什么建议?
陆奇:
20岁需要做让你可以走得很快的事情,快速学、快速失败。30岁你要让自己可以走得远,建立一个核心支撑体系能让你走得很远。这个体系包括你的身体、你厚实的家庭基础和几个志同道合你可以信任的朋友。
一个人到了35岁,到了打造产品的黄金时段,我已前很关注这个年龄阶段的人才,因为他/她已经犯过不少错,他/她最需要做一个好产品让他/她的职业生涯有一个本质提升。
40岁后,理想情况是找到一个可以让你淋漓尽致去发挥的舞台,一个人的才华和一个公司的才华只有在真正被释放的情况下才能实现它的价值。如果这个舞台是你自己的最好。
这个回答很经典,我反复看了很多遍。但要真的看懂看透,我们还必须要放在陆奇的整个人生系统里看,我一口气翻看了所有关于陆奇重要的中文报道,从中得到了一个更完整清晰的答案。
20岁:做让自己走得快的事情
陆奇:“20岁需要做让你可以走得很快的事情,快速学、快速失败。”
1、20多岁,习得什么能力最重要?
陆奇认为有两个:
学习能力:在这个变化速度越来越快的世界里,拥有学习和持续学习的能力,不断提高自己在某一个专业领域以及在企业内开发产品和业务的认知能力是基础。
原因很简单,因为创新,世界变化的速度越来越快。唯一的应对,是与它共跑甚至赶超。方法就是学习,要持续不断的学习,让自己拥有更多更深的专业知识和技能,更强的在企业内开发产品和业务的能力。
交流能力:这是一个人与人之间愈发紧密联结的世界,通过各种数字通讯服务与工具,社交网络,人们能够以文字、图片乃至视频,与更多的人保持交流。
从长远角度看,一个人越擅长结识他人,表达自己,形成相互学习并共同完成某些理想的关系和友谊,对这个人就越好。
2、20多岁,去创业公司还是大公司?
陆奇认为,要看个人追求。
如果你的长远理想是自己开公司,那加入创业公司,甚至直接创业,都是最好的选择。加入创业公司或自己创业会愈发成为年轻人学习并拥有真正创新能力的重要途径。因为在创业企业,每天做的事就是为了生存而战斗,一个人的真实作战能力测试来的很快。创新或死亡,是创业企业每天面临的现实。就学习和人才发展角度,一个人能获得这样的学习机会是非常宝贵的。
如果你的长远理想是成为一家公司某个职能的高管,那就进入一家可以提供你学习和成长机会的大企业。
但陆奇认为,以上仅限于少部分清楚的知道自己长远目标的人,他对女儿说:大部分人在25岁之前,对于人生想要做什么,其实只有模糊的感觉。
所以,20多岁,要学会快速失败,尝试,反馈,改变。把自己的时间投资在更大的学习发展空间机会中,可能为未来创造更高的收入。
3、陆奇的20多岁,在做什么?
读书,以及继续读书。
1978年,全国恢复高考,17岁的陆奇埋头狠狠啃了两年书,考入复旦大学计算机专业。读书期间,陆奇特别用功。他的同学们回忆说:
“他瘦瘦小小的身影,每天穿行在教室和图书馆之间,夜里图书馆熄灯,他才穿过农田,回到另一区的寝室。”
“他背着大书包在校园里穿梭,在林荫道上反反复复背着单词。他是全年级最瘦小的男生,但扛着全年级最大的书包。”
凭着超凡的努力,陆奇顺利考取复旦的研究生。凭着读研期间优异的成绩,他毕业后留校任教。
勤奋学习和扎实的专业知识带给陆奇的远不止一份稳定而又体面的工作,还包括更多的人生选项。
1989 年,卡耐基梅隆大学教授克拉克到复旦交流讲学,讲学时间选在了周末。不巧地是,当天的天气很不给力,暴雨倾盆,周末加坏天气使得来听讲座的学生寥寥无几。校方为了不让教授尴尬,就安排周末留校的师生去听讲座,因为暴雨取消回家计划的陆奇就是其中之一。
克拉克教授讲完后,让在场师生提问。陆奇抓住这个机会,接连向教授提了几个专业问题,克拉克听完,立刻就对这个提问的复旦老师的学术水平刮目相看。讲座过后,他专门翻阅了陆奇写的论文,看过之后,克拉克就邀请陆奇去卡耐基梅隆大学读博。
那年陆奇28岁,有点犹豫:“在大学当老师已经是很不错的职业了”。
克拉克只回了一句:“你是鹰,不应该局限在笼子里。”
陆奇去了美国。
走上卡耐基梅隆大学这个更大的平台,才有了陆奇对计算机科学更深入的研究与理解、才有了陆奇与李开复的相识以及后面的开挂人生。
4、59岁的陆奇还在试图重构知识体系,20多岁怎能不学?
2016年陆奇在硅谷接受采访时说:“最近几年我重新觉悟——你必须要重新学习,以前学的东西不光过时了,而且现在很多理论包括物理学都已经有了全新的认识,所有你要从根本上重新构建知识、认识世界。”
陆奇从微软离职原因之一是练习倒骑自行车摔伤了腿,那辆车是他与同事改造的、反向骑行的自行车,骑车时人和身体反应全部是倒置,所以要忘记过去学习到的全部经验。
就连之前选择加入YC,其中一个原因也是学习:我还希望我的工作不能只利用过往的经验,而是要每天学新东西。不学新东西的话,就没什么乐趣。
这几年陆奇观察到人才市场里一个非常重要的宏观趋势,整体的需求从原来的技能驱动型人才,越来越往知识和创新驱动型人才转移。所以他认为,一个人的能否快速学习,并将学到的知识应用于创造新的价值也变得愈发重要。
现在他仍旧保持着每天学习英语、阅读计算机领域最前沿论文的习惯。他说:“我把自己想象成一个软件,今天的版本一定要比昨天的版本好,明天的版本一定要比今天的版本好。”
年近60岁,陆奇还试图重构知识体系,20多岁的我们又怎么能不学习?
30岁:做让自己走得远的事情:搭建系统
陆奇说:30岁你要让自己可以走得远。建立一个核心支撑体系,能让你走得很远。这个体系包括你的身体、你厚实的家庭基础和几个志同道合、可以信任的朋友。
陆奇是一个寻求最优解的人,方式就是建立系统。
任何一个问题他都有系统的固定方式去解决——就是把它变成一个非常理性化、可以拆解成任务的方程。
比如,陆奇的人生里几乎看不冒险,因为他只把机会成本的8%用来冒险,就算这8%,他还是会建立一个决策系统,理性决定——快速反馈——如果方向不对,立即掉头甚至放弃。
比如,看待自己在微软的贡献,他不计较几个产品的得失,还是要回到系统上:比起一个产品的成败,帮助企业建造长期的创新的生命力才是最重要的。
我们再看一下他上面着重提到的三个系统。
1、身体系统
陆奇极度自律,坚持了十几年早上4点起床。
过去十几年他是这样的:“4点起来先弄Email,弄完了以后跑步,跑30分钟,洗个澡,去办公室。跑步第一对呼吸系统是很好的锻炼,第二可以出一身汗,第三是我可以边跑边听书不浪费时间,有时候我会把PPT放在跑步机上翻着看。”
从微软离开后有所变化,他现在对自己的生活效率很不满意,因为骑反向自行车把腿摔伤后,跑步根本不行了,目前他正在找一个让自己感觉每天都很顺畅的方式。
不过他依然精力旺盛,百度期间,同事说他每日长时间工作,无论周末、假期,无论在北京还是在国外,只要开会,他总是准时出现在视频会议的另外一端。他有依然有自己严格的作息制度,有自己严格的生活习惯,也有非常严格的饮食习惯。
陆奇认为,每个人有不同的身体状况,他自己的做法不建议其他人学习。但是他有一套核心的方法论可以介绍给大家:
找到问题的核心,即:无论创业还是在大企业里从业,在工作中如何进行时间管理来让产出最大化,同时也能获得自我满足?
再找到核心的解决办法,即:
设计一个“马拉松快步跑”的时间管理方法和心态。
第一:要意识到这是一场马拉松,不是一场短跑。
第二:这场马拉松的速度需要很快,因为现实世界中,任何高价值的东西——创业公司、大企业的好岗位等——都会有非常激烈的竞争,你需要保持速度并持续领先。
设计这样一个工作节奏和时间管理方式,很类似在高速公路开车。
陆奇说:“你需要保持一个均匀的高速,然后时不时的加速一下,再回到之前均匀的高速。你要避免过度频繁的加速、减速。就像一辆车,如果一直都是高速前进,只是偶尔减速一下,这对与一辆车的损耗是很低的。但如果一辆车过度频繁的突然加速、减速,会对这辆车带来巨大损耗,不用多久车就可能垮掉。
因此,你需要设计属于你自己的一个工作和生活节奏,这种节奏是你可以保持住的高速,而这个高速可以给你带来最大的效率。同时,你也需要设计这个日程节奏,让它可以应对突发变化,可以时不时的冲刺一下,比如偶尔过度加班让工作在截止日期前完成,然后迅速回归之前的速度。必须避免经常性的透支,经常性的拼命追赶截止日期,经常性的处于疲累状态。身体和精神上偶尔透支可以补回,不可长期透支。”
跑一个高效率、可持续、并且可以应对临时突发状况的马拉松才是关键。
2、家庭系统
陆奇的家庭很少出现在媒体中,公开信息绝少,但陆奇在讲搭建系统时特意提到“厚实的家庭基础”,说明他的个人成功受“家庭系统”支持颇多。
2018年5月8日,百度宣布陆奇因“个人和家庭原因”离开百度。
这其实是拿陆奇最不可能的原因当了最常见的公关话术,陆奇的家庭一直是全力支持陆奇做他想做的事业,百度的一位高层说,陆奇就职微软期间,其长期在美国西雅图工作,家人为了陆奇就定居硅谷,“他早就把家庭的事情处理好了”。
陆奇回国加入百度后,为了照顾陆奇的饮食起居,陆奇家人曾一度迁居北京,百度还为陆奇的夫人配备了出入百度大厦的证件。
2018年8月16日,YC媒体沟通会上,主持人官宣陆奇加盟YC担任YC中国首任CEO。陆奇和太太、女儿都在现场。
陆奇的太太说:“我们有一半的时间在美国,他去哪里,我们就跟到哪里。”
陆奇现场致辞的最后,也特别感谢了他的太太和家人。而且说希望在美国、中国多花时间,为了家庭。
写这部分内容时,我突然想起小晚的《晚点》团队采访陆奇时曾问过这么一个问题:你是否经常会太过相信自己的力量?
陆奇说:会。我太太一直觉得我太过于自信了。她老觉得我自以为是。
这就是最好的支持吧,即便有时认为你的理想“不现实”,但只要你想做,我愿意陪你。这就是陆奇所说的“厚实的家庭基础”对一个人事业的重要性吧,如果你的梦想和成长能得到最亲近的人的支持,应该是最幸福的事了。
3、人脉系统
陆奇的人脉有多强?
陆奇的人脉有多好,我相信在开头介绍中,那些顶级大佬的评价就是最好的答案,接触过的人都愿意帮他,合作过的人都愿意捧他。
这里再讲几个点。
1996年,陆奇博士毕业,摆在他面前的有三个选项:回国;华尔街;硅谷。
他不知道该如何选择,就去请教李开复自己该去哪里、进哪个公司工作,李开复给出了自己的建议:“去硅谷吧,找一家技术类的公司。”
于是陆奇就去了IBM的Almaden研究实验室,在那里工作了两年。
之后,陆奇跳槽到雅虎,李开复又一次提醒他:“雅虎的股价不会一直在这个水平上,它要么会上涨5倍,要么下跌5倍。”
陆奇职业生涯的两次关键时刻,李开复都给出了自己的建议和判断,一次让他看清了自己的优势和发展方向,一次让他看清了一家公司的发展空间。
2008年,微软收购雅虎未果,当时已在微软任职的师兄沈向阳向鲍尔默引荐了陆奇,于是有了之后鲍尔默与陆奇长达6个小时的会谈。就这样,微软成功挖到了雅虎搜索引擎业务第一人——陆奇,陆奇也开启了他在微软的执行副总裁生涯。
沈向阳的引荐,让陆奇成为“硅谷最有权势的华人”。
再到2019年,YC撤出中国,陆奇独立运营新基金奇绩创坛,很快首期美元基金募集完成约1亿美金,出资人都是谁呢?
陆奇的朋友们,阵容相当豪华:比尔盖茨、孙正义、红杉中国、高瓴资本、北极光创投等。
陆奇如何看待人脉?
中国人常说,做成一件事就是:天时地利人和。
人和就是人脉。陆奇喜欢那句“机会总是留给有准备的人”,但他喜欢那句“机会是留给广结良友的人。”
陆奇说:我个人的经验里,除了准备充分,你所拥有的人脉的宽度和广度也很重要,要通过交流结识更多人,最好是拥有不同职业背景的人,并跟他们保持关系)。美国有一句谚语,你获得一份工作不是因为你知道什么,而是因为你认识谁。这句话在某种角度上其实很正确,至少在我个人的经验里,这句话很正确。
陆奇为什么有如此好的人脉资源?
这句按照查理芒格的说法,当然是陆奇配得上。
他做了什么让自己配得上?
我们来分析几点。
陆奇的人品。
小晚的团队采访他时,多次试图让他聊百度,我们看陆奇的表现。
比如问“回头来看,加入百度是一个错误的选择吗?”,陆奇回答“不好意思,我真的不想讲百度”。
记者追问“你可以谈微软,但是避免谈百度,为什么?”,陆奇回答“是职业道德,我不想为它带来任何Distraction(干扰)”。
我看完这句,佩服。
谈及老东家YC,陆奇说:我个人很感激YC,我一定要强调这一点,他们送我们到了他们能送到的最远的地方。
记者问:看着雅虎一步步走向衰落,为什么没有更早的离开?
陆奇答:因为我答应杨致远做10年。当时雅虎进入了一个危机,杨致远找我说,中国有一个传统,朋友有难的时候不应该离开。我说那我就不离开了。
膜拜。
陆奇的情商。
小晚团队问:你心中优秀的CEO是什么样子?你的榜样是谁?
陆奇答:最强的人愿意为你而来,这是我觉得最好的CEO。在中国我觉得马云做得不错。
后面的一个问题中,他特意提及了张小龙,“张小龙是我非常敬仰的人。中国的移动生态走得很远,很大因素是微信,微信可能是当代做得最出色的一个产品”。
赞美阿里的组织,赞美腾讯的产品。
陆奇的品质。
一个浑身闪耀着发光品质的人怎么会没朋友?
陆奇身上的优秀品质太多,略举一二。
比如准时。自媒体人辉哥曾和陆奇在百度共事,他说某次出差,他们先到楼下大堂等,距离预定出发的时间还有1分钟时,他有一些着急,问要不要给陆奇打个电话。熟悉他的人说“他会准时的”,话音刚落,电梯门打开,陆奇出现,一分不差他极度守时。
比如来信必回。无论是邮件还是微信,你只要发给他,他一定会回复,时间不确定,有时候是凌晨1-2点,有时是早晨5-6点左右。
比如永远正向。辉哥说,工作中永远难免会遇到困难,但陆奇任何时候都保持正向的态度。无论是在公司开会,还是做大会的 MC,或是回邮件,永远是用简短有力,但充满了力量和鼓舞人上进的精神。大家最累最困难的时候,只要陆奇在那里振臂一挥,大家顿时又像打了鸡血。
40岁:找一个可以让你淋漓尽致发挥的舞台
陆奇:“40岁后,理想情况是找到一个可以让你淋漓尽致去发挥的舞台,一个人的才华和一个公司的才华只有在真正被释放的情况下才能实现它的价值。如果这个舞台是你自己的最好。”
陆奇说过一句广为流传的话:
“人生不是线性的,不要以为一班车就能把你从现在的位置带到你自己所期望的位置。”
什么阶段做什么,40岁以后,就要找到一个可以让你淋漓尽致发挥的舞台。
为什么不是20岁?
前文也说了,陆奇认为那个阶段,绝大部分人对于人生想要做什么,其实只有模糊的感觉。
而且陆奇认为,20多岁你要考虑一些现实因素,比如财务方面,工作收入需要满足自己生活的需求以及其他潜在财务责任,比如资助父母兄妹等,理想情况下,还可以有一些存款。
20多岁多学多做多试,30多岁搭建系统,正是为了40岁以后真正有属于自己的舞台。
微软属于他的舞台,但不够,所以他离开,回到中国,找更合适的舞台。
比尔·盖茨一直挽留他,说:百度能给你什么,我都给你。
陆奇说:你不能给我中国。
中国是他现在更好的舞台,一个更大意义上的舞台,他要借助一家合适的平台在这个舞台上跳舞。很可惜,百度没能最终成为那个合适的舞台。后来他加入YC,很可惜YC也没最终成为那个合适的舞台。
后来陆奇认为:属于自己的舞台,如果真的“属于自己”,那是最好的。
“如果你想真正大规模改变世界,那你必须是这个企业的创始人,否则你永远受限于你的雇主。当这个平台是你亲手建造,那你可以发挥的能量和范围是最充分的。”
陆奇的的签名是:“Do more, know more, be more”。
这大概就是追求“be more”吧,40岁以后,自我更重要了。
这个问题,《晚点》和陆奇的对话很精彩:
《晚点》:甘地说,be the change you want to see in the world。成为更好的自我和建立一个更好的世界,后者难道不会推动人走得更远吗?
陆奇:自我才会让人更永久。赚很多钱、建设一个成功公司,甚至建造一个国家、世界,都是外在目标。如果一个目标是外在的,你永远会在达到目标之后变得一片空虚。
《晚点》:有一些商人,他们的目标就是赢,他们乐此不疲,似乎并不空虚。
陆奇:你的追求是建立在别人输的基础之上,为什么世界上一定要有人输你才觉得你的生命是有价值的?我认为人的目标是你自己而不是任何外在的因素。
如今他终于有了属于自己的舞台,奇绩创坛,也真的“属于自己”。
网络
中断(Interrupt)是指 处理器接收到来自硬件或软件的信号,提示发生了某个事件,应该被注意,这种情况就称为中断。
软中断 (form 《UNIX 操作系统设计》)
内核在收到软中断信号的进程上下文中处理软中断信号,因此进程必须运行以便处理信号。
处理软中断信号的方式:
- 进程忽略软中断信号;
- 进程收到软中断信号后退出;
- 进程收到信号后执行一个特殊的(用户)函数;
// 中断当前线程,仅设置中断标识位。 |
Java 中不推荐使用抢断式中断,倡导:
一个线程的生命不应该由其他线程终止,应当由它自己选择是否停止。
try { |
由于近期换工作,停下了技术书籍,去了解行业
《移动健康和智慧医疗》算是互联网医疗的科普资料
前面部分的内容已经后面部分国际案例,了解之用足够
里面提到的『量化自我』,如果把世界量化分析,岂不是美哉?
随说:前提是大家相信分析出来的结论,以及按建议行事。
《移动健康和智慧医疗》0711~0717
过去人口红利式的告诉发展逐渐降速
老龄化突显使疾病预防和控制更重要
医疗信息化建设提升医疗系统效率
医疗数据收集与分析改进医疗方案
多维度健康数据分析建议促进健康
减少医疗信息不对称
降低患者再次入院率
早运动早发现早治疗
有效地减少医疗支出
互联网医疗典型方向:
《移动健康和智慧医疗》0711~0717
过去中国高速发展,目前人口红利逐渐消失,老龄化日益突显,使得以传染病为主,转向非传染性疾病的预防和控制 。
利用现代技术加强相关人员交流和互动
慢性病管理
血糖控制,通过监测行为特征,配合辅助功能,加强用户掌控能力,医生,家人远程支持与提醒。
随说:收集足够信息,给出专业建议
骨科手术后居家康复指导,尽快出院,获取足够信息与支持。
随说:给予高质量内容,提升自我恢复能力。
服务设计、实现、患者使用过程,均反应出一系列信息技术和预防、临床医学(流程、知识)之间的相互作用和支持,提现了互联网+多学科交叉,跨行业深度融合的思想。
随说:降本增效,沉淀数据,线上线下无缝对接
互联网医疗典型方向:健康促进、慢性病管理、诊断治疗、术后康复。
健康医疗APP重要因素:专业性、相关性、有效性、趣味性、社交化。
随说:社交?相互鼓励,交流心得
医疗云平台:数据汇集分发、电子健康档案、业务管理、安全体系、运维系统。
对多元异构多模态大数据进行处理、分析、挖掘,从中获取新知识和洞察,优化经营、管理,提升患者体验,提取最佳临床路径,辅助临床决策,实行计算机自动筛查和诊断,为其它利益相关方提供未知的信息资源等,这是互联网医疗追求的理想和目标。
研究发现我国近2/3接受糖尿病治疗的患者未能适当控制血糖,因此会出现各种并发症,如:心脏病、中风、失明、肾功能衰竭等。
2014年,慢性疾病导致的死亡占中国总死亡人数的 85%,导致的疾病负担占总疾病负担的 70%。
虽然中国经济的增长速度赢得了世界的瞩目,但是如何提高慢性病是综合防治能力,减少慢性病的发病率、致残率和死亡率,降低费用支出,仍是健康医疗服务需要应对的巨大挑战。
著名卫生经济学家普林斯顿大学教授 WR 提出,各国医疗体系的本质在于国家价值观和国家性格决定其系统如何运行。
低功耗可穿戴设备使得随时随地采集健康医疗数据成为可能。这些大量的、连续的、包含上下文情境的健康医疗数据,为健康医疗提供决策依据、促进健康生活方式的养成、改善疾病监护、诊治状况。
移动互联网具有用户身份、位置可识别,随时交互、多元数据可采集、用户可高度参与等一系列技术特征,使得移动互联网与其他行业融合时带来新的解决方案、服务模式和发展机遇。
医护路径全流程服务:促进健康、预防/慢性病管理、院前急救、诊断治疗、院外康复/干预。
院前急救:伤者历史数据、辅助诊断、车载数据同步医院,医院提前准备。
远程问诊成本低,灵活性强,出现一些早期症状可以及时获得指导。
随说:小毛病挂专家号,会诊几分钟…
量化自我:2007年凯文凯利提出,通过设备和技术持续跟踪、采集自己的生理心理特征,形成生活日志,探索身体健康的奥秘。
可穿戴设备的数据如果作为对患者实施诊断、治疗等环节的重要依据,则属于医疗器械,需要监管。
智能服装才是可穿戴设备的终极形式。
单点登录的目的是为了让多个相关联的应用使用相同的登录过程,代码复用,提升体验。
CAS 是开源的企业级单点登录解决方案。
根据密钥的职责和重要性,一般分为:主密钥、二级密钥、初级密钥。初级密钥是直接使用的密钥。高级密钥对低一级密钥做加密,保护低一级的密钥。
不同级别的密钥应该分开存放,最好是异地、异设备。
密钥不以明文形式存储在数据库或传输媒介中:避免密钥被截获后直接用来解密数据,增强安全性。
HIS:医院信息系统
PACS:影像系统
LIS:检验信息系统
RIS:放射信息系统
EMR:电子病历
HIMSS:美国医疗信息和管理协会
EMRAM:电子病历采纳模型
CHA:康体佳健康联盟
流式计算的数据来自一个最近的时间窗口,数据延迟短但精度可能较低。
一个完全测序的人类基因组包含 100~1000G的数据。
精准医疗:根据每个人的基因、生活环境、生活方式等的不同,提供相适应的个性化疾病治疗和预防
健康医疗大数据的收集、分析、整理和挖掘对于患者健康医护路径的不同环节都有非常重要的价值。
任何疾病最有效的治疗方式是预防保健。
每年心脑血管医疗费用占比搞,且再次入院率高,如何有效管理心血管病、节省医疗开支、降低出院患者再次入院率已经成为社会各界关注的重点。
美国的分级诊疗制度、医生多点职业、医疗信息化、商业保险、医院集团管理等一系列成熟体系,为美国移动健康医疗的发展提供了肥沃土壤。
远程医疗服务提供简单、方便、低成本的方式为患者远程诊治感冒、流感、喉咙痛或其它简单非急症性疾病。
2014 年 5 月,阿里旗下的支付宝推出“未来医院计划”,支付宝对医疗机构开放自己的平台能力,包括:账户体系、移动平台、支付及金融解决方案、云计算能力、大数据平台等,旨在优化患者在医院的就医流程,提高就医体验,提升医院的管理效率。
2015年阿里健康业务
北京大学人民医院是中国最具实力的三级甲等研究型医院之一,积极推进医疗信息化建设,2014 年通过了国际上衡量医院信息化水准的 HIMSS EMRAM 最高等级(7级)的评审,成为亚洲第二,中国第一家。
]]>想要真正的理解count函数,我们就必须明白count函数的作用。
作用一:统计某一列非空(not null)值得数量,即统计某列有值得结果数,使用count(col)。
作用二:统计结果集的行数,此时不用管某列是否为null值。即使用count(*).
明白了这点,我们就应该知道MySQL的count(*)并不是想象中的那样,统计每一列的值,而是直接忽视掉所有列,直接统计行数,那么它的效率肯定是很高的。
但是有一点,当col指定了该字段为NOT NULL时实际上,MySQL会自动将count(col)转为count(*),但是这样也同样耗费了些时间,如果col没有指定为NOT NULL的话,那么效率就更低了,MySQL就必须要判断每一行的值是否为空。
所以综上所述,如果是要统计行数最好优先使用select count(*)
当统计某一列等于多少的值得时候可以使用下面两种方法:
SELECT SUM(IF(id = 23,1,0)) FROM table |
最近在做数据迁移
为了加速迁移速度
其中就需要把查询到的数据( max 100 条)
拆分成 5 份,然后执行 5 个子任务,加速处理
public static <T> List<List<T>> split2(List<T> lists, int subCount) { |
public static <T> List<List<T>> split(List<T> lists, int subCount) { |
从结果可以看出,一味地追求新颖也不是好事,需要知其然
java 8 的 stream 并不占优势,性能相差好几个数量级…
Benchmark Mode Cnt Score Error Units |
压测教程:JMH 使用参考
import com.google.api.client.util.Lists; |
其中不错的一点我觉得是
int splitTimes = (lists.size() + subCount - 1) / subCount; |
这样巧妙的计算,避免了先取模,后判断是否有余数的繁杂。
这个不是我想到的,也不知道怎么通过数学证明,但是这样就是对的 ==
ps:是谁说数学没用的 ????
]]>原来并不用安装spark什么的这些东西
这样就不会那么繁琐,门槛也低了点
具体过程如下
pom.xml添加依赖
<dependency> |
编写java代码
package com.hisen.spark; |
运行main方法:结果:Lines with a: 11146, lines with b: 10760
C:\hisenwork\soft\jdk8\bin\java -Dspark.master=local "-javaagent:C:\hisenwork\IntelliJ IDEA 2017.1.1\lib\idea_rt.jar=59366:C:\hisenwork\IntelliJ IDEA 2017.1.1\bin" -Dfile.encoding=UTF-8 -classpath C:\hisenwork\soft\jdk8\jre\lib\charsets.jar;C:\hisenwork\soft\jdk8\jre\lib\deploy.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\access-bridge-64.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\cldrdata.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\dnsns.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\jaccess.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\jfxrt.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\localedata.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\nashorn.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunec.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunjce_provider.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunmscapi.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\sunpkcs11.jar;C:\hisenwork\soft\jdk8\jre\lib\ext\zipfs.jar;C:\hisenwork\soft\jdk8\jre\lib\javaws.jar;C:\hisenwork\soft\jdk8\jre\lib\jce.jar;C:\hisenwork\soft\jdk8\jre\lib\jfr.jar;C:\hisenwork\soft\jdk8\jre\lib\jfxswt.jar;C:\hisenwork\soft\jdk8\jre\lib\jsse.jar;C:\hisenwork\soft\jdk8\jre\lib\management-agent.jar;C:\hisenwork\soft\jdk8\jre\lib\plugin.jar;C:\hisenwork\soft\jdk8\jre\lib\resources.jar;C:\hisenwork\soft\jdk8\jre\lib\rt.jar;C:\hisenwork\code\rmitec\SparkTest\target\classes;C:\hisenwork\soft\maven\org\apache\spark\spark-core_2.11\2.0.1\spark-core_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\apache\avro\avro-mapred\1.7.7\avro-mapred-1.7.7-hadoop2.jar;C:\hisenwork\soft\maven\org\apache\avro\avro-ipc\1.7.7\avro-ipc-1.7.7.jar;C:\hisenwork\soft\maven\org\apache\avro\avro\1.7.7\avro-1.7.7.jar;C:\hisenwork\soft\maven\org\apache\avro\avro-ipc\1.7.7\avro-ipc-1.7.7-tests.jar;C:\hisenwork\soft\maven\org\codehaus\jackson\jackson-core-asl\1.9.13\jackson-core-asl-1.9.13.jar;C:\hisenwork\soft\maven\org\codehaus\jackson\jackson-mapper-asl\1.9.13\jackson-mapper-asl-1.9.13.jar;C:\hisenwork\soft\maven\com\twitter\chill_2.11\0.8.0\chill_2.11-0.8.0.jar;C:\hisenwork\soft\maven\com\esotericsoftware\kryo-shaded\3.0.3\kryo-shaded-3.0.3.jar;C:\hisenwork\soft\maven\com\esotericsoftware\minlog\1.3.0\minlog-1.3.0.jar;C:\hisenwork\soft\maven\org\objenesis\objenesis\2.1\objenesis-2.1.jar;C:\hisenwork\soft\maven\com\twitter\chill-java\0.8.0\chill-java-0.8.0.jar;C:\hisenwork\soft\maven\org\apache\xbean\xbean-asm5-shaded\4.4\xbean-asm5-shaded-4.4.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-client\2.2.0\hadoop-client-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-common\2.2.0\hadoop-common-2.2.0.jar;C:\hisenwork\soft\maven\commons-cli\commons-cli\1.2\commons-cli-1.2.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-math\2.1\commons-math-2.1.jar;C:\hisenwork\soft\maven\xmlenc\xmlenc\0.52\xmlenc-0.52.jar;C:\hisenwork\soft\maven\commons-io\commons-io\2.1\commons-io-2.1.jar;C:\hisenwork\soft\maven\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\hisenwork\soft\maven\commons-configuration\commons-configuration\1.6\commons-configuration-1.6.jar;C:\hisenwork\soft\maven\commons-collections\commons-collections\3.2.1\commons-collections-3.2.1.jar;C:\hisenwork\soft\maven\commons-digester\commons-digester\1.8\commons-digester-1.8.jar;C:\hisenwork\soft\maven\commons-beanutils\commons-beanutils\1.7.0\commons-beanutils-1.7.0.jar;C:\hisenwork\soft\maven\commons-beanutils\commons-beanutils-core\1.8.0\commons-beanutils-core-1.8.0.jar;C:\hisenwork\soft\maven\com\google\protobuf\protobuf-java\2.5.0\protobuf-java-2.5.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-auth\2.2.0\hadoop-auth-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-compress\1.4.1\commons-compress-1.4.1.jar;C:\hisenwork\soft\maven\org\tukaani\xz\1.0\xz-1.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-hdfs\2.2.0\hadoop-hdfs-2.2.0.jar;C:\hisenwork\soft\maven\org\mortbay\jetty\jetty-util\6.1.26\jetty-util-6.1.26.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-app\2.2.0\hadoop-mapreduce-client-app-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-common\2.2.0\hadoop-mapreduce-client-common-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-client\2.2.0\hadoop-yarn-client-2.2.0.jar;C:\hisenwork\soft\maven\com\google\inject\guice\3.0\guice-3.0.jar;C:\hisenwork\soft\maven\javax\inject\javax.inject\1\javax.inject-1.jar;C:\hisenwork\soft\maven\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-server-common\2.2.0\hadoop-yarn-server-common-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-shuffle\2.2.0\hadoop-mapreduce-client-shuffle-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-api\2.2.0\hadoop-yarn-api-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-core\2.2.0\hadoop-mapreduce-client-core-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-yarn-common\2.2.0\hadoop-yarn-common-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-mapreduce-client-jobclient\2.2.0\hadoop-mapreduce-client-jobclient-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\hadoop\hadoop-annotations\2.2.0\hadoop-annotations-2.2.0.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-launcher_2.11\2.0.1\spark-launcher_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-network-common_2.11\2.0.1\spark-network-common_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\fusesource\leveldbjni\leveldbjni-all\1.8\leveldbjni-all-1.8.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\core\jackson-annotations\2.6.5\jackson-annotations-2.6.5.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-network-shuffle_2.11\2.0.1\spark-network-shuffle_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-unsafe_2.11\2.0.1\spark-unsafe_2.11-2.0.1.jar;C:\hisenwork\soft\maven\net\java\dev\jets3t\jets3t\0.7.1\jets3t-0.7.1.jar;C:\hisenwork\soft\maven\commons-codec\commons-codec\1.3\commons-codec-1.3.jar;C:\hisenwork\soft\maven\commons-httpclient\commons-httpclient\3.1\commons-httpclient-3.1.jar;C:\hisenwork\soft\maven\org\apache\curator\curator-recipes\2.4.0\curator-recipes-2.4.0.jar;C:\hisenwork\soft\maven\org\apache\curator\curator-framework\2.4.0\curator-framework-2.4.0.jar;C:\hisenwork\soft\maven\org\apache\curator\curator-client\2.4.0\curator-client-2.4.0.jar;C:\hisenwork\soft\maven\org\apache\zookeeper\zookeeper\3.4.5\zookeeper-3.4.5.jar;C:\hisenwork\soft\maven\com\google\guava\guava\14.0.1\guava-14.0.1.jar;C:\hisenwork\soft\maven\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;C:\hisenwork\soft\maven\org\apache\commons\commons-math3\3.4.1\commons-math3-3.4.1.jar;C:\hisenwork\soft\maven\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;C:\hisenwork\soft\maven\org\slf4j\slf4j-api\1.7.16\slf4j-api-1.7.16.jar;C:\hisenwork\soft\maven\org\slf4j\jul-to-slf4j\1.7.16\jul-to-slf4j-1.7.16.jar;C:\hisenwork\soft\maven\org\slf4j\jcl-over-slf4j\1.7.16\jcl-over-slf4j-1.7.16.jar;C:\hisenwork\soft\maven\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\hisenwork\soft\maven\org\slf4j\slf4j-log4j12\1.7.16\slf4j-log4j12-1.7.16.jar;C:\hisenwork\soft\maven\com\ning\compress-lzf\1.0.3\compress-lzf-1.0.3.jar;C:\hisenwork\soft\maven\org\xerial\snappy\snappy-java\1.1.2.6\snappy-java-1.1.2.6.jar;C:\hisenwork\soft\maven\net\jpountz\lz4\lz4\1.3.0\lz4-1.3.0.jar;C:\hisenwork\soft\maven\org\roaringbitmap\RoaringBitmap\0.5.11\RoaringBitmap-0.5.11.jar;C:\hisenwork\soft\maven\commons-net\commons-net\2.2\commons-net-2.2.jar;C:\hisenwork\soft\maven\org\scala-lang\scala-library\2.11.8\scala-library-2.11.8.jar;C:\hisenwork\soft\maven\org\json4s\json4s-jackson_2.11\3.2.11\json4s-jackson_2.11-3.2.11.jar;C:\hisenwork\soft\maven\org\json4s\json4s-core_2.11\3.2.11\json4s-core_2.11-3.2.11.jar;C:\hisenwork\soft\maven\org\json4s\json4s-ast_2.11\3.2.11\json4s-ast_2.11-3.2.11.jar;C:\hisenwork\soft\maven\com\thoughtworks\paranamer\paranamer\2.6\paranamer-2.6.jar;C:\hisenwork\soft\maven\org\scala-lang\scalap\2.11.0\scalap-2.11.0.jar;C:\hisenwork\soft\maven\org\scala-lang\scala-compiler\2.11.0\scala-compiler-2.11.0.jar;C:\hisenwork\soft\maven\org\scala-lang\modules\scala-parser-combinators_2.11\1.0.1\scala-parser-combinators_2.11-1.0.1.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\core\jersey-client\2.22.2\jersey-client-2.22.2.jar;C:\hisenwork\soft\maven\javax\ws\rs\javax.ws.rs-api\2.0.1\javax.ws.rs-api-2.0.1.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\hk2-api\2.4.0-b34\hk2-api-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\hk2-utils\2.4.0-b34\hk2-utils-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\external\aopalliance-repackaged\2.4.0-b34\aopalliance-repackaged-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\external\javax.inject\2.4.0-b34\javax.inject-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\hk2-locator\2.4.0-b34\hk2-locator-2.4.0-b34.jar;C:\hisenwork\soft\maven\org\javassist\javassist\3.18.1-GA\javassist-3.18.1-GA.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\core\jersey-common\2.22.2\jersey-common-2.22.2.jar;C:\hisenwork\soft\maven\javax\annotation\javax.annotation-api\1.2\javax.annotation-api-1.2.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\bundles\repackaged\jersey-guava\2.22.2\jersey-guava-2.22.2.jar;C:\hisenwork\soft\maven\org\glassfish\hk2\osgi-resource-locator\1.0.1\osgi-resource-locator-1.0.1.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\core\jersey-server\2.22.2\jersey-server-2.22.2.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\media\jersey-media-jaxb\2.22.2\jersey-media-jaxb-2.22.2.jar;C:\hisenwork\soft\maven\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\containers\jersey-container-servlet\2.22.2\jersey-container-servlet-2.22.2.jar;C:\hisenwork\soft\maven\org\glassfish\jersey\containers\jersey-container-servlet-core\2.22.2\jersey-container-servlet-core-2.22.2.jar;C:\hisenwork\soft\maven\org\apache\mesos\mesos\0.21.1\mesos-0.21.1-shaded-protobuf.jar;C:\hisenwork\soft\maven\io\netty\netty-all\4.0.29.Final\netty-all-4.0.29.Final.jar;C:\hisenwork\soft\maven\io\netty\netty\3.8.0.Final\netty-3.8.0.Final.jar;C:\hisenwork\soft\maven\com\clearspring\analytics\stream\2.7.0\stream-2.7.0.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-core\3.1.2\metrics-core-3.1.2.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-jvm\3.1.2\metrics-jvm-3.1.2.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-json\3.1.2\metrics-json-3.1.2.jar;C:\hisenwork\soft\maven\io\dropwizard\metrics\metrics-graphite\3.1.2\metrics-graphite-3.1.2.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\core\jackson-databind\2.6.5\jackson-databind-2.6.5.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\core\jackson-core\2.6.5\jackson-core-2.6.5.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\module\jackson-module-scala_2.11\2.6.5\jackson-module-scala_2.11-2.6.5.jar;C:\hisenwork\soft\maven\org\scala-lang\scala-reflect\2.11.7\scala-reflect-2.11.7.jar;C:\hisenwork\soft\maven\com\fasterxml\jackson\module\jackson-module-paranamer\2.6.5\jackson-module-paranamer-2.6.5.jar;C:\hisenwork\soft\maven\org\apache\ivy\ivy\2.4.0\ivy-2.4.0.jar;C:\hisenwork\soft\maven\oro\oro\2.0.8\oro-2.0.8.jar;C:\hisenwork\soft\maven\net\razorvine\pyrolite\4.9\pyrolite-4.9.jar;C:\hisenwork\soft\maven\net\sf\py4j\py4j\0.10.3\py4j-0.10.3.jar;C:\hisenwork\soft\maven\org\apache\spark\spark-tags_2.11\2.0.1\spark-tags_2.11-2.0.1.jar;C:\hisenwork\soft\maven\org\scalatest\scalatest_2.11\2.2.6\scalatest_2.11-2.2.6.jar;C:\hisenwork\soft\maven\org\scala-lang\modules\scala-xml_2.11\1.0.2\scala-xml_2.11-1.0.2.jar;C:\hisenwork\soft\maven\org\spark-project\spark\unused\1.0.0\unused-1.0.0.jar com.hisen.spark.SimpleApp |
某做科研的朋友
需要对一些地点的坐标
然后在 WGS-84 坐标系的底图上呈现相关内容
BD09 vs WGS84
北京韩美林艺术馆,BD09:116.68347847243588,39.88148624000483
北京韩美林艺术馆,WGS84:116.67097966259838,39.87446583754102
找了几个网址,反馈说之前用过坐标不准确
服务免费
需要实名认证
网址:lbsyun.baidu.com
我没有选择 IP 白名单
选择的是 SN 签名
获取 AK、SK
接口文档
之前 V2 版本的接口已经停用了
地址:地理编码文档
SN 生成
注意文档的生成方式还是 V2 的例子
地址:SN 生成文档
简单说明
地址文件格式一行一个
转换后会输出文件:地址,精度,纬度
CoordinateTransformUtil 在参考文档
/** |
注意,第一个文档的接口已经过时,新申请的用户无法使用
]]>现有的长城 100M 宽带太寒酸了
之前的住户说想升级光纤都没办法
于是乎咨询了下联通可否装光纤
答案是可以,换个套餐就行
桥接的好处就是,光猫只做光猫该做的事情。
其它事情由自己的路由器进行设置并且管理。
这样即使你搬家什么的,路由器搬走,
任何设备都不用动,包括固定内网 IP 等
我主要的点是固定内网 IP,因为我由 NAS
这一步是需要联系安装宽带的师傅
他们远程可以直接修改
如果改为桥接,那么原有网络无法使用
重点
我的路由器是网件 R8000,输入账号密码等配置生效。
完事之后就可以上午,但是,这时候 IPv6 是不好使的。
找到 IPv6 相关设置(高级—高级设置—IPv6)
选择 PPPoE,使用 IPv4 一样的账号密码拨号
等待配置生效,即可发现 IPv6 正常
IPv6 测试网址:test-ipv6.com
至于为什么要 IPv6,那只能说懂得都懂,啊哈哈。
桥接上网
这篇文章的一些观点我可能不太认同,
最重要的是,里面提到可以联系客服修改为桥接
这就很方便了,网上很多都是各种破解,挺麻烦。
zookeeper用来注册服务和进行负载均衡,哪一个服务由哪一个机器来提供必需让调用者知道,简单来说就是ip地址和服务名称的对应关系。
当然也可以 通过硬编码的方式把这种对应关系在调用方业务代码中实现,但是如果提供服务的机器挂掉调用者无法知晓,如果不更改代码会继续请求挂掉的机器提供服务。
zookeeper通过心跳机制可以检测挂掉的机器并将挂掉机器的ip和服务对应关系从列表中删除。至于支持高并发,简单来说就是横向扩展,在不更改代码 的情况通过添加机器来提高运算能力。
通过添加新的机器向zookeeper注册服务,服务的提供者多了能服务的客户就多了。
是管理中间层的工具,在业务层到数据仓库间有非常多服务的接入和服务提供者需要调度,dubbo提供一个框架解决这个问题。
注意这里的dubbo只是一个框架,至于你架子上放什么是完全取决于你的,就像一个汽车骨架,你需要配你的轮子引擎。
这个框架中要完成调度必须要有一个分布式的注册中心,储存所有服务的元数据,你可以用zk,也可以用别的,只是大家都用zk。
Dubbo的将注册中心进行抽象,是得它可以外接不同的存储媒介给注册中心提供服务,有ZooKeeper,Memcached,Redis等。
引入了ZooKeeper作为存储媒介,也就把ZooKeeper的特性引进来。
需要注册 Cloudflare 账号
这个服务目前是可以免费使用
速度的话一般,勉强可以接受。
后续再折腾看看是什么问题。
# 安装客户端 |
网页版:draw.io
桌面版:github 下载支持:Windows、macOS、Linux、Google Chrome OS
https://api.github.com/ |
这里介绍两个api
#获取个人信息 |
key | 含义 | value |
---|---|---|
login | 登录名称 | hisen-yuan |
id | 数字编号 | 16789019 |
avatar_url | 头像地址 | https://avatars1.githubusercontent.com/u/16789019?v=3 |
name | 用户昵称 | hisenyuan |
blog | 博客地址 | http://hisen.me |
location | 地理位置 | China |
bio | 个人说明 | Java R & D |
public_repos | 仓库个数 | 11 |
created_at | 创建时间 | 2016-01-20 01:57:15Z |
updated_at | 最后更新 | 2017-04-20 14:03:27Z |
#获取项目信息 |
key | 含义 | value |
---|---|---|
id | 项目编号 | 88646378 |
name | 项目名称 | dubbo |
html_url | 项目地址 | https://github.com/hisen-yuan/dubbo |
created_at | 创建时间 | 2017-04-18T16:21:57Z |
updated_at | 更新时间 | 2017-04-18T16:23:16Z |
pushed_at | 提交时间 | 2017-04-19T02:33:33Z |
size | 项目大小 | 6514 |
language | 编程语言 | Java |
current_user_url: "https://api.github.com/user", |
host位置:
C:\Windows\System32\drivers\etc |
host文件最后一行加上下面内容即可
192.30.253.112 github.com |
com.alibaba.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 14277263, max payload: 8388608, channel: NettyChannel [channel=[id: 0x12a13c8f, /172.0.0.1:49402 => /172.0.0.2:23888]] |
dubbo默认使用Netty传输协议
并且默认的大小限制为:默认为8M,即8388608
修改接口
出现这种情况是因为一个接口查某个表的所有数据(几万条)
一般这种接口肯定是需要分页的
更改配置信息
在dubbo.properties 中增加如下
dubbo.protocol.dubbo.payload=11557050 |
安装好上面三个工具
可能会遇到的问题:
1、Git Bash执行node -v
提示无效 或者 npm install
报 command not found
解决办法:在环境变量 - 用户变量中 - 新建用户变量 - 添加nodejs安装路径
如:C:\tool\nodejs
2、ERROR Deployer not found : github
解决办法:
3使用淘宝镜像加快安装速度
安装cnpm,使用命令:
npm install cnpm -g --registry=https://registry.npm.taobao.org |
npm install -g hexo
#等待安装完成,这个过程可能会快也可能很慢,耐心等待mkdir blog && cd blog
#上面这个代码是创建一个博客存放的目录hexo init
#初始化cnpm install
#安装依赖包hexo g
#生成静态页面hexo s
#启动服务器,打开http://localhost:4000 就是本地博客本地博客安装完成,下面介绍发布到github上
yourgithubname.github.io
Setting
_config.yml
配置文件deploy: |
最后执行
hexo g
#重新生成静态博客hexo d
#将本地静态博客部署到github现在你在浏览器打开:http://yourname.github.io就可以访问你的博客了
到此为止就搭建完了一个博客
开始写第一篇文章:
执行:hexo new “你的文章标题”
然后你在blog/source/_posts
文件夹下面有文件,用markdownpad打开编辑
执行:
hexo g
#重新生成hexo s
#本地查看效果hexo d
#上传到githubhexo d -g
有时候上线会出现合错代码,比如功能,或者maven的pom文件;
人都不是十全十美的人,只要是人就会犯错
关键是要想办法去避免,只有工具才不犯错
所以尽量想办法利用工具来防止我们犯错,git来说有很多办法;
简单的命令,或者gitlab的compare报告;
每次上线之前,开发自己看一遍当前版本与线上版本的区别,确认每一个点都是正确的改动;
2.1 入口:工程首页 -> Repository -> Compare
2.2 选择:上一个版本,当前版本,点击Compare
2.2 结果:一次能看到两个版本的所有commit、改动点
# 显示版本之间改动的文件名 |
这里是创建post的模板。
我的默认设置成这样:
--- |
tags: [关键词1,关键词2]
]]>响应国家就地过年的号召,今年第一次在外过年。
弹指一挥间,12 天的假期已经成为过去。
期间还是有不少的收获,最主要的是看了 4 本书。
以及在微博上面看到了不少的人和事,甚是触动。
找到自己的兴趣,追求精进,坚持做对的事情。
这本书是 leader 推荐给大家的
基于职责去做设计的理念确实很棒,值得观摩实践。
春节之前断断续续看了一部分,后面主要是春节在看。
关键是:要做对的事情,把事情做对。(前者更重要)
创始人对公司的文化影响很大,文化又对公司影响大。
有自己清晰的不为清单,发现错了立马纠正,因为这时候止损成本最低。
段永平的投资问答录其实很多时候也适合于人生建议,都是相通的。
很幸运有如此成功的人愿意与普通人进行交流,传授经验。
书本当中也能接触到不少成功人士,正所谓近朱者赤,
还有所谓的圈子,多看多想多学,总是会进步的。
实践出真知,作者成就非凡
其中的很多理念深度赞同
是一本值得翻阅的书,收益颇多
eg:
看完对马斯克以及他的企业和野心有更多的了解
羡慕他精力旺盛、超强的学习能力、以及追求梦想的执着
触动最大的就是@纯银V 一位产品经理的微博
特别是关于一个 95 后实习生的故事
也很佩服纯银从一个法警做到如此高阶的产品经理
羡慕他把看产品的思路套用在看公司上,然后 2020 投资中概股收益颇丰
感悟就是:积极、主动、为自己工作,找到喜欢的事情,持续精进。
和家里亲戚去郊区玩了几天,还是比较放松。
有时候不管是家人之间的沟通,还是朋友之间,可能更多的时候需要的是倾听,而不是讲道理。
犹如《代码精进之路》里讲的”不过在家里,我依然是输多赢少,后来我才发现,原来家不是一个讲逻辑的地方。”
安排好自己的时间,加强执行力!
]]>这里给出的解决办法是用hexo自动提交插件
需要获取一个自动提交的token
baidu_url_submit: |
加入新的deployer: 原来type前面是没有 - 的
但是不这样处理执行hexo g 会报错
deploy: |
生成效果如下:
$ hexo g |
感谢插件作者:王辉的博客
]]>CentOS系统更换软件安装源
第一步:备份你的原镜像文件,以免出错后可以恢复。
1、备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
2、下载新的CentOS-Base.repo 到/etc/yum.repos.d/
(如果无wget命令,底部有具体说明)
CentOS 5
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo |
CentOS 6
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo |
CentOS 7
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo |
3、之后运行yum makecache生成缓存
ps:如果你跟我一样苦逼:
-bash: wget: command not found |
然后:
yum -y install wget #失败 |
那么你可以直接选择上面对应系统的文件下载链接
下载好文件之后改名为CentOS-Base.repo
直接放到/etc/yum.repos.d/目录下即可
]]>但是刚刚看书上写出来的这个程序,居然不知道怎么在goland里面运行…
于是曲线救国,了解到打印输入的参数。
这断代码就是为了找出输入数据中的重复行
直接启动,不带参数,启动之后输入参数
参数0: /private/var/folders/lk/p8gbq87n6rvfndk7wlk23y8r0000gn/T/___go_build_dup2_go |
在命令行启动,带
$ go run dup2.go 'hisen.txt' |
package main |
一直么有重启,后来就安装了个插件重启一下,结果就泪崩了
一直出现这个错误
总以为是环境变量配置的问题,或者是文件损坏了什么
重启,重装jdk,重新配置什么都试过,不管用。
后来替换了配置文件就好了!!!
配置文件路径:
\IDEA HOME\bin\idea64.exe.vmoptions |
默认配置文件内容如下:
32bit
-server |
64bit
-Xms128m |
by the way:
IDEA 写博客真是舒服啊~
完全不用切换来切换去的!
]]>然后就搜了下自动连接远程服务,于是就发现了一个不错的脚步
整个设置过程还是比较顺畅,
操作步骤:
新建一个sh文件
vi auto_ssh.sh |
输入如下内容,[lindex $argv 0] 这个为第一个参数的占位符
!/usr/bin/expect |
复制脚本到bin下并且赋予执行权限
sudo cp auto_ssh.sh /usr/local/bin/ |
设置
在iTerm2中Command+o呼出profile
# 界面右下角,点击: |
本文灵感来自《人人都是产品经理 2.0》
位置:7.4.2 如何做一个让 Ta 们讨厌的人
作为一个研发,工作过程中如果能及时发现如下场景,
及时给对方负反馈,否则受伤的是整个团队。
看了这本书之后,感觉对产品有新的认知,
知道他们在做什么,怎么做,后续可以更好的与他们沟通。
而且里面的内容对于研发来讲也是适用的。
技术问”为什么要做”时:
1、时支支吾吾
2、这是老板(XXX)要的,假装自己是个传话筒
3、我接的是二手需求,什么都不知道
随说:其实正确的做法是追溯这个需求的初衷,有利于评估 ROI (投入产出比),以及排优先级,以及增进对业务的理解。
技术问细节(业务细节,非技术细节)时:
1、装作自己完全没有想过
2、那就这样做
3、肯能那样做也可以
4、要不你来定吧
随说:这些表现其实都是不负责的!没有明确的需要,后期容易扯皮,也可能做出来的东西有问题。
1、这不是很简单嘛,就改个 XXX,几行代码就搞定
2、这些我都评估过了,都能做
3、不要偷懒,不要忽悠我,我抖动
随说:评估真是个高难度的活,往往只见树木不见森林
1、任何时候只知道公事公办,技术承诺了却做不到,自己就没有责任了。
随说:互联网企业更多的只是一个”预测”,而非”承诺”,因为变化太快,承诺是技术对产品的责任,而预测是产研一起担责。
1、经常在某个迭代周期内做”非受迫的需求变更”,这招杀伤力很大,技术同学一般受不了。
随说:非受迫,意味着是产品没有想清楚,然后导致研发无谓劳动。万万不可取。
1、可以想各种办法隔绝与研发的联系。
随说:一般都需要多次沟通,反复确认细节。
1、帮技术确定各种技术方案,这个应该这样实现…
随说:这种一般少见,研发转岗产品的多一些
1、发布之后,犹如石沉大海,不告诉大家任何结果,甚至庆功宴都不叫 Ta 们,紧接着继续安排他们干活。
随说:技术人员也需要从市场、用户那里获得反馈,从而对自己做的事情产生价值感和成就感。
1、让研发一阵忙一阵闲,发布之后再开始研究接下来做什么。
2、一会儿让研发有着天天通宵的高强度,给 deadline,下死命令,做完之后不知道做什么。
随说:保持合理的安排,让研发有个合理的预期比较好。而不是等你们上了大学就自由了这种…
1、你定吧,你说往哪儿走我们照办
2、啊…那个…方案各有利弊,我也不知道怎么办,你们有什么好想法
随说:自己左手和右手互搏,思考清楚之后给大家一个明确的结果。
1、藏着噎着一些坏消息,eg:老板正考虑干掉这个项目等,大家只能通过小道消息得知
随说:这样很破坏信任感
1、只关注结果,不关注人的成长,永远把合作伙伴当”资源”
随说:结果导向没有问题,但是没有成长,留不住人。
2017年04月12日 18:26:37 星期三
<!DOCTYPE html> |
重复了一遍以往正常的不能再正常了的导入配置,结果遇到了如下问题:
SEVERE [RMI TCP Connection(3)-127.0.0.1]
15-Feb-2017 11:05:25.993 严重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Skipped installing application listeners due to previous error(s) |
因为idea要用的东西自己会自动生成
然后就搞定了这个纠结我一天的问题
我是百度搜索这个错误:RMI TCP Connection(3)-127.0.0.1
得到的答案,感谢10100:查看原文
]]>入坑水族几年,和年纪无关…
修生养性,培养一个兴趣爱好,毕竟生命在于折腾
下班回家,看着鱼儿在水中游,喂喂乌龟,也蛮有趣
最近几天在折腾过滤,
进一步了解了一下过滤系统,
也有朋友在问养鱼养龟方面的问题,
于是就想着写一篇博客简单的记录一下。
不懂的多百度,设备什么的购物平台搜搜。
有兴趣可以逛逛:南美水族论坛、乌龟吧(百度贴吧),等水族相关内容。
需要有一定的金钱投入,更重要的是精力投入,长期维护。
养宠物之前
一定要先了解清楚
自己喜欢什么,适合什么
先了解学习一些经验,不要着急入手
鳄鱼龟:互动性不错,有点危险,长的很快.
宝莲灯:个人比较喜欢的热带灯科鱼,小型的.
鱼缸
龟缸
主要考虑过滤使用
选择根系强大的挺水植物
选择透明的玻璃容器,观赏性比较好
鱼缸
龟缸
俗话说,养鱼先养水。
要想养好水,就需要过滤器材。
关于自来水
开缸尽量不要用自来水,
使用自来水最好是晾晒 2 天,
水质稳定之后,换水的时候也可以直接注入少量自来水。
使用过滤器
尽量增大水体体积
尽量增大水与滤材的接触面积(过滤效果好)
滤材表面积大利于细菌进行生长繁殖,可保持干净稳定的水。
滤材选择:表面积越大越好,一般比较贵;便宜的可以以量取胜。
异养细菌,把食物残渣、动物粪便等,转化成无机物,氨气(对动物有害)等。
硝化细菌,把氨气转换为硝酸盐(对动物无害),可以供植物吸收。
水循环大概过程:
『有机物(残渣、粪便)』 一异养细菌一> 『氨(有害)等其它无害物质』 一硝化细菌一> 『硝酸』 一> 『植物吸收』
硝化细菌:属于生产者,包括亚硝酸细菌(将氨氧化成亚硝酸),硝酸细菌(将亚硝酸氧化成硝酸),
硝化细菌(英语:nitrifying bacteria)是一群好氧的化能自养生物之统称,属于生产者,
细菌能通过食用无机氮化合物生长。硝化细菌以二氧化碳为碳源,通过代谢将氨或铵盐氧化成硝酸盐。
自养生物(英语:autotroph)也称为生产者(producer)
指食物链底端可以利用阳光(光合作用)或无机物氧化配以地热能(化能合成)
将空气和周边环境中的二氧化碳、水以及无机盐等制造成有机物来提供代谢底物并存储化学能的生物,
主要包括绿色植物、海藻和少数微生物(浮游植物)。
异养生物(英语:heterotroph),也称为消费者( consumer)
指不能直接利用无机物或有机物维生,必须摄取现成的养分来维持生存机能的生物。
除了runtimeException以外的异常,都属于checkedException。
CheckedException(受检异常):编译器会检查这类异常,需要强制捕获,否则无法编译通过。
UnCheckedException(非受检异常):编译器不会检查这类异常,可以不用捕获,可以编译通过。
受检:IOException、SQLException、NumberFormatException、IllegalArgumentException
非受检:OutOfMemoryError、StackOverflowError、NullPointerException、IndexOutOfBoundsException
点击查看所有jdk8 api文档
进去可以看到java.lang.RuntimeException下有很多子类异常
暂时写这些,日后再完善
]]>这个错误出现的原因有的说是因为jdbc配置文件写错了
正确的写法是:
c3p0.driverClass=com.mysql.jdbc.Driver |
而不是
driver=com.mysql.jdbc.Driver |
但是我遇到的不是如此
后来发现是因为maven出问题了,jar包没有加载进项目
这是在starkoverflow上看到的回答
In my case it was problem that c3p0-0.9.2.1.jar file was not copied by maven into src/main/webapp/web-inf/libs |
最后maven重新install之后就解决了
]]>今天导入到IDEA中去,发现编译出问题
ava编译错误:程序包javax.servlet不存在javax.servlet.*
原因大概是myeclipse中可以选择Java EE项目
而idea没有,缺少 servlet-api.jar 这个jar包
解决办法:
即可
]]>注册地址:https://zeroturnaround.com
注册完了之后在IDEA里面去设置,会提醒激活。
tomcat部署了项目之后,点击JR启动是可以热部署的!!!
改了java代码都不要重新启动项目,哈哈!!!
]]>看的过程中发现,结合一定的场景,和示例
和官方文档相比,没有那么枯燥,也更好理解
甚至有一些之前未曾关注的用法让我感到惊艳
所以推荐一下
]]>其中有一个经常发 Java 相关的内容
今天看到一个稍微熟悉一点关于 FastJson 漏洞
窃以为Fastjson入门的最佳篇章非Mi1k7ea这个系列莫属,郑重推荐: Mi1k7ea。
共有5篇,从第3篇开始,成体系地由旧到新展示了1.2.25之后各版本的补丁绕过,
直至思路惊艳的1.2.47绕过方案及1.2.48的修补方案,相当完备。
可以看出此君是动手实践派、整理归纳派,要我说,新学东西时就得这套路,无它。
今天看了这两篇文章,不得不说对 Java 是异常的熟悉。
想做好安全,想必要对用的东西了如指掌,知道坑在哪里,怎么填坑。
后记:
很多时候大部分人都只关注自己工作职责内的那一亩三分地
其实很多时候横向观察一下会发现很多靓丽的风景
至今没有如此深入的去看过底层甚是愧疚
用最多的时间去做最正确的事情!
理论原因:JVM在编译的时候能找到调用方法或静态变量所在的类,但在运行的时候找不到此类而引发的错误。
真实原因:(仅针对当前问题)
项目A依赖公共服务C-1.0.1版本
项目B依赖项目A,B中dependencyManagement强制指定C-1.0.0
此时编译可以通过,运行时如果有用的C的新版本功能就会会出现上述问题
解决办法:对项目B中C的版本升级,使用1.0.1
扩展阅读:
https://blog.csdn.net/qq_27576335/article/details/77102385
https://blog.csdn.net/jamesjxin/article/details/46606307
##显示当月的日历 |
fileChannelIn.read(byteBuffer) != -1
EOF = End Of File,其默认值就是-1
这是一个约定好的结束符,不是认为改变的
建议使用大文件进行测试,看效果比较明显
|
曾经整理过一个帖子,不过是在公司内网。
今天突然想起,博客上零散的 jvm 相关内容,
但未系统整理相关知识和工具,遂写一篇文章。
学习的过程需要不断发现好的资源,深入钻研某个领域。
目前测试机器为 4C8G
两台机器完全处理一样的工作
大部分时间对象朝生夕死,很少进入老年代
CMS 指定了新生代最大 1536M,略微有点浪费
于是设置 G1 自动调节各个区域大小,看看能否有所改善
也因为最近重温了两本 JVM 相关的书籍,找机会进行实践看看
-Xms4096M |
最大最小设置成一致的值,是为了不让堆大小进行收缩(缩的过程会 GC)
# 初始堆大小 |
Type | Duration | Xmn | YGC count | YGC avg | Interval Time |
---|---|---|---|---|---|
G1 | 72 hrs 21 min 8 sec | 1.66G | 7596 | 19.6 ms | 34 sec 294 ms |
CMS | 70 hrs 24 min 51 sec | 1.5G | 7029 | 14.4 ms | 36 sec 68 ms |
目前应用堆响应时间比较敏感,追求低延迟。
就上表来看,G1 新生代的大小确实上去了,但并不尽如人意。
但是随着而来的是 G1 『更频繁的YGC』以及『更长的停顿时间』
在《深入理解JVM虚拟机》第三版看到,
由于 G1 处理跨 region 需要耗费额外 10% ~ 20% 的资源,小堆 (堆大小<8G) 上没有优势。
JVM 新生代大小与老年代大小默认为 1:2,
大部分应用按这个设置是 OK 的,
虽然有时候看着老年代一直很小,
设置那么大浪费内存,但是当调用量大的时候,就能派上用场,减少 Full GC。
先占个坑,后续继续填内容。
]]>JDK8 因未指定 MetaSpace 大小,程序启动过程中元空间不够用,触发 full gc。
详细如下:
JDK8 因未指定 MetaSpace 大小,默认初始大小约 21M
程序启动,元空间大小占用稳定在 90M
因为超过了默认元空间大小,导致元空间扩容(每次扩容会 full gc)
从 GC 日志来看,每次元空间扩容都是增加 20M 左右,所以程序启动时 full gc 4 次
应用启动时出现 full gc;
gc日志重点:GC (Metadata GC Threshold) [PSYoungGen: 354024K->15340K(1376256K)
启动过程中,出现了 JVM Full GC 告警。
由于启动过程中之前没有遇到这种情况,找不到其它原因。
于是修改 JVM 参数,增加 GC 日志,于是就看到了『二』中的内容。
看原因是元空间内存不够大导致的
通过 GC 日志可以看到元空间实际占用大小,100M
于是调整 JVM 元空间大小至 128M,问题解决。
问题是解决了,但是原因是什么呢?
在结论部分已经讲了,这里不重复。
所谓知其然,更要知其所以然。
只有这样才能明白问题的本质,学到知识。
tail -f test.log
你会看到屏幕不断有内容被打印出来. 这时候中断第一个进程Ctrl-C,
cat -n hisen.log | grep ‘907’
在文件当中查找指定的内容,这里是查询:907
linux 如何显示一个文件的某几行(中间几行)
从第3000行开始,显示1000行。即显示3000~3999行
cat filename | tail -n +3000 | head -n 1000 |
显示1000行到3000行
cat filename| head -n 3000 | tail -n +1000 |
*注意两种方法的顺序
分解:
用sed命令
sed -n ‘5,10p’ filename 这样你就可以只查看文件的第5行到第10行。
例:cat mylog.log | tail -n 1000 #输出mylog.log 文件最后一千行
cat主要有三大功能:
1.一次显示整个文件。$ cat filename
2.从键盘创建一个文件。$ cat > filename
只能创建新文件,不能编辑已有文件.
3.将几个文件合并为一个文件: $cat file1 file2 > file
参数:
-n 或 –number 由 1 开始对所有输出的行数编号
-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 –show-nonprinting
例:
把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里
cat -n textfile1 > textfile2 |
把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。
cat -b textfile1 textfile2 >> textfile3 |
把test.txt文件扔进垃圾箱,赋空值test.txt
cat /dev/null > /etc/test.txt |
注意:>意思是创建,>>是追加。千万不要弄混了。
tac (反向列示)
tac 是将 cat 反写过来,所以他的功能就跟 cat 相反, cat 是由第一行到最后一行连续显示在萤幕上,
而 tac 则是由最后一行到第一行反向在萤幕上显示出来!
在Linux中echo命令用来在标准输出上显示一段字符,比如:
echo “the echo command test!”
这个就会输出“the echo command test!”这一行文字!
echo “the echo command test!”>a.sh
这个就会在a.sh文件中输出“the echo command test!”这一行文字!
该命令的一般格式为: echo [ -n ] 字符串其中选项n表示输出文字后不换行;字符串能加引号,也能不加引号。
用echo命令输出加引号的字符串时,将字符串原样输出;
用echo命令输出不加引号的字符串时,将字符串中的各个单词作为字符串输出,各字符串之间用一个空格分割。
#在整个文件搜索含有907的内容 |
我是使用IDEA,maven
具体的目录结果见github:github
#可以设置级别:debug>info>error |
package com.hisen.log4j.log4j2MySQL; |
###设置 |
log4j详细使用方法:点击查看
]]>hisen@ubuntu:~$ mongo |
看倒数第二行,应该是权限的问题,于是
hisen@ubuntu:~$ sudo chown -R hisen /home/hisen/.mongorc.js |
完美解决,用户权限的问题。
]]>《贫穷的本质》告诉我们,贫穷的本质是认知。其实很多时候真的是认知,方法论决定了一个人可以走多远。
《刻意练习》原地踏步的练习是没意义的,大众眼里一万小时定律基本上是错误的,需要的是有进步练习;
《学习之道》十个不错的方法:运用回想、知识组块、简化类比、方法交替、间隔重复、注意休息、心理对照、自我测试、保持专注、困难先行;
《如何阅读一本书》里面有提到主题阅读,不同的人对同一主题会有不同的看法,可以对比吸收;
《程序员的职业素养》有提到卡塔练习,提高我们的肌肉反应,让写代码像聊天打字一遍的顺畅;
早些天看到一篇不错的帖子
对我感触最深的就是:4
标题:如果高效学习有什么秘诀的话,那就都在这里了:)
1)不要完美主义!
2)不要过度“学习路径依赖”,学习要冲着自己的目标去。
3)不要迷信权威的“好”教材。
4)不要看不起“薄薄”的“傻”教材,这些你看不起的学习材料,可能是你入门某个领域的关键。
5)不要迷信单一教材。
6)实践!
7)debug非常非常重要。
8)量变到质变。
9)最后,一定要相信时间的力量。
参考:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.hisen.dao.UserMapper.insert |
使用mybatis生成插件,产生的mapper,由于路径不对移动了一下mapper.java文件
所以造成mapper.xml里面的namespace错误,无法映射
所以把namespace改为正确的即可
例如:
mapper.UserMapper
改为
com.hisen.dao.UserMapper
]]>想用docker搭建一个lnmp环境
使用这个脚本:
https://github.com/buxiaomo/docker-compose/tree/master/lnmp |
执行命令之后报错
docker-compose -f lnmp.yml up -d |
查看当前机器时间文件真实位置(/etc/localtime 这个路径是不让共享给docker的)
ls -la /etc/localtime |
设置位置 :Docker -> Preferences… -> File Sharing
docker-compose -f lnmp.yml up -d |
1.1 使用Homebrew安装go环境(如果很慢,可以换个源)
brew install go |
1.2 查看安装信息
go env |
主要关注如下输出
GOROOT="/usr/local/Cellar/go/1.10.3/libexec" # 安装目录 |
1.3 配置环境变量
vi ~/.bash_profile # 没有的话会新建一个文件 |
输入如下内容,第一行是安装的目录,第三行是工作目录(可以改成自己喜欢的路径)
GOROOT=/usr/local/Cellar/go/1.10.3/libexec |
1.4 让配置文件生效并且查看环境变量
source ~/.bash_profile |
我是习惯了用jetbrains的idea
发现它家也有go语言的IDE GoLand
于是就去官网下载,安装,找个注册码,修改一下host防止注册码失效
这里就不再累赘了
买了一本《Go语言程序设计》
有些程序需要从标准输入获取信息,然后进行处理,例如dup2
运行之后不知道该肿么办,百度一番之后发现了方法
命令行:Ctl + D
GoLand:command + D
贴一段程序和运行的结果
package main |
JDBC Type | Java Type |
---|---|
CHAR | String |
VARCHAR | String |
LONGVARCHAR | String |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
BIT | boolean |
BOOLEAN | boolean |
TINYINT | byte |
SMALLINT | short |
INTEGER | int |
BIGINT | long |
REAL | float |
FLOAT | double |
DOUBLE | double |
BINARY | byte[] |
VARBINARY | byte[] |
LONGVARBINARY | byte[] |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
CLOB | Clob |
BLOB | Blob |
ARRAY | Array |
DISTINCT | mapping of underlying type |
STRUCT | Struct |
REF | Ref |
DATALINK | java.net.URL |
2015 年刚毕业的我懵懵懂懂看书都想睡觉
很开心来到北京遇到了许多美好的人和事
受到环境的影响一路走来成长加速收获颇丰
从 2016 开始慢慢喜欢上了阅读
从开始看书就想睡觉到现在一个6层书架都放不下的纸质书
从开始的『kindle voyage』到现在的『kindle oasis』第三代
从开始的只是在北京地铁5号线看下电子书到现在有点时间就看
慢慢地养成了阅读的习惯,生活也没有那么无聊,工作慢慢步入正轨
非技术书籍喜欢用 kindle 看,技术书还是纸书比较合适翻阅
简单统计
2020 51本
2019 71本
2018 38本
2017 48本(2017以及之前)
Q:看书想睡觉怎么办?
A:先找有兴趣/好奇的主题
Q:看书记不住怎么办?
A:能不能记住无所谓,看的过程中有思考即可,好的书多看几遍
Q:哪来这么多时间?
A:合理安排时间,少浪费时间即可(通勤+早晚+中午,最少有3个小时时间)
读书使人充实,读史使人明智,读诗使人灵秀,
数学使人周密,科学使人深刻,伦理使人庄重,逻辑修辞学使人善辩
古人说开卷有益(无营养的除外)
通过阅读我们可以了解他人的经历
在他人的经历中我们可以得到经验
在他人的经验当中我们可以得到思想
一个人毕竟阅历有限,站在巨人的肩膀上你可以看的更高
科普性的书很多时候会恍然大悟
技术性的书能获得很多优秀的设计和实践以及学习新的技能
人文历史地里这些基本上是扩展知识面、提高个人综合素养、探索人生存在的意义
从我的书单(hisen.me/booklist/)当中可以看出
刚开始的时候基本上都是兴趣导向
俗话说兴趣是最好的老师,有些好书恨不得立马就看完,
接触很多人说看书就想睡觉,其实那不是我们的错,
是书没有写好,换一本就好了,如果还是不行,那就继续换。
当找到感兴趣的主题,看了一段时间之后
会发现阅读速度会有所提升,也会有很强的满足感
毕竟看的过程中总会有所收获,有所思考
兴趣是最好的老师,但是兴趣不能当饭吃
这个时候应该开始找一些通俗易懂的技术书,而不是那些很难啃的枕头
还是以有趣,通俗易懂为主
坚持一段时间,技术上也会有所收获
慢慢的就可以驰骋技术书籍的战场了
如果有时候发现看不下去了
那么就切换其它类型的书籍(我一般都是一本技术一本非技术)
建议看看《如何阅读一本书》
当通过阅读,名利双收的时候,我想没有几个人会不沉迷于阅读
想做到名利双收,需要养成好的习惯,挑选好的书籍
建议看看相关领域大佬分享的书单,或者直接咨询
书籍看多了实践也得跟上
有条件可以合志同道合的人一起看同一本书,看的时候多交流探讨,会有意想不到的效果
贫穷的本质是认知的差异
阅读、反馈、实践慢慢迭代认知
有长远的目标,不负韶华,坚持学习,努力提高
new ImageIcon("1.jpg") |
正确:
new ImageIcon("src/com/hisen/thread/progressbar/1.jpg") |
图片路径:
test\src\com\hisen\thread\progressbar\1.jpg |
所谓的相对路径,是相对于这个工程而言的,而不是当前文件夹而言。
]]>27-Feb-2017 12:53:31.268 严重 [RMI TCP Connection(13)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method manageApp |
重要的是:
org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method manageApp |
Project Structure -> Artifacts
查看里面是否有配置相同的Artifacts
删除即可
]]>今天人家给我个powerdesigner设计好的表
要我去间数据库,直接复制出来去oracle执行,结果报错。
在comment附近,如果把comment去掉则可以正确执行
最后找到罪魁祸首:powerdesigner没有设置对数据库
解决办法,在powerdesigner页面
database-->change curren DBMS |
上面是设置你需要的数据库
下面是为更改前的数据库
]]>Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00) |
1.自定义下载目录,修改配置文件
C:\hisenwork\soft\maven-3.3.9\conf\settings.xml |
C:\hisenwork\soft\maven-3.3.9为你解压的maven路径
ps:如果不想自己设置,我有现成的settings.xml,直接复制粘贴,覆盖原来的即可
现成的settings.xml内容我放在底部
搜索:localRepository
在注释外添加以下代码,以后下载maven相关文件就会在这
<!--自定义存放目录--> |
2.自定义镜像(推荐阿里云,速度飞快)
搜索:mirrors
在里面添加:
<!--阿里云--> |
3.运行命令初始化maven
mvn help:system |
然后你会看到命令行飞快的移动,在你刚刚设置的目录下会出现很多东西
类似于这样
$ mvn help:system |
创建 Maven 项目
mvn archetype:create |
编译源代码(编译到target文件夹中)
mvn compile |
编译测试代码
mvn test-compile |
运行应用程序中的单元测试
mvn test |
生成项目相关信息的网站
mvn site |
清除目标目录中的生成结果(把默认target文件夹中的数据清理)
mvn clean |
项目打包
mvn package |
将打包好的包安装到本地仓库中,以使其塔项目能够调用
mvn install |
生成 Eclipse 项目文件
mvn eclipse:eclipse |
忽略测试文档编译
mvn -Dmaven.test.skip=true |
部署到私有服务器
cargo:deploy |
<?xml version="1.0" encoding="UTF-8"?> |
简单介绍,《凤凰架构》作者,周志明。
他最出名的书籍非《深入理解Java虚拟机》莫属了
书中了解到他对技术的态度,以及持续奋战一线值得学习,《程序员之路》值得一看(底部有链接)。
阅读时间:0531~0612
构建凤凰磐涅般的系统
介绍了一整套技术体系
穿插着技术的来龙去脉
着实是一部不错的书籍
架构的前提是足够了解
综合实际情况做出权衡
给人感觉不太像架构书
总的来说还是值得一看
用输出倒逼输入
这就是写博客等其它输出手段的作用
目前的软件没有烟囱式的,都是金字塔类型,所以底层基础要牢固!
四层负载均衡的优势是性能高
主要工作在
数据链路层(2层),改写Mac地址
网络层(3层),改写 IP 地址
七层负载均衡的优势是功能强
将简单的校验交给 bean validation,
而把复杂校验留给自己,简直就是买株还珠。
可以使用自定义注解,优雅地解决校验问题。
检查校验项预置好默认提示信息。
基础校验直接放在 bean 属性上,业务的单开类。
能够使用确定的操作,促使状态间产生确定的转移结果的计算模型,在计算机科学中被称为状态机。
状态机特性:任何初始状态一样的状态机,如果执行的命令序列一样,则最终达到的状态也一样。(可用于分布式协商…)
广播指令、状态机复制。
让各个系统节点不受局部网络分区、机器崩溃、执行性能、其它因素影响,都能最终表现出整体一致的过程,被称为各个节点的协商共识。
一致性是指数据不同副本之间的差异,
共识是指达成一致性的方法与过程。
足可见技术圈里即使再有本事,也需要好好包装一下。paxos 论文发表三次后,被谷歌实现之后,凭着谷歌大拿的高度评价,获得了极大的关注。
操作转移模型
状态转移模型
达成共识的三步
网关 = 路由器(基础职能) + 过滤器(可选职能)
打饭解释各种 I/O 模型
异步 I/O :下完外卖订单后干别的去,骑手送上门
同步 I/O
阻塞:打饭发现饭还没好,就一直干等着
非阻塞:打饭发现饭还没好,per 3min 看好了没
多路复用:同上,只是一个人可以处理多个请求
信号驱动:发现饭没好,让厨师好了通知你
BFF网关:backends for frontends,针对网关这种边缘节点,对同样的后端集群,裁剪、适配、聚合出不一样的前端服务,有助于后端的稳定,也有助于前端的赋能。
由于服务随时都有可能崩溃,因此快速的失败检测和自动恢复就显得至关重要。
lstio(mesh) 在 1.5 之前是使用微服务架构开发
模块如下
微服务的目的是有效拆分应用,实现敏捷开发和部署。
凡事总该现有目的,有预期收益再谈行动才显得合理。
《没有银弹》:硬件的成本能够持续稳定地下降,而软件开发的成本则不可能。
系统的架构趋同于系统设计团队的沟通解构。
康威定律核心观点:沟通决定设计
大厂研发收到追捧,出除了企业本身的光环外(来自于哪里?),有大型系统浸染的经验,更有可能属于技术专家,也是其中的原因。
微服务对普通业务研发友好,但是对架构要求极高。
微服务的前提
需要想清楚做一件事的目的是什么?考虑 ROI
长期来看,多数服务端结局都是报废而非演进–Martin Fowler。
随说:良好设计的系统,应该是能够报废的,而非一味追求一步到位。
微服务拆分粒度
下界:独立(发布 / 部署 / 运行 / 测试),内聚(本地事务)
上界:2 披萨团队 (6~12)在一个研发周期完成全部需求。
治理,系统复杂性下的产物。
软件研发的认知负荷,本质上是来自技术的认知复杂度。
分布式系统早已放弃 Unix 所追求的简单性设计哲学。
治理架构腐化唯一有效的办法就是演进式设计。
开发过程中少妥协,否则会形成破窗效应。
Architect 架构师一词从建筑行业借鉴而来,让人容易误解架构师类似于给建筑设计骨架、绘制图纸的建筑架构师。演进式设计更像是“换房子”而不是“造房子”。
先进的生产力都伴随着更高的复杂性,需要有与生产力符合的生产关系来匹配,敏锐地捕捉到生产力的变化,随时调整生产关系,这才是架构师治理复杂性的终极方法。
1992 Java write once,run anywhere。
2018 graal vm,run programs faster anywhere。
目前 graal vm
优势:启动时间快,打包小,内存消耗少
劣势:无法无缝支持动态代理技术,延迟、吞吐量、可监控方面略差,性能劣于 hotspot jit 优化。毕竟是运行时优化,各种分支预测~
将思考具象化。
如果不把自己思考的内容输出给他人,
我们很容易就被自己所欺骗,
误以为自己已经理解得足够完备了。
随说:用输出倒逼输入。
纸书作者应该还在初版中,目前看的是 PDF.
这本书属于开源书籍,开源地址:《凤凰架构》
凤凰架构附录的一篇文章不错:《程序员之路》
mybatis:No constructor found in xxx matching [java.lang.Integer, java.lang.String, java.lang.Integer]
原因:xxx 这个bean缺少一个默认的构造方法!
解决:加上默认的构造方法即可
我是在单元测试的时候遇到这个问题
]]>echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list |
# 打开管理页面功能 |
ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN.
帐号密码错误,建议使用2.3配置的账户,guest账户不靠谱
connection error
ip或者port错误,确认信息是否正确,虚拟机的话看看端口映射是否正常
# 添加普通用户 |
<dependency> |
package com.hisen.jars.rabbitmq; |
package com.hisen.jars.rabbitmq; |
鉴于目前 Redis 使用广泛
虽然数据结构、API 比较简单
但是想使用好,还是有一定难度
建议了解下《Redis 开发与运维》
以达到知其然且知其所以然的境界
大规模互联网在线应用
流量比较大,响应时间要求高
Redis 作为一款流行的高性能数据库
对于读多写少的场景,一般作为缓存使用
某大型电商订单系统读写比大概在 10:1
并且订单读取 90% 的流量都是创建订单当天查询
对于可容忍丢数据,但是对性能有极致要求,
比如优惠券发放,流量高,这种情况下当做 DB 用也挺好。
《Redis开发与运维》20 1121~1122
dbsize 获取当前数据库中键总数,复杂度 O(1)
keys * 复杂度 O(n)
type key 返回 redis 外部数据结构
object encoding key 返回 redis 内部编码实现
redis 为单线程模型,所有命令都进队列。
redis 单线程为何还这么快?
锁和线程切换通常是性能杀手。
单线程可以简化数据结构和算法。
由于是单线程,所以对每个命令执行时间有要求。
redis 是面向快速执行场景的数据库。
mget 结果是按照传入键的顺序返回。
redis 中每个中文占 3 个字节
随说:utf-8 汉字 3 ,ascii unicode 2
字符串类型的内部编码有 3 种:
list 的 lrange 操作获取指定索引范围的元素。
对于字符串类型的键,再次执行 set 命令会将上次的过期时间去掉。
纯内存存储、I/O多路复用技术、单线程架构是 redis 高性能的三个因素。
了解每个命令的时间复杂度在
redis 命令真正执行的时间通常在微妙级别,所以才会有 redis 性能瓶颈是网络的说法。
原生批命令与 pipeline 的区别:
pipeline 只能操作一个 redis 实例,但即使在分布式 redis 场景中,也可以作为批量操作的重要优化手段。
redis 3.2 版本提供了 geo 功能,支持 LBS 服务。
geo 功能是 redis 借鉴了 ardb 功能实现,ardb 的作者来自中国。
输出缓冲区由两部分组成:
RESP(Redis Serialization Protocol Redis),协议。
保证客户端与服务端的正常通信,是各种编程语言开发客户端的基础。
jedis 没有内置序列化工具,需要自己选用。
page 121 有使用 protostuff (protobuf的Java客户端)进行操作的例子。
随说:这块 21 年出实际场景测试过,时间、空间复杂度优化幅度都蛮大
理解 redis 通信原理和建立完善的监控系统对快速定位客户端常见问题非常有帮助。
redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理,压缩后的文件远远小于内存大小。
正常情况下,fork 操作耗时应该是每 GB 消耗 20 毫秒左右。
redis 是 CPU 密集型服务,不要做绑定单核 CPU 操作。
由于子进程非常消耗 CPU,会和父进程产生单核资源竞争。
子进程通过 fork 操作产生,理论上需要两倍的内存来完成持久化,
但 Linux 有写时复制机制(copy-on-write),
父子进程会共享相同的物理内存页,
当父进程处理写请求时会把要修改的页创建副本,
而子进程在 fork 操作过程中共享整个父进程内存快照。
复制功能是高可用 redis 的基础。
主从复制延迟,redis 提供了 repl-disable-tcp-nodelay 参数控制是否关闭,
TCP_NODELAY,默认为 no,即开启 TCP_NODELAY 功能,
这时主节点会合并较小的 TCP 数据包节省带宽但是增大了主从之间的延迟,
适用于跨机房部署。如果为 yes,那么会立即发送,适合同机房网络。
对于写并发量较高的场景,
多个从节点会导致主节点写命令的多次发送从而过度消耗网络带宽,
同时也加重了主节点的负载影响服务稳定性。
psync 2.8 以上支持,有全量复制,部分复制
需要组件支持:
redis 支持无盘复制,repl-diskless-sync,试验阶段,
rdb 文件不保存到硬盘而直接通过网络发送给从节点。
为了降低主从延迟,
一般把 redis 主从部署在同机房 / 同城机房,
避免网络延迟和网络分区造成的心跳中断等情况。
对于读写分离,会造成从节点数据延迟,
可以编写外部监控程序监听主从节点的复制偏移量,
当延迟较大时出发报警或者通知客户端避免读取延迟过高的从节点。
为了保证复制一致性,从节点自身永远不会主动删除超时数据。
建议做读写分离之前,
可以考虑使用 redis cluster 等分布式解决方案,
这样不止扩展了读性能还可以扩展写性能和可支撑数据规模,
并且一致性和故障转移也可以得到保证,
对客户端的维护逻辑也相对容易。读写分离成本太高
redis-cli –bigkeys
把历史扫描过的最大对象统计出来,分析优化
带宽瓶颈通常出现在以下几个方面:
网络快慢:同物理机 > 同机架 > 跨机架 > 同机房 > 同城机房 > 异地机房
随说:但它们的容灾性正好相反
redis 进程的内存消耗主要包括:自身内存 + 对象内存 + 缓冲内存 + 内存碎片。
对象内存是 redis 内存占用最大的一块,存储着用户所有的数据。
输入输出缓冲区在大流量的场景中容易失控,造成 redis 内存的不稳定,需要重点关注。
由于进程内保存大量的键,
维护每个键精准的过期删除机制会导致消耗大量的 CPU,
对于单线程的 redis 来说成本过高,
因此 redis 采用惰性删除和定时任务删除机制实现过期键的内存回收。
在高并发放场景下,建议字符串长度控制在 39 字节以内,
以减少 redisObject 内存分配次数,从而提高性能。
尽量减少字符串频繁修改操作如 append、setrange,
改为直接使用 set 修改字符串,降低预分配带来的内存浪费和内存碎片化。
redis sentinel 有一套合理的监控机来判断节点不可达,有三个定时任务:
redis 使用 raft 算法实现领导者的选举。
redis sentinel 是 redis 的高可用方案实现:故障发现、故障自动转移、配置中心、客户端通知
redis sentinel 模式下,客户端初始化连接的是 sentinel 节点集合,
不再是具体的 redis 节点,但 sentinel 只是配置中心不是代理。
redis cluster 是 redis 的分布式解决方案。当遇到单机内存、并发、流量等瓶颈时,
可以采用 cluster 架构方案达到负载均衡的目的。
redis cluster 之前的分布式方案:
数据分区是分布式存储的核心,
理解和灵活运用数据分区规则对于掌握 redis cluster 非常有帮助。
redis cluster 限制:
在分布式存储中需要提供维护节点元数据信息的机制,
所谓元数据是指:节点负责哪些数据,是否出现故障等状态信息。
常见的元数据维护方式分为:集中式、P2P方式
redis cluster 采用 P2P 的 Gossip(流言) 协议,
Gossip 协议工作原理就是节点彼此不断通信交换信息,
一段时间之后所有节点都会知道集群完整信息。
虽然 Gossip 协议的信息交换机制具有天然的分布式特性,但他是有成本的。
redis 集群内节点通信频率为每秒 10次。单次通信消息 > 2KB,
消息体携带的数据量根集群节点数息息相关,更大的集群代表更大的通信成本。
因此对于 redis 集群来说并不是大而全的集群更好,需要对集群的规模做限制。
随说:大规模集群可以考虑使用哨兵模式、或者拆分 redis cluster
集群内 Gossip 消息通信本身会消耗带宽,官方建议集群最大规模在 1000 以内。
redis cluster 可以实现对节点的灵活上下线控制。
其中原理可以抽象为槽和对应数据在不同节点之间的灵活移动。
集群伸缩=槽和数据在节点之间移动。
MOVED 重定向:在集群模式下 redis 接收 key 相关命令先计算对应的槽,再根据槽找到节点,
如果节点是自身,则处理命令,否则返回 MOVED 重定向错误,通知客户端请求正确的节点。
键使用大括号包含的内容又叫做 hash_tag,它提供不同的键可以具备相同的 slot 功能,
常用于 redis I/O 优化。在集群模式下实现 mget mset pipeline 等操作。
smart 客户端通过在内部维护
slot → node 的映射关系,本地就可以实现
key → node 的查找,从而保证 I/O 效率低最大化,而 MOVED 重定向负责协助 smart 客户端更新 slot → node 映射。
jediscluster 解析 cluster slots 结果缓存到本地,为每个节点创建唯一的 jedispool 连接池。
cluster slots 风暴:
针对以上问题,jedis 2.8.2 版本做了改进:
jedis cluster 中由于 key 分布在不同的节点上,会造成无法实现 mget、mset 等功能。
但是可以利用 CRC16 计算出 key → slot,以及 smart 客户端保存 slot → node 的特性,
将属于同一个 redis 节点的 key 进行归类,
然后分别对每个节点对应的子 key 列表执行 mget 或者 pipeline 操作。
ASK 与 MOVED 都是对客户端重定向控制,ASK 表示集群正在进行 slot 迁移,
不知道什么时候完成。MOVED 明确表示 slot 对应的节点,因此需要更新 slot 缓存。
配置纪元的应用场景有:
配置纪元的主要作用:
唯品会开发的 redis-migrate-tool 支持在线迁移,
采用多线程加速,提供数据校验和查看迁移状态等功能。
随说:在 github 开源了
缓存更新策略最佳实践
缓存粒度问题
使用布隆过滤器减少缓存击穿,page 351
随说:订单业务很难做到,特别是订单量大
无底洞:投入越多不一定产出越多
无底洞优化
NTP 是一种保证不同时钟一致性的服务。
redis cluster | sentinel 如果多个节点时间不一致,
会影响日志排查,但不会影响功能,节点依赖各自的时钟。
redis 公网无密码情况下,黑客可以写入公钥,通过设置 rdb 文件目录到 /root/.ssh 目录,
并且文件名设置为 authorized_keys 即可实现免密登录。爆破主机。
redis bind 参数指定的是 redis 和哪个网卡绑定(建议绑定内网),和客户端什么网段没有关系。
bigkey,一般字符串类型 value 超过 10KB 就是 bigkey 了,但这个值和具体的 OPS 相关。
redis 查看 key 的大小:debug object key
看其中的 serializedlength 即可。
分页查询一般都会想到 offset limit
当不停机需要全量同步数据时
有可能会漏掉或者重复处理很多数据
因为中途会有数据改动
每次分页内的数据与预期的会有出入
offset 会进行全表扫描
通过不变的字段进行排序
最好是使用递增的主键索引
select * |
“I wish i had” vs “I’m glad i did”
人生会不会留下遗憾,在 20 年之后的这两句话中就能看出。
希望 20 年后的自己,能够很自豪的说:I’m glad i did.
这是一个只定义了标准的日志组件
|
常见配置:log4j.xml
|
由于目前经常需要登录数据库查询相关数据
每次进行登录一系列操作,有点费劲
于是乎想着看看怎么自动化
限制:需要在堡垒机进行操作
expect是一个自动化交互套件,
主要应用于执行命令和程序时,
系统以交互形式要求输入指定字符串,实现交互通信。
Awk是一种便于使用且表达能力强的程序设计语言,
可应用于各种计算和数据处理任务。
入门指南
说明:基于 expect
文件:mysqlLogin.sh
!/usr//bin/expect -f |
说明:通过 shell 动态获取登录信息
文件:autologin.sh
!/usr/bin/bash |
设置完成之后,输入 ma 命令,即可自动登录到 MySQL 客户端
cat ~/.bashrc |
在Oracle 11g中,Oracle 又增加了2个查询:pivot(行转列) 和unpivot(列转行)
下面是在mysql中的操作:
mysql> select * from test; |
在近两年高并发系统 DevOps 的过程中,
遇到了很多底层的问你题,eg: 网络、硬件、虚拟机等,
有些现象虽然知其然,但是不知其所以然,书到用时方恨少!
抱着深入学习的心态这两年看了一些相关书籍:
《计算机网络:自顶向下方法》
《操作系统精髓与设计原理》
《Java性能优化权威指南》
《Redis运维与开发》
《性能之巅》
收获甚大 所以想继续深入学习
误打误撞,看到了之前在 GitHub 关注的一个『自学计算机科学』仓库,很赞同下面这个观点
软件工程师分为两种:
这两种人都自称软件工程师,都能在职业生涯早期挣到差不多的工资。
然而,随着时间流逝,第一种工程师不断成长,所做的事情将会越来越有意义且更为高薪,
不论是有价值的商业工作、突破性的开源项目、技术上的领导力或者高质量的个人贡献。
科目 | 为何要学 | 最佳书籍 | 最佳视频 |
---|---|---|---|
编程 | 不要做一个“永远没彻底搞懂”诸如递归等概念的程序员。 | 《计算机程序的构造和解释》 | Brian Harvey’s Berkeley CS 61A |
计算机架构 | 如果你对于计算机如何工作没有具体的概念,那么你所做出的所有高级抽象都是空中楼阁。 | 《深入理解计算机系统》 | Berkeley CS 61C |
算法与数据结构 | 如果你不懂得如何使用栈、队列、树、图等常见数据结构,遇到有难度的问题时,你将束手无策。 | 《算法设计手册》 | Steven Skiena’s lectures |
数学知识 | 计算机科学基本上是应用数学的一个“跑偏的”分支,因此学习数学将会给你带来竞争优势。 | 《计算机科学中的数学》 | Tom Leighton’s MIT 6.042J |
操作系统 | 你所写的代码,基本上都由操作系统来运行,因此你应当了解其运作的原理。 | 《操作系统导论》 | Berkeley CS 162 |
计算机网络 | 互联网已然势不可挡:理解工作原理才能解锁全部潜力。 | 《计算机网络:自顶向下方法》 | Stanford CS 144 |
数据库 | 对于多数重要程序,数据是其核心,然而很少人理解数据库系统的工作原理。 | 《Readings in Database Systems》 (暂无中译本) | Joe Hellerstein’s Berkeley CS 186 |
编程语言与编译器 | 若你懂得编程语言和编译器如何工作,你就能写出更好的代码,更轻松地学习新的编程语言。 | 《Crafting Interpreters》 | Alex Aiken’s course on Lagunita |
分布式系统 | 如今,多数 系统都是分布式的。 | 《数据密集型应用系统设计》 | MIT 6.824 |
内容值得一看,真心建议多花功夫学好底层知识。
原文:Teach Yourself Computer Science
翻译:自学计算机科学
来自亚马逊 CTO 的博文也值得一看,操作系统经典书籍
The OS Classics
关键错误信息:
java.lang.RuntimeException: RESTeasy Provider Factory is null, do you have the ResteasyBootstrap listener configured?
java.lang.RuntimeException: Illegal to inject a message body into a singleton into public com.alibaba.fastjson.support.jaxrs.FastJsonProvider(java.lang.String)
resteasy:JBoss的一个开源项目,提供一套完整的框架帮助开发人员构建RESTful Web Service和RESTful Java应用程序。
fastjson:由阿里开发的一个性能很好的Java JSON 解析器和生成器。
引起错误的依赖
<dependency> |
2019-08-03 11:51:22,491 ERROR - [RMI TCP Connection(2)-127.0.0.1] - Context initialization failed |
tomcat localhost long
八月 03, 2019 11:51:22 上午 org.apache.catalina.core.ApplicationContext log |
<dependency> |
暂时不知道引起的原因,后期补充
]]>缓存是针对读多写少的场景典型的以空间换时间的操作
空间:内存
时间:读内存速度快(相对于读磁盘)
这个世界很多事情都符合 2/8 原则
把热点数据缓存起来就大大提高系统效率
先读缓存、再读DB
如果是并发读缓存失效,使用分布式锁只允许单次查询,其它等待,超时返回失败
cache 指的是删除『缓存』
db 指的是『更新/删除数据库』
删除缓存成功,更新数据库失败,不影响数据准确性。
如果在 cache 与 db 短暂的时间内
有访问查询动作(先查缓存,后查 db 并且设置缓存)
那么还缓存中还是会存在过期的数据
如果 db 成功,cache 失败,会导致数据不一致。
可以让 db cache 在一个事务,cache 失败回滚 db,保证一致性。
其实本质上就是个分布式事务问题
怎么保证两个操作同时成功/失败
通过本地事务 / 补偿机制 实现会比较好
解决方案:当查询到某数据不存在时,缓存假数据,例如:(key,key#);
缓存高可用(集群+主备)
循环一致性 Hash,节点组成一个环,如果一个节点挂了,顺着往下走;
hisen@ubuntu:/var/lib$ su |
解决办法
hisen@ubuntu:$ sudo passwd root |
重新设置一下密码即可,我这边装的时候设置的用户是:hisen
刚刚重新设置的密码就是你装系统的时候设置的用户密码。
]]>之前京东组里有同事使用二进制优化支付密码打标性能(大促 QPS 数百万),节省内存资源。
随说:存二进制报文小,传输快,反序列化快(之前存 JSON 对象),节省缓存。
目前公司遇到个套餐打标,也通过二进制实现简单高效得解决掉了。
随说:目前倒不是要求性能,只是这么设计扩展性好,操作简单。
知识点:二进制、与运算
打标,无非就是识别某个东西是不是包含某些属性。
那么有什么好的办法能做到通用与高效?
如果固定映射,扩展性不好,查询逻辑费劲,存储成本偏高。
目前相对较好的方案是通过二进制位来做标记,再结合与运算,快速找出数据。
随说:Java MySQL 均支持与运算
套餐 | VIP1 | VIP2 | VIP3 | 标记值 |
---|---|---|---|---|
A | 1 | 1 | 1 | 7 |
B | 1 | 1 | 0 | 6 |
C | 1 | 0 | 0 | 4 |
如上表所示,相应套餐的购买资格标记。
A 套餐所有会有均可购买
B 套餐 VIP3 不能购买
C 套餐仅 VIP1 可购买
对相关标记进行入库处理:A=7,B=6,C=4;
正常思维,需要存三个字段,没有扩展性,性能还差。
使用二进制,结合与运算,降本(计算、传输、匹配)增效(性能提升)。
public static void main(String[] args) { |
系统流量小的时候
粗糙烂制也不是不能用
但是当系统流量大了就得想办法优化:CPU、传输、存储
很多时候往往利用简单的原理解决大的问题,只是很多时候限于认知不知道可以这么用。
说到底还是要知其然,更要知其所以然。
]]>官网地址:http://try.redis.io/
我的redis是安装在linux虚拟机,通过Xshell操作,显示可能跟cmd不大一样
但是操作都是一样的
#连接redis客户端 |
sudo apt-get update |
安装docker包
sudo apt-get install \ |
添加docker官方GPG秘钥,留意最后那个符号也要复制
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
sudo add-apt-repository \ |
再次更新源
sudo apt-get update |
安装docker-ce
sudo apt-get install docker-ce |
在阿里云申请一个账号,打开连接https://cr.console.aliyun.com/#/accelerator
拷贝您的专属加速器地址(每个人专属的,登陆需要密码),然后
vi /etc/systemd/system/multi-user.target.wants/docker.service |
可以看到如下内容
[Service] |
找到 ExecStart= 这一行,在这行最后添加加速器地址 –registry-mirror=<加速器地址>
如:ExecStart=/usr/bin/dockerd -H fd:// –registry-mirror=https://xxxxxx.mirror.aliyuncs.com
$ sudo systemctl daemon-reload |
至此docker安装及国内加速器都好了,开始你的docker之旅吧。
sudo docker run hello-world |
看到如下信息
hisen@ubuntu:/$ sudo docker run hello-world |
到此就圆满结束
最后给个彩蛋,阿里云一键安装脚本,执行下面命令即可安装最新版docker
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh - |
工作当中会遇到很多部署导致的问题
其中大部分的问题原因是配置问题
关于部署
互备很重要,哪怕对方没有介入开发,简单的按正常流程问你几个问题,也许就会发现漏了什么。
]]>只是简单的让例子在IntelliJ IDEA跑起来
目前是最新的版本:2.5.4-SNAPSHOT
本文档更新时间:2017年04月19日01:08:02
参考链接:ubuntu apt-get安装zookeeper
导出项目之后,配置一下tomcat,添加dubbo-admin:war到tomcat中
项目github地址:https://github.com/hisen-yuan/dubbo
默认账号:root
默认密码:root
/dubbo/dubbo-demo/dubbo-demo-consumer/src/test/resources/dubbo.properties |
#dubbo.registry.address=multicast://224.5.6.7:1234 |
/dubbo/dubbo-demo/dubbo-demo-provider/src/test/resources/dubbo.properties |
#dubbo.registry.address=multicast://224.5.6.7:1234 |
即可在后台看到有服务在运行
]]>在压测过程中发现有部分 redis cluster 节点内存占用比其它节点高(来自监控)
内存倾斜的隐患
redis cluster slot 分配不均匀
redis cluster 集群内存分配算法的缺陷
问题算法:单节点内存 = 集群总内存 / 节点数
合理算法:单节点内存 = (集群总内容 / slot 数量) * 当前节点 slot 数量
key 根据 crc16 计算之后比较均匀,排除 key 分布不均
在 key 均匀的情况下,考虑 slot 分配问题
查找 slot 分布
redis 控制台执行:cluster slots
取最后一个节点的 rely 日志如下(日志含义见参考链接)
(0)(0)10137 |
通过 awk 计算每个节点管理的槽 ( slot ) 数量
# 把上面的日志粘贴到 slots 文件中 |
由于本案例当中,大部分节点都是包含 326 个 slot,问题节点明显偏多 360
awk NR 代表行号
awk getline 获取下一行,并且赋值到 $0 (本意是代表当前行数据)。
sort -k 3 -r,以第三列排序(-k 3),倒序输出(-r)
head -n 3,输出前三行
根据上述假设,经过验证,发现确实是由于 slot 分配不均匀导致
人工手动调整 slot 较多节点的内存,使之达到与其它节点内存占用水平。
提示:redis 可以通过修改参数( maxmemory,单位 byte )调整最大内存。
具体的内容可以看下面的程序代码(虽然是抄书)
package main |
package main |
美国风险投资家 Naval Ravikant 通过一个很长的推特阐明了他的商业观,感觉挺精辟。
积累独到的知识(无法批量复制的),为社会提供他们需要的。
财富不是靠出卖时间获得,应该通过杠杆(资本、人力、一本万利的工具<写书等>)去积累。
选择一个可以长期从事的行业,寻找一批可以长期共事的人。
Seek wealth, not money or status. Wealth is having assets that earn while you sleep. Money is how we transfer time and wealth. Status is your place in the social hierarchy.
去寻求财富,而非金钱或地位。财富就是你拥有资产,而资产在你睡觉的时候都还在为你赚钱;金钱是我们转换时间和财富的工具;身份是你在社会等级体系里所处的位置。
Understand that ethical wealth creation is possible. If you secretly despise wealth, it will elude you.
要明白一件事:一个人完全可以不靠坑蒙拐骗站着赚取财富。如果你在暗中鄙视财富,那么财富也会躲着你。
Ignore people playing status games. They gain status by attacking people playing wealth creation games.
别去理会那些热衷于玩身份游戏的人,他们通过攻击那些创造财富的人以获得自己的身份。
You’re not going to get rich renting out your time. You must own equity — a piece of a business — to gain your financial freedom.
你不会通过出租自己的时间而变得富有。你必须拥有产权,也就是生意的一部分,以此才能赢得个人财务自由。
You will get rich by giving society what it wants but does not yet know how to get. At scale.
提供社会大众想要但是他们还不知道如何获取的东西,你就会因此而致富。但有一点:你必须规模化地供应社会。
Pick an industry where you can play long term games with long term people.
选择一个你可以长期从事的产业,寻找一批可以一起长期共事的人。
The Internet has massively broadened the possible space of careers. Most people haven’t figured this out yet.
互联网极大拓展了一个人职业生涯的可能性。绝大多数人对此毫无认知。
Play iterated games. All the returns in life, whether in wealth, relationships, or knowledge, come from compound interest.
玩就玩复利游戏。无论是财富,人际关系或者是知识,所有你人生里获得的回报,都来自复利。
Pick business partners with high intelligence, energy, and, above all, integrity.
在选择商业合作伙伴的时候,选择那些高智商、精力旺盛的家伙,但在这一切之上,他应该是个正直诚实的人。
Don’t partner with cynics and pessimists. Their beliefs are self-fulfilling.
不要和愤世嫉俗者和悲观主义者合作,因为他们会任由坏事发生,以此证明他们的负面看法是正确的。
Learn to sell. Learn to build. If you can do both, you will be unstoppable.
学会如何销售,学会如何创建。如果你同时能做到这两件事,你的成功将无可阻挡。
Arm yourself with specific knowledge, accountability, and leverage.
用独到知识,责任感和杠杆武装自己。
Specific knowledge is knowledge that you cannot be trained for. If society can train you, it can train someone else, and replace you.
独到知识是那种不可以通过培训而获得的知识。这是因为,如果这种知识可以经由培训而得,那么其他人同样也可以,并且以此取代你。
Specific knowledge is found by pursuing your genuine curiosity and passion rather than whatever is hot right now.
在真正的好奇心和热情驱使你前进的路上,你更有可能获得独到知识,而不是在追逐潮流热点的闻风起舞脚步里。
Building specific knowledge will feel like play to you but will look like work to others.
创建独到知识的过程对于你就像是在玩,而对于别人则像是工作。
When specific knowledge is taught, it’s through apprenticeships, not schools.
不能通过学校教育教会一个人独到知识,它只能通过学徒制口传身教。
Specific knowledge is often highly technical or creative. It cannot be outsourced or automated.
独到知识通常极富技术性和创造性,因此它不能被外包或自动实现。
Embrace accountability, and take business risks under your own name. Society will reward you with responsibility, equity, and leverage.
拥抱责任感,押上自己的声誉以承担商业风险。社会也会以责任,产权和杠杆作为回报。
The most accountable people have singular, public, and risky brands: Oprah, Trump, Kanye, Elon.
最具责任感的人都具有独一无二的、世人皆知的、敢于冒险的个性特征,如奥普拉、川普、坎耶、埃隆。
“Give me a lever long enough, and a place to stand, and I will move the earth.” — Archimedes
只要给我一根足够长的杠杆,一处可以立足的地方,我就能撬起地球。——阿基米德
Fortunes require leverage. Business leverage comes from capital, people, and products with no marginal cost of replication (code and media).
财富增长需要使用杠杆。商业杠杆有三个来源:1、资本;2、人力;3、复制起来边际成本为零的产品(如:代码和媒体)。
Capital means money. To raise money, apply your specific knowledge, with accountability, and show resulting good judgment.
资本的意思就是钱。想要融资,那就运用你的独到知识,配合你责任感,展示出你良好的判断力。
Labor means people working for you. It’s the oldest and most fought-over form of leverage. Labor leverage will impress your parents, but don’t waste your life chasing it.
人力指的就是为你干活的人,它是最古老也是争夺最激烈的杠杆。人力杠杆会让你父母因为你手下有许多人为你工作而感到骄傲,但你不要浪费生命去追求这一点。
Capital and labor are permissioned leverage. Everyone is chasing capital, but someone has to give it to you. Everyone is trying to lead, but someone has to follow you.
资本和劳动力是需要征得许可才能使用的杠杆。每个人都在追逐资本,但总得有个什么人给你才行;每个人都想要领导其它人,但总得有什么人愿意跟着你才行。
Code and media are permissionless leverage. They’re the leverage behind the newly rich. You can create software and media that works for you while you sleep.
代码和媒体是无需要许可即可使用的杠杆。它们是新贵人群背后的杠杆,你可以通过自己创建的软件和媒体,在睡觉时仍然为你干活。
An army of robots is freely available — it’s just packed in data centers for heat and space efficiency. Use it.
一支机器人军团已经集结待命,只是为了节约空间和热效能,它们被打包放进数据中心。去用吧。
If you can’t code, write books and blogs, record videos and podcasts.
如果你不会编程,那你还可以写书和博客,或者做视频或者音频节目。
Leverage is a force multiplier for your judgement.
杠杆能够成倍地放大你的判断力(所产生的效能)。
Judgement requires experience, but can be built faster by learning foundational skills.
判断力需要经验,但它可以通过学习基本技能的方法更快速地建立起来。
There is no skill called “business.” Avoid business magazines and business classes.
并不存在一种叫做“商业”的能力。尽量避开商业杂志和商业课程。
Study microeconomics, game theory, psychology, persuasion, ethics, mathematics, and computers.
去学习微观经济学、博弈论、心理学、说服术、伦理学、数学和计算机科学。
Reading is faster than listening. Doing is faster than watching.
读比听快,做比看快。
You should be too busy to “do coffee,” while still keeping an uncluttered calendar.
你应该忙得没有社交的时间才对,与此同时你应该始终保证日程安排井井有条。
Set and enforce an aspirational personal hourly rate. If fixing a problem will save less than your hourly rate, ignore it. If outsourcing a task will cost less than your hourly rate, outsource it.
你应该为自己设定一个有抱负的个人时薪数,并且坚持执行。如果解决一个问题所能节省下来的成本低于你的个人时薪,那就忽略这个问题好了;如果一项任务的外包成本低于你的个人时薪,就把它外包出去。
Work as hard as you can. Even though who you work with and what you work on are more important than how hard you work.
尽管你跟谁一起工作、做什么工作,要远比你的努力程度更加重要。但还是要倾尽全力去工作。
Become the best in the world at what you do. Keep redefining what you do until this is true.
你所做的事情,要努力做到世界最好。不断重新定义你在做什么,直到真的做到世界最好。
There are no get rich quick schemes. That’s just someone else getting rich off you.
这个世界上并没有快速赚钱致富的方法,如果你想要找寻这种方法,那它只会让别人从你身上赚钱致富。
Apply specific knowledge, with leverage, and eventually you will get what you deserve.
运用你的独到知识,配合上杠杆,最终你会得到你应该得到的东西。
When you’re finally wealthy, you’ll realize that it wasn’t what you were seeking in the first place. But that’s for another day.
终有一天当你变得富有,你会发现那一切并不是你最开始想要的东西。但是那就是另外一回事了。
财富就是你睡着觉,你的资产也在为你继续赚钱。这是一个越来越被广泛接受的定义。Naval Ravikant 是硅谷狂热的数字货币支持者,所以,他的话另有所指。从前后文来看,他所谓的资产并不等于是传统意义上的房产、股票、收藏,而是偏向于他反复提及的:软件和媒体。
出租时间概念,许多人理解为打工,认为打工就是出租自己的时间以换取金钱。其实并非如此,Naval 所指的出租时间概念,指的是一个人的财富增长,是否直接关系到他的时间。一个小卖部的老板,他并不为谁打工,但是他的财富增长需要他长时间守在店里,因此,他依然是出租时间换钱。但一个淘宝点卡店老板则不同,他的点卡销售是全自动的,不需要 24 小时守着,而且也不需要只做这一样生意。这就是Naval所谓互联网拓宽了个人职业生涯的一个例子。
equity 我翻译为产权,不是一个很好的翻法。但是 Naval 前文提到 assets,很明显,作为投资人他非常清楚地知道这两个字眼之间的区别。equity 无论是翻译为股票、权益或者是资产,原文说“You must own equity — a piece of a business — to gain your financial freedom.”,这是和出租时间概念做对应的。出租时间的人,在商业链条里作为生产资料出现,不拥有任何产权,也就无法通过商业行为获利,所以,我这里勉强翻译为产权。
specific knowledge 我翻译为独到知识,没有翻译为特定知识、专业知识或者是特殊知识。原因是在我的理解中,specific knowledge 不是书本知识,也不是学校教授的知识,更不可能在网上免费获取。一方面,它只能提供自己实践来获取;另一方面,它只能通过前人口耳相传。这种知识是做成一件事情的关键,属于知识体系中不共的那一部分。所以,我翻译为独到知识。
“Give me a lever long enough, and a place to stand, and I will move the earth.” — Archimedes 这话不像是阿基米德说的。更像是一次抬杠的结果:
“给我一个支点,我就能撬起地球!” |
accountability 我本想翻译为“靠谱程度”,想想还是算了。
号称是“四十条语录”,但是我就找见了 39 条。
结合上下文看,Leverage 一词始终翻译为“杠杆”其实也不大对头。Naval 一再强调代码、博客、播客、视频节目,我觉得 Leverage 在他那里,有些时候应该相当于是个人影响力的代名词,或者可以简单理解为放大器。
有个朋友抛出一个问题,明显不符合最左匹配原则的 SQL,居然走索引了
兜兜转转,嘀咕了好几天,期间也和几个朋友讨论了一下
都没有结果,最后还是在 MySQL 的官方文档中找到了原因
记录下,也算是一次不错的探索。
CREATE TABLE `people_new` ( |
mysql> select * from people_new; |
可以看到 Using index
但是 possible_keys null 而 key 显示 index_union
mysql> explain select * from people_new where bob = '2008-08-08' and first_name = 'yuan'; |
1.1 的表结构显示,除了 id,其余三个属性都在 联合索引 中
所以通过任何字段查询,返回的字段都被索引覆盖了,构成 覆盖索引 ,
由于扫描全部索引会快于全表扫描,所以这时候 sql 不管是不是最左匹配都会走索引(应该是『全索引扫描』)。
3.1 的表结构中,除了 id ,还有 area 不在联合索引当中,此时破坏了 覆盖索引 ,故不走索引。
If the index is a covering index for the queries and can be used to satisfy all data required from the table, |
CREATE TABLE `people_new` ( |
mysql> select * from people_new; |
mysql> explain select * from people_new where bob = '2008-08-08' and first_name = 'yuan'; |
有时候多和同行交流也能学到很多。
带着问题去看官方文档收获会比较大。
遇到问题,找到原因,解决问题,印象会深刻。
单位 | 英文全称 | 中文全称 | 转换 |
---|---|---|---|
b | bit | 位 | - |
B | Byte | 字节 | 1B=8b |
KB | Kilo Byte | 千字节 | 1KB=1024B |
MB | Mega Byte | 兆字节 | 1MB=1024KB |
GB | Giga Byte | 千兆 | 1GB=1024MB |
TB | Trillion Byte | 万亿字节 | 1TB=1024GB |
PB | Peta Byte | 千万亿字节 | 1PB=1024TB |
EB | Exa Byte | 百亿亿字节 | 1EB=1024PB |
ZB | Zetta Byte | 十万亿亿字节 | 1ZB=1024EB |
YB | Yotta Byte | 一亿亿亿字节 | 1YB=1024ZB |
BB | Bronto Byte | 一千亿亿亿字节 | 1BB=1024YB |
NB | Nona Byte | 1NB=1024BB | |
DB | Dogga Byte | 1DB=1024NB | |
CB | Corydon Byte | 1CB=1024DB |
进制除了 Byte 与 bit 之间是 8,其它的都是 1024,但是目前很多时候习惯用 1000,比如 1T ≈ 1000G;
运营商(ISP)带宽宣传常见的有:50M、100M、500M、1000M…
注意:这是传输速率,而不是下载速度。
它们的单位其实是:bps (全称 bit per second,b/s)
50M 中 M 的含义是:million 即 百万。
翻译过来就是:50Mbps = 50,000,000 b/s;
各种下载软件,比如迅雷会现在下载速度:12M/s
这个 12M 的单位是 byte 也就是字节。
由表常见单位可知,1byte = 8bit
所以由带宽传输速率转换为下载速度一般需要除以 8
即 100M 带宽,理论上最大的下载速度为:100Mbps / 8 = 12.5Mbyte / s(俗称网速 12.5M);
关于字节的占用,最明显的就是文本编辑器,写入文本后保存,在文件管理器中能看到具体占用了多少存储空间。
问:一个英文(或标点)占用多少字节?一个汉字(或标点)占用多少字节?
答:与所使用的编码有关系,具体如下表:
编码 | 英文 | 汉字 |
---|---|---|
ASCII | 1byte | 2byte |
UTF-8 | 1byte | 3byte |
Unicode | 2byte | 2byte |
面试决定因子:70% 能力、20% 缘分、10% 行情。
软件工程师是条不归路,每天进步一点点,早日走上人生巅峰。
仓库的内容更多是抛砖引玉,提供通用与重要的技术,
真正掌握还得贴合自身需要,花时间持续深入地学习。
基础指引:https://github.com/Snailclimb/JavaGuide
进阶之路:https://github.com/doocs/advanced-java
编程书籍:https://github.com/jobbole/awesome-programming-books
算法小抄:https://labuladong.gitbook.io/algo/
大厂试题:https://github.com/0voice/interview_internal_reference
简历打磨:https://github.com/geekcompany/ResumeSample/blob/master/java.md
后续持续更新,多交流,共同成长。
就这个群晖的网卡,困扰了我两天。
因为按照之后没法在系统控制面板里面找到对应的网卡。
就连 GitHub 上驱动的作者都说不支持 RTL-8156B(详见:GitHub-issue) 的外置网卡。
但是我想那么多人都买了这种网卡,并且成功了,于是周末到处搜,最终找到了办法。
可能这是 DS918+ 之类才会遇到的问题
搜索引擎很多
https://github.com/bb-qq/r8152/releases
我这里是 DM7 的系统,下载的最新版本
下载到 PC 上即可,不用下载到 NAS
下载完成,在群晖套件中心,手动安装,选择刚刚下载的驱动文件安装
第一次安装会失败(GitHub 上也有说明),需要执行如下命令
sudo install -m 4755 -o root -D /var/packages/r8152/target/r8152/spk_su /opt/sbin/spk_su |
修改之后,再次安装即可完成。
由于群晖918+等型号对 lan 口限制了最大 2 个,这里需要修改两个配置文件。
都是找到 maxlanport=“2” 修改数字为大于 2 的数字即可。
vi /etc.defaults/synoinfo.conf |
vi /etc/synoinfo.conf |
群晖 DS918+,USB 外置网卡安装好驱动,设置好 maxlan 之后,
系统命令行可以识别网卡,并且可以获取 IPv6 地址,但是没有 IPv4 的地址
root@HiSEN-DS:~# ifconfig |
设置局域网 3 (外置网卡) 为自动获取 IP 后,网络正常,系统控制面积显示正常
root@DS:~# ifconfig |
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。
队列是一种数据结构.它有两个基本操作:在队列尾部加入一个元素,和从队列头部移除一个元素(注意不要弄混队列的头部和尾部)就是说,队列以一种先进先出的方式管理数据,如果你试图向一个 已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具。工作者线程可以定期地把中间结果存到阻塞队列中而其他工作者线程把中间结果取出并在将来修改它们。队列会自动平衡负载。如果第一个线程集运行得比第二个慢,则第二个 线程集在等待结果时就会阻塞。如果第一个线程集运行得快,那么它将等待第二个线程集赶上来。下表显示了jdk1.5中的阻塞队列的操作:
排序方法 | 平均情况 | 最好情况 |
---|---|---|
add | 增加一个元素 | 如果队列已满,则抛出一个IllegalSlabEepeplian异常 |
remove | 移除并返回队列头部的元素 | 如果队列为空,则抛出一个NoSuchElementException异常 |
element | 返回队列头部的元素 | 如果队列为空,则抛出一个NoSuchElementException异常 |
offer | 添加一个元素并返回true | 如果队列已满,则返回false |
poll | 移除并返问队列头部的元素 | 如果队列为空,则返回null |
peek | 返回队列头部的元素 | 如果队列为空,则返回null |
put | 返回队列头部的元素 | 如果队列满,则阻塞 |
take | 返回队列头部的元素 | 如果队列为空,则阻塞 |
介绍:
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。
实现高性能,高可用,可伸缩和最终一致性架构。
是大型分布式系统不可缺少的中间件。
目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。
场景:异步处理、应用解耦、流量削锋、日志处理
以上就是关于为什么要使用队列的大致说明
参考:
]]>我用得是网易邮箱大师,把代码存为本地网页打开全选复制
粘贴到邮箱大师的签名里面即可!亲测有效,还挺好看的
<html> |
#删除原有的规则 |
带来的问题就是:
内网的数据库,在启动之后。时不时会自动断开,导致影响正常工作,时不时得重启程序才能测试
刚开始我觉得这样会很麻烦,后来想想以前写博客也是醉了
先新建一个 _post 的快捷方式
进去,然后到博客根目录
打开Git Bash,然后执行
hexo n "你要写的文章题目" |
然后在 _post 快捷方式打开刚刚新建的markdown文件,用markdownpad打开编辑。。。
编辑完了回到Git Bash。。。。想想就很麻烦
于是乎用IDEA打开博客根目录
sources -> _post -> new -> Edit File Templates |
name:markdown extension:md
内容:
--- |
接下来apply -> *.md -> 下面选择markdown
以后新建markdown文件就会默认带上这个模版
效果
title: 利用IDEA写Hexo博客的一些技巧 |
接下来到了发布的时间,于是我们可以设置一下Terminal(在setting里面),设置为bash(git目录下)
设置完了之后Alt + F12 调出 Terminal 即可进行git操作
到此,大功告成,我要去更新博客了
]]>有时间多学习
多线程基础 & 进阶
系统架构
例子代码:NIO应用之简单的CS模型
可以用来简单的理解一下java nio
深入的理解可以看看下面的链接。
Java NIO 系列教程:点击查看
如何学习Java的NIO?:点击查看
[root]# virt-what |
wget http://people.redhat.com/~rjones/virt-what/files/virt-what-1.12.tar.gz |
apt-get install virt-what |
参考:https://www.cnblogs.com/qiumingcheng/p/5259892.html
####例子
//Hashtable |
####性能对比
使用ExecutorService来并发运行5个线程,每个线程添加/获取500K个元素。
从数据可以看出,ConcurrentHashMap效率最高
代码如下
package com.hisen.collection.map; |
做这件事的目的是为了了解一条数据库记录从创建到使用的一个情况;
查询分布时间计算方式采用Top Percentile方式,就是按一定排序的数据,前面xx%的最大值是多少;
TP999 1ms 代表某接口99.9%的响应都在1ms之内;
最终的目的也就是为了知道数据多久之后可以打入冷宫,使用廉价存储;
冷热数据分级处理有利于在性能和成本上达到一定的平衡;
如把内存缓存时间设置为tp90所处的时间,那么90%的数据都能快速返回,其它少量数据回源处理;
关键字
java格式化输出
java8
stream
parallelStream
分组
排序
DoubleSummaryStatistics数据分析
TP999
日志源数据预览
19-10-24.14:47:12.721 [THREAD-22000-18-T-17] INFO FacadeImpl - response yw:jiaoyi, orderId:123456, time:2019-10-24T14:46:44 |
yw | count | min(ms) | max(ms) | tp50(ms) | tp90(ms) | tp99(ms) | tp999(ms) |
---|---|---|---|---|---|---|---|
hisen | 1000 | 1 | 10000 | 20 | 60 | 90 | 130 |
hisen-1 | 200 | 2 | 16000 | 16 | 50 | 70 | 110 |
ps 输出是格式化的数据,并不是表格,可以通过:
world->粘贴输出文本->插入->表格->文本转换成表格->空格
即可完成文字到表格转换
这种过程可能比较low,但是也需要时间去处理,过程中还得配合linux命令等整合文本;
完整:github-CallerAnalyze.java
摘要如下:
/** |
public void testCreate() { |
effective java # 2 |
Builder模式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,
得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,
来设置每个相关可选的参数,最后调用无参的build来生成不可变的对象。
完整代码+测试:github:完整代码+测试
public class NutritionFacts { |
国庆假期没有什么安排,看了几部电影之后感觉蛮愧疚,又浪费了大把的时间
于是乎在书架上找了本决定看起来压力不那么大的书来看
这本书感觉整体上写的一般,可能定位就是通俗易懂吧
但是对于了解一些细节,还是很有帮助
由于目前待在创业公司,看到很多文字的时候还是很有感触的
如果你想成功,积极乐观地看待任何问题
马云在校教书,兼职创业:海博翻译社 |
医学专业已经建立起一套严密的辅导体系
软件行业建立一种包含学徒期、实习期、和长期指引的机制已是迫在眉睫
有人指导大多数人都可以快速的成长,节省很多走弯路的时间
当然,事在人为,只是说掌握了书中的那些要领,成为专业人员的几率更高,做更好的自己
如果从小学开始就一直有人引路并且自己也愿意跟着走的话,应该会很棒,现在也不晚,抓住时间就好
主要内容:
专业主义
学会说“不”,学会说“是”
编码的正确姿势
TDD
卡塔练习很重要,肌肉反应
验收测试(各方都一致同一的检验方式)
测试策略,自动化测试是趋势
时间管理,番茄工作法,注意力点数
预估的概念以及方法
压力,避免与面对
协作,学会与人交流
团队与项目,有凝聚力的团队战斗力强
软件开发如医生一样培训更佳
合适的工具事半功倍
豆瓣链接:《代码简洁之道:程序员的职业素养》
单元素的枚举类型已经成为实现Singleton的最佳方法 |
理由:
单例模式模式:完整代码+测试
主要代码:
public class EnumSingleton { |
FileInputStream方式获取出来的大小会有差异
NIO与IO的对比详见:NIOCopy.java
/** |
以上
]]>public void process(MainTable mainTable) { |
其中一个最小的公倍数是他们的最小公倍数
同样地,若干个整数公有的倍数中最小的正整数称为它们的最小公倍数
求最小公倍数算法:
最小公倍数=两整数的乘积÷最大公约数
求最大公约数算法:
有两整数a和b:
例如:求27和15的最大公约数过程为
因此,3即为最大公约数
代码实现:
/** |
布隆过滤器的作用是加快判定一个元素是否在集合中出现的方法。
因为其主要是过滤掉了大部分元素间的精确匹配,故称为过滤器。
其应用场景为需要频繁在一个海量的集合中查找某个元素是否存在。
并且通常,这个值不在集合中。
比如Google chrome用此方法检查一个url是否在恶意url库中。
假设有一些字符串,假设有一个字符串a,要在集合B中查找其是否在集合B中。最笨的方法是遍历集合B中的每个元素bi,精确匹配a是否等于bi。若集合B中有N个元素,则最坏情况下需要执行N次精确匹配。
一个改进的方法是将a和B中每个字符串按照特定规则映射为数字,称为hash值。规则可以任意设置。比如取各字符串的首字母和尾字母的编码之乘积,取奇数个字符的编码执行异或,等。将比较字符串问题变成一个比较数字的问题。比较字符串需要从头到尾比较,而数字的比较会快很多。
需要注意的是,当两个字符串相同时,采用相同的映射规则得到的数字一定相同。但当两个字符串不同时,得到的字符串不一定不同。所以,当我们发现两个字符串的hash值相同时,两个字符串不一定相同,所以需要进一步去精确匹配两个字符串是否相同。但采用hash值方法已经能够过滤掉一部分以前需要精确匹配的计算量。仅当hash值相同(假设hash值通过字符串首尾字母计算得来,则当两个字符串首尾字母相同时hash值相同)时才去比较字符串本身。若选择hash值合理,则性能将大幅提高。
布隆过滤器通过将一个字符串使用多个不同的hash值计算方法,映射为多个不同的hash值,当所有这些hash值完全相同时,才认为两个字符串相同。从而进一步降低了放生hash值相同的可能性,从而进一步提高了过滤的性能。
package com.hisen.interview; |
这个系列的文章还不错
版权归原作者所有
感觉文章不错,一边看一边实践。
有时候从头开始学习也会有另一番风味。
兴趣是最好的老师,唯有坚持才是实现梦想的唯一途径。
]]>分割线
//插入代码 |
删除线
引用,只能写在一行
markdown语法 |
在head加上这两行代码,可以做到原样输出
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> |
一个接口的关键指标应该就是响应速度,要想提高响应速度,结果在缓存中最好;
所以通过查询时间与缓存中订单的时间进行对比,得出缓存过期时间的最佳值,以平衡性能与成本;
近期在做日志分析,找到比较理想的一个缓存过期时间,使90%的查询都能被缓存覆盖;
ps:提取日志的关键是要日志规范,方便切割,才好算出调用时间(适用于暴利分析,而不是通过调用链等方式);
常见指标:TP50、TP90、TP99、TP999
正式解释:TP=Top Percentile,Top百分数,是一个统计学里的术语,与平均数、中位数都是一类;
通俗理解:TP99 100ms,99%的查询都能在100ms内返回;
计算方式:拿100次调用的耗时,排序,取第99个的耗时,这就是TP99的值;
具体的代码方式就是,先算出耗时,放入List,然后排序,按指定的下标取值即可;
private void calTime(List<Long> timeDurations) { |
Linux和UNIX都支持ps命令,显示所有运行中进程的相关信息。
ps命令能提供一份当前进程的快照。如果想状态可以自动刷新,可以使用top命令。
输入下面的ps命令,显示所有运行中的进程:
ps aux | less |
这个命令按 q 退出
后面加了“| less”就会分页显示,如果去掉会一次性显示出所有结果
hisen@hisen-server:~$ ps aux | less |
ps -A |
-A:显示所有进程
a:显示终端中包括其它用户的所有进程
x:显示无控制终端的进程
pstree |
输出
hisen@hisen-server:~$ pstree |
后面觉得挺好玩,也试了很多次,找过很多的教程。
搭建了一个zookeeper的集群(docker-compose)
然后当我需要搭建redis集群的时候,发现里面很多的概念还不是很懂
比如:volume network
然后加了docker的群,遇到了在以前idea群里面熟的一个人
花了一天的时间看完他传的一本书,昨天买的几本书晚上也到了。
(docker从入门到实践、java并发编程的艺术、effective java中文版 2)
这本书总体来说还行,就是过时了,还在用link,毕竟三年前的东西
有些例子也报错,主要是ruby相关的不行,提醒需要2.2以上的版本
# 所有容器,不加-a只显示正在运行的;-1 列出最后一次运行的 |
最多有两棵子树的有序树,称为二叉树。二叉树是一种特殊的树。
这里规定二叉树的根结点的层次为1。
n0 = n2 + 1
+
https://github.com/hisenyuan/btree
package com.hisen.interview.tiger20171110.btree; |
package com.hisen.interview.tiger20171110.btree; |
但是之前完全没有把独显用上,在英伟达的设置里选择使用显卡感觉也没有用
后来找到在BIOS里面设置,貌似管用,联想的机子可以看看
其他的机子应该也差不多
连接:http://iknow.lenovo.com/detail/dc_102471.html
6. IdeaPad Z380/Z480/Z580/U310/U410,Lenovo G480A/V370A/V470A/V570A |
我的默认居然是:UMA Only
]]>题意:一个数组有奇数个元素,其中只有一个元素出现一次,其它都出现了2次
方案A:利用hashMap存储出现的次数,然后遍历,复杂度O(3/2N)=O(N);
方案B:利用bitmap,根据数组元素的大小确定位置,做取反(0->1->0);
方案C:利用异或的特性快速找出,最简单,高效;
a^a=0
0^a=a
异或支持:交换率、结合率
因此:
a^b^c^b^c=a^(b^b)^(c^c)=a
public static void main(String[] args) { |
这只是一个场景的妙用,实际当中很难遇到这种情况。
所以不管什么时候还是得多去刷题,没事刷几道,熟然生巧。
最终指向的都是Reimage Repair,网址zh.reimageplus.com
网上一查,貌似因为插件被污染的原因
我关闭chrome所有的插件,一个一个排查,最后找到了一个插件出问题
本来还想去举报,发现这个插件被下架了
问题排查
右上角菜单按钮 ---更多工具 --- 扩展程序 --- 关闭所有插件 |
volatile是Java提供的一种轻量级的同步机制
保证变量的修改其它线程立马可见,解决部分并发问题
无法解决复合操作,例如 i++ i–这种操作
原因:i++操作分三步
volatile底层依靠指令重排序来实现内存可见性的
具体的规则如下
在支付业务当中,每一笔交易都得进行记账。
两种情况:
上面的两种情况各自都是在一个事物当中。
在同一个商户进行并发操作的时候,交易有成功有失败;
因为在各自的事物当中更新两条记录的信息,并且使用了for update(innodb引擎)
ß
在某一瞬间:成功的先锁A账户,失败的先锁了B记录
接下来就两个事物各自持有对方想要的资源,并且不释放已经占有的资源,就造成了死锁
在程序里面,更新两个账户的钱的时候,始终先更新ID更小的那条记录,那样不管多少个事务同时进来
都会按照固定的顺序去持有资源,比如先A再B,这样就不会出现各自持有对方想要的资源
ID ACCOUNT |
每个事务都是先锁定A再锁定B,拿不到锁就一直等待
]]>Window -> preferences -> general -> Contents Types -> Text(展开)
-> Java Aroperties File(点击) -> *.properties(locked)(点击)
-> 把iso-8859-1改为 UTF-8 -> Update -> OK
然后就可以正常显示中文了
]]>脏读:在一个查询事务过程中,读到了其它事务没有提交的数据;
不可重复读:一个事务查询过程中,多次查询得到了不一致的结果,原因是:有别的更新事务提交了;
幻读:一个事务查询过程中,多次查询得到了不一致的结果,原因是:有别的删除事务/插入事务提交了;
name | 名称 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
---|---|---|---|---|---|
Read uncommitted | 读未提交 | Yes | Yes | Yes | No |
Read committed | 读已提交 | No | Yes | Yes | No |
Repeatable read | 可重复读 | No | No | Yes | No |
Serializable | 序列化 | No | No | No | Yes |
默认的隔离级别为:RR,原因:5.1之后版本,如果Binlogog开启语句级别,必须为RR,RC可能会导致Binlog数据错误(详情);
读未提交:每次都是读数据最新的版本(包括事务未提交的数据);
读已提交:MVCC控制;
可重复读:MVCC控制;
序列化:在读取的每一行上加锁,只能按顺序进行读写;
InnoDB引擎下的MVCC,是通过在每一行上增加两个隐藏列实现的;
每发生一个新的事务,系统版本都会递增;
当UPDATE数据的时候,都是先copy出来一行操作,不影响原表数据,提交之后才影响;
一个保存创建时间(非时间值,而是系统版本号);
一个保存删除时间(非时间值,而是系统版本号);
当前查询事务系统ID:5
结果条件:
1可以保证读取到的行,在事务开始之前就已经存在,要么是事务自身插入或者修改的;
2可以保证读取到的行,在事务开始之前未被删除;
为新插入的每一行保存当前系统版本号作为CREATE VERSION;
为删除的每一行保存当前系统版本号作为DELETE VERSION;
插入一行新的记录,保存当前系统版本号作为CREATE VERSION;
同事保存当前系统版本号到原来的行上作为DELETE VERSION;
今天中午一个朋友问我一个问题没来得及回,现在折腾一下;
问题:有一个包含以N个空格分割的字符串,求最大子串的长度,要求时间空间复杂度最优;
封装的代码比较复杂,目前来看不在么好分析时间复杂度和空间复杂度;
于是就直观得对比了一下时间;
// output |
有时间再深入了解下StringTokenizer的源码
String oriStr = "aa aa aaaa aaa a a a aa aa a"; |
/** |
同步与异步主要是针对CPU来说的
阻塞与非阻塞主要是针对I/O来说的
本质上还是同步阻塞I/O
不过是在服务器把socket链接封装成Task提交给线程池处理
因为有队列,所以可以突破C:S=1:1的比例
通过把多个I/O的阻塞复用到一个阻塞上,从而使得系统在单线程情况下可以处理多个客户端的请求。
类似于linux的epoll、select
Selector,核心是通过Selector来轮询注册在其上的Channel
当发现有Channel就绪就返回Channel的选择键集合,进行I/O操作;
对比项 | 同步阻塞I/O(BIO) | 伪异步IO | 非阻塞I/O(NIO) | 异步I/O(AIO) |
---|---|---|---|---|
客户端个数:I/O线程数 | 1:1 | M:N(M>=N) | M:1 | M:O |
I/O类型(是否同步) | 同步 | 同步 | 同步(I/O多路复用) | 异步 |
I/O类型(是否阻塞) | 阻塞 | 阻塞 | 阻塞 | 非阻塞 |
API使用难度 | 简单 | 简单 | 非常复杂 | 复杂 |
调试难度 | 简单 | 简单 | 复杂 | 复杂 |
可靠性 | 非常差 | 差 | 高 | 高 |
吞吐量 | 低 | 中 | 高 | 高 |
String str = new String("java"); |
答案:最少一个,最多两个
这是在线支付的最普遍形式。
大致支付过程:第三方支付公司作为代理(网关),接入一堆银行。用户在网关页面(可以在商户端,也可以第三方支付平台端)选择银行,页面跳转到第三方支付平台,然后重定向到对应的银行,用户在银行电子银行官网,采用网银(个人网银或企业网银)完成支付。
网关支付分为:B2C、B2B两类。
涉及的概念:网银支付、银行卡支付。
我们一般说的网关支付是指在PC上的在线支付,由于国内银行基本上都要求安装对应的安全控件,且需要银行的网银客户端,这也是大家经常抱怨网银不支持MAC/Linux等操作系统、不支持除IE外的浏览器等兼容性问题。
在手机端也有类似网关支付的形态,但由于操作过程较为麻烦,体验不好,一般都采用快捷支付等支付形式。
快捷支付一般是指首次需要验证卡要素,生成协议号或者TOKEN,后面支付直接凭协议号扣款。走的交易形式是消费。快捷支付相比于我们原先说的无磁无密支付[MOTO]在限额上有劣势,体验上有优势。
一个相当于长期关系,MOTO相当于一次性关系,每次来都要输入卡要素。
代收代付业务是我社利用自身的结算便利,接受客户的委托代为办理指定款项的收付事宜的业务。
由中介公司或第三方代为收取和支付费用。
顾名思义,代收代付是指先付出去,然后再收回来,金额必须相等。
比如代办运输业务,如果是收取一定比率的手续费,就改变了性质。
代收代付业务分录:
代付时,借:其他应收款 贷:银行存款
收回时,借:银行存款 贷:其他应收款
待完善
微信扫码业务流程说明:
日后需要用到这方面的东西,先整理一番
系统的学习或者理解之后再来说说深层次的东西。
]]>这是一本人类大脑可塑性研究先驱与翘楚的故事书,正是让我们用触觉看到世界的巴赫-利塔这类先驱,使得我们正在成为来自地球的神。
这本书对我来讲还是很棒的,刷新了我对大脑的认知;
以前还停留在左右脑分工上,殊不知这是日本鬼子整出来的不严谨的概念;
看完书,感觉对个人技术、学习方面都有帮助,增加信心,因为之前错过了学校的大把学习时间;
运动和学习是互补的,前者产生新的神经干细胞,后者使它们的寿命延长;
这本书我是很推荐看的;
犹如最近看完的reids英文版文档;
每天看一点点,持续的刺激大脑相关区域,收获还是可以;
之前也咨询过英语比较好的同事;
反馈说目前想提高,就拿着领域内的文档硬看,坚持下来会有收获的;
每次看完书都会发个微博,避开朋友圈的尴尬,扩大散播范围,与更多的同好交流;
《重塑大脑,重塑人生》0822~0901
在持续不断噪声环境中长大的孩子都好动和吵闹,白噪声对大脑发育也有影响。
大脑重塑性和多巴胺有关,多巴胺可以使达成目标的那个行为的神经回路固话,连接得更紧。
有人说A片提供的是健康的快乐,使人从性的紧张中解放,其实A片提供的是上瘾、耐药性,他会降低快乐的感受。
所以学习没有一蹴而就之事,它是要下苦功的,我们的每一个经验都在改变大脑的连联结。
一定要指出一点:台湾地区一直受日本的影响,社会上流行着日本人说的右脑革命、右脑开发的谬论。婴儿发展初期,大脑两边很相似,只是后期专职分化了。因此绝对没有日本人七田真说的“右脑先发展到三岁才长出脑梁到左脑”
上学太早对身心情绪发展不好。
大脑每做一次不同的活动时,这些活动都改变了大脑的结构,每次练习都改变了大脑神经回路,使他更适合手边的作业,假如某些部件坏掉了,其他部件有时可以接管这项工作。(有时候头皮有反应、头胀、有点不舒服的感觉就是这个原因?)
大脑比我们能想象的还更开放。
大脑练习:找出弱点区域然后强化这个区域的功能。
一个认知能力的测试可以帮人们更加了解自己的大脑。
他们发现小猫的大脑有关键期:从3~8周,在这期间接受刺激才会正常地发展。
人的大脑也有关键期,例如语言发展有关键期,始于出生,终止于8岁到青春期之间。
当大脑在分配处理的资源时,大脑地图遵循的法则是竞争。资源不足时,大家会抢珍贵的资源,用进废退是唯一的法则。
当我们年龄越大,我们使用母语的频率就越高,母语占据我们语言地图的空间就越大,这也是因为我们的大脑有可塑性,我们学新语言才这么难。
使用双语的孩子两种语言的语音都共享一个大的语言地图。
但事实上,当我们学会一个坏习惯时,它占据了大脑地铁的空间,每次我们重复这个坏习惯,它又占据多点,让好习惯难以立足,这是为什么戒掉一个坏习惯比学它时难10倍,也是为什么同年的教育这么重要:最好一开始就教对,不要等到坏习惯已经做大有竞争优势了再去拔除它。
训练让神经元效率更高。
当动物有动机要学习时,大脑会弹性地对学习的需求作出反应。
一心多用不会使你的大脑地图产生永久改变。
多巴胺增强回馈报酬
乙酰胆碱帮助大脑加深印象,增强记忆。
都是噪声惹的祸:越靠近机场、公路的孩子智商越低。(持续的背景噪声对听觉皮质有很大的刺激)
把20~20000Hz的声音集合起来就是所谓的白噪声,昼夜播放白噪声会使人失去理智,进而发疯。
打开成年人的关键期:关键是要有激励,多巴胺、乙酰胆碱。
有些人只有在看色情影片时才会勃起,他们很少会想不举根他们爱看色情影片有关系。
恋人可以通过以下方式突破耐受性:浪漫的度个假,尝试新奇的活动,穿新的活动,想办法让对方惊喜。
我们的大脑就是演化来对新奇的东西起反应了。
当一个人成为父亲时,会分泌血管压缩素,会改变我们的大脑使你变得适合做父亲。
催产素通常是在草原田鼠交配时分泌(人性交也会),这使它们白头偕老,不会花心。
没有安全感的男人在做完爱后,会迅速离开,因为他害怕留下来,会被她影响;女人比较容易爱上与她性交的男人。
爱情的“去学习”也使我们改变了对自己形象的看法。在爱上一个很有权利欲、喜欢操控和贬低别人以抬高自我的人后,会失去所有的自我,变成自我怀疑、对自己没有信心的人。
《洛丽塔》
把猴子一只手神经切断,另外一只手绑起来,结果后面猴子用切断了神经的手进食。
“大量练习”(两周内集中训练)是为了引发启动大脑的可塑性改变,帮助大脑重新组织。
利用大脑可塑性停止忧虑、偏执想法、强迫性行为和坏习惯。
强迫症是:
你越做,就越想做;
越不做就越不会去想做。
幻肢是来自大脑的重组,脸和手的神经比较靠近。
有些女性的耳朵、锁骨和胸骨受到刺激会感到性兴奋,这三者的大脑地图都跟乳头的大脑地图紧邻;有些因阴茎癌而把阴茎切除的男性不但体验到幻阴茎,而且阴茎还会勃起。(性器官的大脑地图是在脚的旁边)
成功切除幻肢,通过镜子让患者看到幻肢,然后就会有信号传回大脑。
控制阀门理论,用电流刺激抑制痛的神经元,帮助疼痛阀门关闭。这个理论让西方科学家比较能接受针灸。
仅仅用想象和视觉错觉来重建构造大脑地图,没有打针、吃药、电流刺激,就将其痛苦、难以忍受的长期痛苦减轻或治愈了
经颅磁刺激可以无痛刺激脑神经。
实验表明,心智练习(靠想象)是用最少的实际练习来学习新肢体技术的有效方式。
用进废退的大脑需要外界刺激来维持它的地图。(心智下棋的例子最多)
专家不存储答案,但是存储重要的事实和策略,用长期记忆来解决问题是很多领域专家的共同特点。
从神经科学的观点来看,想象一个动作和执行其实没有很大差别。
一个人想象他在使用自己的肌肉可以增加肌肉的强度。
要发展一个新的回路,就必须阻挡或管制它的竞争者,即那些通常最常使用这个回路的信息。例如;想提高触觉等能力,就蒙住眼睛。
通常我们会重组我们的记忆以符合新的环境。
孩子要了解情绪,调节情绪,而产生社会化联结,必须在关键期经历几百次互动(母亲通过触觉 听觉 视觉 表现情绪)
两三岁以前靠内隐记忆,非语言的,例如骑自行车。
两三岁以后外显记忆开始发展,收集各种事实,事件,需要语言支持。
有几十个研究显示睡眠帮助我们巩固学习和记忆,而这影响大脑的可塑性改变。
婴儿时期的快速眼动睡眠是大脑可塑性发展的必要条件。
我们常常不自觉得被过去重要人际关系的魅影缠绕而影响现在的人际关系。
计算机听觉训练程序可以帮助老年人训练大脑。
不要因为小事而钻牛角尖,因为压力会产生皮质激素,而这会杀死海马回的神经细胞,海马回有助于短期记忆转为长期记忆
海马回中有神经干细胞。
在刺激丰富的环境中(球类、跑步机等各种玩具)生长的老鼠海马回容积增大15%,神经元数目增加了15%。长期丰富刺激环境对老年人的大脑神经再生有巨大影响。
为了使大脑保持最佳状态,我们必须学习新东西,而不是每天重复已经做的很熟练的事情,终身学习是很有必要的。
运动和学习是互补的,前者产生新的神经干细胞,后者使它们的寿命延长。
学一种新乐器、玩桥牌、打麻将、阅读和跳舞都可以帮助神经元的活化(需要全神贯注的活动才行)。
大脑最怕的就是人呆在相同的环境不动,这样会使大脑萎缩加速,单调不动会减少多巴胺的分泌,破坏维持大脑可塑性的注意力系统。
只有做自己想做的事情才会产生强烈的动机。
半个大脑也可以活的很好。
洗脑遵循了神经可塑性原则,可以用奖励、严厉惩罚以及大量训练的方式达到制约目的。
刚会走路的婴儿每天看电视的时间每增加一小时,他们在7岁时有注意力缺失问题的概率就会增加10%
]]>主要是交流比较多,不是先笔试
直接是把这些问题带入到具体的情景当中去
可能这样更能考验出一个人真正的技术水平
1,很多文件,读出数字,加1写回,谈谈你的想法
2,能继承string类?
不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。 |
3,能有个包名一样的String类?如果有一样的会调用哪个?
4,一个主线程等待其他线程完成,如果其中有线程出错怎么办?
把线程可能会出现的问题处理掉 |
5,Oracle默认端口?
1521
+
6,b继承a,b的对象能强转成a嘛?
不能把一个对象强制转换成另外一个对象
+
7,数据库去重,删除所有重复记录,只留下一条
DELETE |
8,try c里面,没打印出错误来,是为什么?
1.可能是程序执行是正确的 |
9,JAVA数据类型
简单类型 | 二进制位数 | 封装器类 |
---|---|---|
boolean | 1 | Boolean |
byte | 8 | Byte |
char | 16 | Character |
short | 16 | Short |
Int | 32 | Integer |
long | 64 | Long |
float | 32 | Float |
double | 64 | Double |
void | – | Void |
10,银行金额字段
金融数字是BigDecimal类型
+
11,用什么解析XML,有什么优缺点
DOM4J(Document Object Model for Java) |
12,阿贾克斯熟悉吗?能发起请求下载文档吗?返回类型有哪些,遇到错误怎么提示用户
不能发起文档下载,返回的类型只有字符型, |
13,jquery选择器
jQuery 元素选择器 |
14,空指针异常,怎么定位错误
定位到出现错误的行数 |
官方发布了这个问题的解决办法
详见:点击前往 页面中搜索:This view has crashed
windows 10系统 需要下载 一个 awesomium_v1.6.6_sdk_win
这是一个 HTML UI ENGINE
下载地址:http://markdownpad.com/download/awesomium_v1.6.6_sdk_win.exe
]]>看了几个小时,感觉还是不错
都按规范来写,可以避免很多错误
背景:一年工作经验,做电子政务
判断字符串是否含有此Url:www.jd.com
11.
Long l1 = new Long(1024L); |
Spring自定义注解、拦截器相关
一个数组 i[] = [-1000 ~ 1000] 中的任意一些数字,求乘积最大的三个数。
/** |
1M 等于多少个1
|
写出两种单例模式
//懒汉模式 |
判断字符串是否含有此Url:www.jd.com
|
http://www.jd.com/...username=... 为了防止sql注入,怎么写正则。
将包含有 单引号('),分号(;) 和 注释符号(--)的语句给替换掉来防止SQL注入 |
mybatis如何防止sql注入
防护一:sql语句不在使用${}表达式,改为#{} |
mybatis使用变量时怎么表示
#与$的区别 |
使用js遍历json数据
var data=[{name:"a",age:12},{name:"b",age:11},{name:"c",age:13},{name:"d",age:14}]; |
感觉从业这么久以来,读取文件路径相关问题一直是一个痛
用的很少,之前也解决过相关的问题
但是得用这种路径
src/test/resources/test/test.txt |
上面这种路径如果在代码中的话,src/test/resources是不会存在的,会出现问题
本次学到了一个新的方法,Class.getResourceAsStream();
需要的路径在资源文件夹下面即可,填写路径:/test/test.txt
打包最终的路径会在:WEB-INF/classes/test/test.txt
ps:因maven打包配置不同,最终resources资源文件夹下的路径是不同的,注意src的坑即可
│ └── test |
.class) (value = SpringJUnit4ClassRunner |
从中不难看出源头是黑卡、被利用的宽带账号、也有可能是路由器、物联网设备等;
运营商加强实名认证
宽带拨号频率限制
网络设备安全加固,关闭特殊权限端口,禁用弱密码
打击网络黑产交易,防止黑产规模化,产业化趋势;
蜜罐系统收集黑产IP
提供IP代理给黑产使用了解对方信息