├── .gitignore ├── face.png ├── img ├── qr.png ├── 2048.png ├── car.jpg ├── emps.jpg ├── head.png ├── lib.png ├── ursb.jpg ├── asknow.png ├── canvas.jpg ├── face.jpeg ├── feedme.jpg ├── miemie.jpg ├── patent.png ├── wechat.jpg ├── IMG_6104.jpeg ├── airinggo.jpg ├── bilibili.jpg ├── feedme-aw.jpg ├── head-face.png ├── sunnybaby.png ├── bilibili2000.png └── timeline-2024.png ├── favicon.ico ├── pdf ├── 2023.pdf └── 2024.pdf ├── font ├── fontello.eot ├── fontello.ttf ├── fontello.woff └── fontello.svg ├── README.md ├── package.json ├── dist └── css │ ├── fontello.min.css │ ├── print.min.css │ └── style.min.css ├── gulpfile.js ├── src └── css │ ├── fontello.scss │ ├── print.scss │ └── style.scss ├── print.html ├── index.html ├── 2024.html └── 2023.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/face.png -------------------------------------------------------------------------------- /img/qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/qr.png -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/favicon.ico -------------------------------------------------------------------------------- /img/2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/2048.png -------------------------------------------------------------------------------- /img/car.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/car.jpg -------------------------------------------------------------------------------- /img/emps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/emps.jpg -------------------------------------------------------------------------------- /img/head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/head.png -------------------------------------------------------------------------------- /img/lib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/lib.png -------------------------------------------------------------------------------- /img/ursb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/ursb.jpg -------------------------------------------------------------------------------- /pdf/2023.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/pdf/2023.pdf -------------------------------------------------------------------------------- /pdf/2024.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/pdf/2024.pdf -------------------------------------------------------------------------------- /img/asknow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/asknow.png -------------------------------------------------------------------------------- /img/canvas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/canvas.jpg -------------------------------------------------------------------------------- /img/face.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/face.jpeg -------------------------------------------------------------------------------- /img/feedme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/feedme.jpg -------------------------------------------------------------------------------- /img/miemie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/miemie.jpg -------------------------------------------------------------------------------- /img/patent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/patent.png -------------------------------------------------------------------------------- /img/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/wechat.jpg -------------------------------------------------------------------------------- /font/fontello.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/font/fontello.eot -------------------------------------------------------------------------------- /font/fontello.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/font/fontello.ttf -------------------------------------------------------------------------------- /img/IMG_6104.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/IMG_6104.jpeg -------------------------------------------------------------------------------- /img/airinggo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/airinggo.jpg -------------------------------------------------------------------------------- /img/bilibili.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/bilibili.jpg -------------------------------------------------------------------------------- /img/feedme-aw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/feedme-aw.jpg -------------------------------------------------------------------------------- /img/head-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/head-face.png -------------------------------------------------------------------------------- /img/sunnybaby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/sunnybaby.png -------------------------------------------------------------------------------- /font/fontello.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/font/fontello.woff -------------------------------------------------------------------------------- /img/bilibili2000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/bilibili2000.png -------------------------------------------------------------------------------- /img/timeline-2024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airingursb/resume/HEAD/img/timeline-2024.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My Resume 2 | 3 | [html.love](http://html.love) 4 | 5 | ## Introduction 6 | 7 | 风格参考 @Ovilia @joyeecheung @lishengzxc 8 | 9 | ## Usage 10 | 11 | 1. Star 本项目 12 | 1. Clone 到本地 13 | 1. 在 `index.html` 和 `print.html` 文件中填写你的信息 14 | 1. 生成PDF(以 OS X 操作系统 Chrome 浏览器为例):打开`文件->打印`,设置布局为纵向,纸张尺寸为A3,边距无,背景图片选项打钩,保存;压缩PDF,推荐在线压缩工具[smallpdf](http://smallpdf.com/cn/compress-pdf);将压缩过的PDF文件放在根目录内 15 | 1. 部署上线 16 | 1. Enjoy it! 17 | 18 | ## Development 19 | 20 | ``` 21 | $ npm install 22 | $ npm install -g gulp 23 | $ gulp 24 | ``` 25 | 26 | ## LICENSE 27 | 28 | MIT © [DIYgod](http://github.com/DIYgod) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aresume", 3 | "version": "1.0.0", 4 | "description": "Wow, such a beautiful resume", 5 | "main": "index.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/DIYgod/Resume.git" 12 | }, 13 | "keywords": [ 14 | "resume" 15 | ], 16 | "author": "DIYgod", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/DIYgod/Resume/issues" 20 | }, 21 | "homepage": "https://github.com/DIYgod/Resume#readme", 22 | "devDependencies": { 23 | "browser-sync": "^2.10.0", 24 | "gulp": "^3.9.0", 25 | "gulp-autoprefixer": "^3.1.0", 26 | "gulp-minify-css": "^1.2.1", 27 | "gulp-rename": "^1.2.2", 28 | "gulp-sass": "^2.1.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dist/css/fontello.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";@font-face{font-family:fontello;src:url(../../font/fontello.eot?32003456);src:url(../../font/fontello.eot?32003456#iefix) format("embedded-opentype"),url(../../font/fontello.woff?32003456) format("woff"),url(../../font/fontello.ttf?32003456) format("truetype"),url(../../font/fontello.svg?32003456#fontello) format("svg");font-weight:400;font-style:normal}[class*=" icon-"]:before,[class^=icon-]:before{font-family:fontello;font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-wechat:before{content:'\e800'}.icon-qq:before{content:'\e801'}.icon-bookmark:before{content:'\e802'}.icon-heart:before{content:'\e803'}.icon-mail-alt:before{content:'\e804'}.icon-link:before{content:'\e805'}.icon-phone-1:before{content:'\e806'} -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var sass = require('gulp-sass'); 3 | var prefix = require('gulp-autoprefixer'); 4 | var minifyCSS = require('gulp-minify-css'); 5 | var rename = require('gulp-rename'); 6 | var browserSync = require('browser-sync').create(); 7 | 8 | // Static server 9 | gulp.task('browser-sync', function() { 10 | browserSync.init({ 11 | server: { 12 | baseDir: './' 13 | } 14 | }); 15 | }); 16 | 17 | // Build css files 18 | gulp.task('compressCSS', function() { 19 | gulp.src('src/css/*.scss') 20 | .pipe(sass()) 21 | .pipe(prefix(['last 15 versions', '> 1%', 'ie 8', 'ie 7'], { cascade: true })) 22 | .pipe(minifyCSS()) 23 | .pipe(rename({ 24 | suffix: '.min' 25 | })) 26 | .pipe(gulp.dest('dist/css')) 27 | .pipe(browserSync.stream()); 28 | }); 29 | 30 | // Watch files for changes & recompile 31 | gulp.task('watch', function () { 32 | gulp.watch(['src/css/*.scss'], ['compressCSS']); 33 | }); 34 | 35 | // Default task, running just `gulp` will move font, compress js and scss, start server, watch files. 36 | gulp.task('default', ['compressCSS', 'browser-sync', 'watch']); -------------------------------------------------------------------------------- /src/css/fontello.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'fontello'; 3 | src: url('../../font/fontello.eot?32003456'); 4 | src: url('../../font/fontello.eot?32003456#iefix') format('embedded-opentype'), 5 | url('../../font/fontello.woff?32003456') format('woff'), 6 | url('../../font/fontello.ttf?32003456') format('truetype'), 7 | url('../../font/fontello.svg?32003456#fontello') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ 12 | /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ 13 | /* 14 | @media screen and (-webkit-min-device-pixel-ratio:0) { 15 | @font-face { 16 | font-family: 'fontello'; 17 | src: url('../font/fontello.svg?32003456#fontello') format('svg'); 18 | } 19 | } 20 | */ 21 | 22 | [class^="icon-"]:before, [class*=" icon-"]:before { 23 | font-family: "fontello"; 24 | font-style: normal; 25 | font-weight: normal; 26 | speak: none; 27 | 28 | display: inline-block; 29 | text-decoration: inherit; 30 | width: 1em; 31 | margin-right: .2em; 32 | text-align: center; 33 | /* opacity: .8; */ 34 | 35 | /* For safety - reset parent styles, that can break glyph codes*/ 36 | font-variant: normal; 37 | text-transform: none; 38 | 39 | /* fix buttons height, for twitter bootstrap */ 40 | line-height: 1em; 41 | 42 | /* Animation center compensation - margins should be symmetric */ 43 | /* remove if not needed */ 44 | margin-left: .2em; 45 | 46 | /* you can be more comfortable with increased icons size */ 47 | /* font-size: 120%; */ 48 | 49 | /* Font smoothing. That was taken from TWBS */ 50 | -webkit-font-smoothing: antialiased; 51 | -moz-osx-font-smoothing: grayscale; 52 | 53 | /* Uncomment for 3D effect */ 54 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ 55 | } 56 | 57 | .icon-wechat:before { content: '\e800'; } /* '' */ 58 | .icon-qq:before { content: '\e801'; } /* '' */ 59 | .icon-bookmark:before { content: '\e802'; } /* '' */ 60 | .icon-heart:before { content: '\e803'; } /* '' */ 61 | .icon-mail-alt:before { content: '\e804'; } /* '' */ 62 | .icon-link:before { content: '\e805'; } /* '' */ 63 | .icon-phone-1:before { content: '\e806'; } /* '' */ -------------------------------------------------------------------------------- /dist/css/print.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";.sidebar,.sidebar a,aside a{color:#fff}.qr,.title{text-align:center}*{margin:0;padding:0}body{background:#e0e0e0;font-family:'Helvetica Neue',Helvetica,'Lucida Grande',Arial,'Hiragino Sans GB',微软雅黑,'WenQuanYi Micro Hei',STHeiti,SimSun,sans-serif}.sidebar,aside li{background:#00bfa5}li,ul{list-style:none}a{text-decoration:none}aside{position:fixed;right:0;top:30%}aside li{margin-bottom:10px;padding:10px;-webkit-border-radius:10px 0 0 10px;border-radius:10px 0 0 10px}.container{width:1260px;height:1782px;position:relative}.sidebar{position:absolute;top:0;bottom:0;width:450px;padding:25px;line-height:1.5;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.skill,.skill-name{position:relative}.title{margin:25px 0 20px}.title img{display:block;margin:0 auto 15px;width:150px}h1{font-size:36px;font-weight:400}h2{font-size:16px}.side-info li{padding-top:20px}.side-info dt{font-size:20px;color:#9f3;line-height:40px}.side-info dd{font-size:16px;line-height:20px}.someRight dd{margin-left:25px}.skill-name{width:100px;font-size:14px;display:inline-block;left:25px;top:-3px}.note,.qr{font-size:20px;color:#004d40}.skill-bar-wrap{height:17px;width:150px;background:#00796b;display:inline-block;-webkit-border-radius:20px;border-radius:20px}.skill-bar{height:17px;background:#fff;-webkit-border-radius:20px 0 0 20px;border-radius:20px 0 0 20px}.note{text-indent:2em;margin-top:100px}.qr{position:absolute;bottom:40px;width:400px}.main,h4{position:relative}.qr-in{margin:0 auto}.qr-in img{width:200px}.qr-in a{color:#004d40}.main{left:450px;width:810px;height:1782px;padding:15px 20px 0;background:#f0f2f1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.main a{color:#4db6ac}.main-info>li{padding-top:10px}.main-info dt{font-size:26px;color:#00796b;line-height:30px;border-bottom:1px solid #00796b;margin:0 0 15px -5px}.main-info dd{font-size:17px;line-height:27px;color:#616161}h4,h5{color:#000}.main-info span{color:#000;font-size:18px}h3,h4{font-size:20px}h3{color:#004d40;margin:0 0 15px 5px}h4{line-height:30px;bottom:3px}h4 a,h5 a{font-size:14px}h5{clear:both;font-size:18px;line-height:25px}.circle{height:14px;width:14px;-webkit-border-radius:100%;border-radius:100%;background:#00796b;float:left;position:absolute;left:-28px;top:5px}.exp{border-left:2px solid #00796b;margin-left:15px}.exp p{font-size:15px;color:#616161;line-height:21px}.exp>li{position:relative;top:-5px;margin:0 0 8px 20px}.exp img{width:150px}.exp ul>li{margin:0 0 12px}.efe .task4img img{height:73px;width:inherit} -------------------------------------------------------------------------------- /dist/css/style.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";.sidebar,.sidebar a,aside a{color:#fff}.title,footer p{text-align:center}*{margin:0;padding:0}body{background:#e0e0e0;font-family:'Helvetica Neue',Helvetica,'Lucida Grande',Arial,'Hiragino Sans GB',微软雅黑,'WenQuanYi Micro Hei',STHeiti,SimSun,sans-serif;min-width:1080px}.sidebar,aside li{background:#00bfa5}li,ul{list-style:none}a{text-decoration:none}dd,dt,h1,h2,h3,h4,h5,p{cursor:default}aside{position:fixed;right:0;top:30%;z-index:2}aside li{margin-bottom:10px;-webkit-border-radius:10px 0 0 10px;border-radius:10px 0 0 10px;-webkit-box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}aside a{display:inline-block;width:80px;height:38px;line-height:38px;padding-left:10px}.container{position:relative;margin:10px auto;-webkit-box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);width:1060px;overflow:hidden;-webkit-border-radius:4px;border-radius:4px}.sidebar{position:absolute;top:0;bottom:0;width:300px;padding:15px 15px 10000px;line-height:1.5;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin-bottom:-10000px}.main,.skill,.skill-name,h4{position:relative}.title{margin:25px 0 20px}.title img{display:block;margin:0 auto 15px;width:120px}h1{font-size:28px;font-weight:400}h2{font-size:14px}.side-info li{padding-top:20px}.side-info dt{font-size:18px;color:#9f3;line-height:40px}.side-info dd{font-size:14px;line-height:20px}.someRight dd{margin-left:25px}.skill-name{width:100px;font-size:14px;display:inline-block;left:25px;top:-3px}.skill-bar-wrap{height:17px;width:150px;background:#00796b;display:inline-block;-webkit-border-radius:20px;border-radius:20px}.skill-bar{height:17px;background:#fff;-webkit-border-radius:20px 0 0 20px;border-radius:20px 0 0 20px}.note{text-indent:2em;margin-top:90px;color:#004d40;font-size:18px}.main{left:300px;width:720px;padding:15px 20px 10000px;background:#f0f2f1;margin-bottom:-10000px}.main a{color:#4db6ac}.main-info>li{padding-top:20px}.main-info dt{font-size:24px;color:#00796b;line-height:30px;border-bottom:1px solid #00796b;margin:0 0 15px -5px}.main-info dd{font-size:15px;line-height:27px;color:#616161}h4,h5{color:#000}.main-info span{color:#000;font-size:16px}.exp p,footer a,footer p{color:#616161}h3{font-size:19px;color:#004d40;margin:0 0 15px 5px}h4{line-height:30px;font-size:18px;bottom:3px}h5{clear:both;font-size:16px;line-height:25px}.fa{margin-right:2px}h4 a,h5 a{font-size:12px;border:1px solid #4db6ac;padding:1px 3px;-webkit-border-radius:5px;border-radius:5px;margin-left:7px}.circle{height:14px;width:14px;-webkit-border-radius:100%;border-radius:100%;background:#00796b;float:left;position:absolute;left:-28px;top:5px}.exp{border-left:2px solid #00796b;margin-left:15px}.exp p{font-size:15px;line-height:22px;margin-bottom:3px}.exp>li{position:relative;top:-5px;margin:0 0 20px 20px}.exp img{width:200px}.exp ul>li{margin:0 0 12px}.efe .task4img img{height:97px;width:inherit}footer{margin:30px 0 20px}footer p{font-size:14px}.throb{-webkit-animation:throb 1.33s ease-in-out infinite;animation:throb 1.33s ease-in-out infinite}@-webkit-keyframes throb{0%,100%{-webkit-transform:scale(1)}50%{-webkit-transform:scale(.8)}}@keyframes throb{0%,100%{-webkit-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(.8);transform:scale(.8)}} -------------------------------------------------------------------------------- /font/fontello.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2015 by original authors @ fontello.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/css/print.scss: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background: #e0e0e0; 8 | font-family: 'Helvetica Neue', Helvetica, 'Lucida Grande', Arial, 'Hiragino Sans GB', 微软雅黑, 'WenQuanYi Micro Hei', STHeiti, SimSun, sans-serif; 9 | } 10 | 11 | ul, 12 | li { 13 | list-style: none; 14 | } 15 | 16 | a { 17 | text-decoration: none; 18 | } 19 | 20 | aside { 21 | position: fixed; 22 | right: 0; 23 | top: 30%; 24 | } 25 | 26 | aside li { 27 | margin-bottom: 10px; 28 | padding: 10px; 29 | border-radius: 10px 0 0 10px; 30 | background: #00bfa5; 31 | } 32 | 33 | aside a { 34 | color: #fff; 35 | } 36 | 37 | .container { 38 | width: 1260px; 39 | height: 1782px; 40 | position: relative; 41 | } 42 | 43 | .sidebar { 44 | position: absolute; 45 | top: 0; 46 | bottom: 0; 47 | width: 450px; 48 | padding: 25px; 49 | background: #00bfa5; 50 | color: #fff; 51 | line-height: 1.5; 52 | -webkit-box-sizing: border-box; 53 | -moz-box-sizing: border-box; 54 | box-sizing: border-box; 55 | } 56 | 57 | .sidebar a { 58 | color: #fff; 59 | } 60 | 61 | .title { 62 | margin: 25px 0 20px; 63 | text-align: center; 64 | } 65 | 66 | .title img { 67 | display: block; 68 | margin: 0 auto 15px; 69 | width: 150px; 70 | } 71 | 72 | h1 { 73 | font-size: 36px; 74 | font-weight: normal; 75 | } 76 | 77 | h2 { 78 | font-size: 16px; 79 | } 80 | 81 | .side-info li { 82 | padding-top: 20px; 83 | } 84 | 85 | .side-info dt { 86 | font-size: 20px; 87 | color: #9f3; 88 | line-height: 40px; 89 | } 90 | 91 | .side-info dd { 92 | font-size: 16px; 93 | line-height: 20px; 94 | } 95 | 96 | .someRight dd { 97 | margin-left: 25px; 98 | } 99 | 100 | .skill { 101 | position: relative; 102 | } 103 | 104 | .skill-name { 105 | width: 100px; 106 | font-size: 14px; 107 | display: inline-block; 108 | position: relative; 109 | left: 25px; 110 | top: -3px; 111 | } 112 | 113 | .skill-bar-wrap { 114 | height: 17px; 115 | width: 150px; 116 | background: #00796b; 117 | display: inline-block; 118 | border-radius: 20px; 119 | } 120 | 121 | .skill-bar { 122 | height: 17px; 123 | background: #fff; 124 | border-radius: 20px 0 0 20px; 125 | } 126 | 127 | .note { 128 | text-indent: 2em; 129 | margin-top: 100px; 130 | color: #004d40; 131 | font-size: 20px; 132 | } 133 | 134 | .qr { 135 | position: absolute; 136 | bottom: 40px; 137 | color: #004d40; 138 | font-size: 20px; 139 | text-align: center; 140 | width: 400px; 141 | } 142 | 143 | .qr-in { 144 | margin: 0 auto; 145 | } 146 | 147 | .qr-in img { 148 | width: 200px; 149 | } 150 | 151 | .qr-in a { 152 | color: #004d40; 153 | } 154 | 155 | .main { 156 | position: relative; 157 | left: 450px; 158 | width: 810px; 159 | height: 1782px; 160 | padding: 15px 20px 0; 161 | background: #f0f2f1; 162 | -webkit-box-sizing: border-box; 163 | -moz-box-sizing: border-box; 164 | box-sizing: border-box; 165 | } 166 | 167 | .main a { 168 | color: #4db6ac; 169 | } 170 | 171 | .main-info > li { 172 | padding-top: 10px; 173 | } 174 | 175 | .main-info dt { 176 | font-size: 26px; 177 | color: #00796b; 178 | line-height: 30px; 179 | border-bottom: 1px solid #00796b; 180 | margin: 0 0 15px -5px; 181 | } 182 | 183 | .main-info dd { 184 | font-size: 17px; 185 | line-height: 27px; 186 | color: #616161; 187 | } 188 | 189 | .main-info span { 190 | color: #000; 191 | font-size: 18px; 192 | } 193 | 194 | h3 { 195 | font-size: 20px; 196 | color: #004d40; 197 | margin: 0 0 15px 5px; 198 | } 199 | 200 | h4 { 201 | line-height: 30px; 202 | font-size: 20px; 203 | color: #000; 204 | position: relative; 205 | bottom: 3px; 206 | } 207 | 208 | h4 a, 209 | h5 a { 210 | font-size: 14px; 211 | } 212 | 213 | h5 { 214 | clear: both; 215 | font-size: 18px; 216 | color: #000; 217 | line-height: 25px; 218 | } 219 | 220 | .circle { 221 | height: 14px; 222 | width: 14px; 223 | border-radius: 100%; 224 | background: #00796b; 225 | float: left; 226 | position: absolute; 227 | left: -28px; 228 | top: 5px; 229 | } 230 | 231 | .exp { 232 | border-left: 2px solid #00796b; 233 | margin-left: 15px; 234 | } 235 | 236 | .exp p { 237 | font-size: 15px; 238 | color: #616161; 239 | line-height: 21px; 240 | } 241 | 242 | .exp > li { 243 | position: relative; 244 | top: -5px; 245 | margin: 0 0 8px 20px; 246 | } 247 | 248 | .exp img { 249 | width: 150px; 250 | } 251 | 252 | .exp ul > li { 253 | margin: 0 0 12px 0; 254 | } 255 | 256 | .efe .task4img img { 257 | height: 73px; 258 | width: inherit; 259 | } -------------------------------------------------------------------------------- /src/css/style.scss: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background: #e0e0e0; 8 | font-family: 'Helvetica Neue', Helvetica, 'Lucida Grande', Arial, 'Hiragino Sans GB', 微软雅黑, 'WenQuanYi Micro Hei', STHeiti, SimSun, sans-serif; 9 | min-width: 1080px; 10 | } 11 | 12 | ul, 13 | li { 14 | list-style: none; 15 | } 16 | 17 | a { 18 | text-decoration: none; 19 | } 20 | 21 | h1, 22 | h2, 23 | h3, 24 | h4, 25 | h5, 26 | dt, 27 | dd, 28 | p { 29 | cursor: default; 30 | } 31 | 32 | aside { 33 | position: fixed; 34 | right: 0; 35 | top: 30%; 36 | z-index: 2; 37 | } 38 | 39 | aside li { 40 | margin-bottom: 10px; 41 | border-radius: 10px 0 0 10px; 42 | background: #00bfa5; 43 | box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); 44 | } 45 | 46 | aside a { 47 | color: #fff; 48 | display: inline-block; 49 | width: 80px; 50 | height: 38px; 51 | line-height: 38px; 52 | padding-left: 10px; 53 | } 54 | 55 | .container { 56 | position: relative; 57 | margin: 10px auto; 58 | box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); 59 | width: 1060px; 60 | overflow: hidden; 61 | border-radius: 4px; 62 | } 63 | 64 | .sidebar { 65 | position: absolute; 66 | top: 0; 67 | bottom: 0; 68 | width: 300px; 69 | padding: 15px 15px 10000px; 70 | background: #00bfa5; 71 | color: #fff; 72 | line-height: 1.5; 73 | -webkit-box-sizing: border-box; 74 | -moz-box-sizing: border-box; 75 | box-sizing: border-box; 76 | margin-bottom: -10000px; 77 | } 78 | 79 | .sidebar a { 80 | color: #fff; 81 | } 82 | 83 | .title { 84 | margin: 25px 0 20px; 85 | text-align: center; 86 | } 87 | 88 | .title img { 89 | display: block; 90 | margin: 0 auto 15px; 91 | width: 120px; 92 | } 93 | 94 | h1 { 95 | font-size: 28px; 96 | font-weight: normal; 97 | } 98 | 99 | h2 { 100 | font-size: 14px; 101 | } 102 | 103 | .side-info li { 104 | padding-top: 20px; 105 | } 106 | 107 | .side-info dt { 108 | font-size: 18px; 109 | color: #9f3; 110 | line-height: 40px; 111 | } 112 | 113 | .side-info dd { 114 | font-size: 14px; 115 | line-height: 20px; 116 | } 117 | 118 | .someRight dd { 119 | margin-left: 25px; 120 | } 121 | 122 | .skill { 123 | position: relative; 124 | } 125 | 126 | .skill-name { 127 | width: 100px; 128 | font-size: 14px; 129 | display: inline-block; 130 | position: relative; 131 | left: 25px; 132 | top: -3px; 133 | } 134 | 135 | .skill-bar-wrap { 136 | height: 17px; 137 | width: 150px; 138 | background: #00796b; 139 | display: inline-block; 140 | border-radius: 20px; 141 | } 142 | 143 | .skill-bar { 144 | height: 17px; 145 | background: #fff; 146 | border-radius: 20px 0 0 20px; 147 | } 148 | 149 | .note { 150 | text-indent: 2em; 151 | margin-top: 90px; 152 | color: #004d40; 153 | font-size: 18px; 154 | } 155 | 156 | .main { 157 | position: relative; 158 | left: 300px; 159 | width: 720px; 160 | padding: 15px 20px 10000px; 161 | background: #f0f2f1; 162 | margin-bottom: -10000px; 163 | } 164 | 165 | .main a { 166 | color: #4db6ac; 167 | } 168 | 169 | .main-info > li { 170 | padding-top: 20px; 171 | } 172 | 173 | .main-info dt { 174 | font-size: 24px; 175 | color: #00796b; 176 | line-height: 30px; 177 | border-bottom: 1px solid #00796b; 178 | margin: 0 0 15px -5px; 179 | } 180 | 181 | .main-info dd { 182 | font-size: 15px; 183 | line-height: 27px; 184 | color: #616161; 185 | } 186 | 187 | .main-info span { 188 | color: #000; 189 | font-size: 16px; 190 | } 191 | 192 | h3 { 193 | font-size: 19px; 194 | color: #004d40; 195 | margin: 0 0 15px 5px; 196 | } 197 | 198 | h4 { 199 | line-height: 30px; 200 | font-size: 18px; 201 | color: #000; 202 | position: relative; 203 | bottom: 3px; 204 | } 205 | 206 | h5 { 207 | clear: both; 208 | font-size: 16px; 209 | color: #000; 210 | line-height: 25px; 211 | } 212 | 213 | .fa { 214 | margin-right: 2px; 215 | } 216 | 217 | h4 a, 218 | h5 a { 219 | font-size: 12px; 220 | border: 1px solid #4db6ac; 221 | padding: 1px 3px; 222 | border-radius: 5px; 223 | margin-left: 7px; 224 | } 225 | 226 | .circle { 227 | height: 14px; 228 | width: 14px; 229 | border-radius: 100%; 230 | background: #00796b; 231 | float: left; 232 | position: absolute; 233 | left: -28px; 234 | top: 5px; 235 | } 236 | 237 | .exp { 238 | border-left: 2px solid #00796b; 239 | margin-left: 15px; 240 | } 241 | 242 | .exp p { 243 | font-size: 15px; 244 | color: #616161; 245 | line-height: 22px; 246 | margin-bottom: 3px; 247 | } 248 | 249 | .exp > li { 250 | position: relative; 251 | top: -5px; 252 | margin: 0 0 20px 20px; 253 | } 254 | 255 | .exp img { 256 | width: 200px; 257 | } 258 | 259 | .exp ul > li { 260 | margin: 0 0 12px 0; 261 | } 262 | 263 | .efe .task4img img { 264 | height: 97px; 265 | width: inherit; 266 | } 267 | 268 | footer { 269 | margin: 30px 0 20px; 270 | } 271 | 272 | footer p { 273 | text-align: center; 274 | color: #616161; 275 | font-size: 14px; 276 | } 277 | 278 | footer a { 279 | color: #616161; 280 | } 281 | 282 | .throb { 283 | -webkit-animation: throb 1.33s ease-in-out infinite; 284 | animation: throb 1.33s ease-in-out infinite; 285 | } 286 | 287 | @-webkit-keyframes throb { 288 | 0% { 289 | -webkit-transform: scale(1); 290 | } 291 | 292 | 50% { 293 | -webkit-transform: scale(0.8); 294 | } 295 | 296 | 100% { 297 | -webkit-transform: scale(1); 298 | } 299 | } 300 | 301 | @keyframes throb { 302 | 0% { 303 | transform: scale(1); 304 | } 305 | 306 | 50% { 307 | transform: scale(0.8); 308 | } 309 | 310 | 100% { 311 | transform: scale(1); 312 | } 313 | } -------------------------------------------------------------------------------- /print.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 邓国雄的简历 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 106 |
107 | 334 |
335 |
336 | 337 | 338 | 339 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 邓国雄的简历 7 | 8 | 9 | 10 | 11 | 12 | 28 | 29 | 30 | 31 | 44 |
45 | 112 |
113 | 700 |
701 |
702 | 706 | 707 | 708 | -------------------------------------------------------------------------------- /2024.html: -------------------------------------------------------------------------------- 1 | 邓国雄的简历(2024)

邓国雄的简历(2024)

前端高级开发工程师

腾讯音乐娱乐有限公司

深圳市,广东省 🇨🇳

职级:T11,团队骨干(毕业 4 年 T11)

T5→T6:2019.7 ~ 2020.9,本周期绩效:3+5

T6→T8:2020.9 ~ 2021.3,本周期绩效:5

T8→T9:2021.3 ~ 2021.9,本周期绩效:5

T9→T10:2021.9 ~ 2022.3,本周期绩效:5

T10→T11:2022.3 ~ 2024.3,本周期绩效:4+5+3+4

T11→?: 2024.4 ~ 至今

685 |

686 |

本科: 2013-2017 / 广州大学教育技术系+软件工程

硕士: 2017-2019 / 中山大学哲学系

✍️ ursb.me

📧 airing@ursb.me 📱131xxxxxxxx

知乎: Airing

GitHub: github.com/airingursb

updated:

技能

  1. Web 开发:熟练掌握 Web 开发技术栈,熟悉 React 技术栈、构建与工程化、Web 性能分析与优化;具有基础类库、开放平台框架的设计与开发经验;具有 2D 游戏开发经验;熟悉浏览器内核。
  1. 游戏引擎与终端开发:熟悉 iOS 原生开发,熟悉 C++ 开发,了解 Android 原生开发;具有 iOS 项目开发经验、游戏引擎的设计与开发经验。
  1. Flutter 跨端开发:熟悉 Flutter 研发技术栈,具有从零设计开发跨端框架的经验,熟悉业内各大跨端方案;曾参与 OpenKraken 开源建设;具有 React Native、Hippy、Flutter、iOS、小程序、Cocos 引擎等跨端容器开发经验。
  1. 3D 渲染:了解 Babylon 框架,熟悉 3D 开发流程,具有一定的 3D 开发经验与优化经验。

业务经历

项目经历

Atum 游戏引擎

职责:项目 Owner,兼 iOS & Web 端负责人,核心开发者,负责架构设计、进度管理、iOS 端 & C++ 层与 Web 端的研发工作,以及一部分 Android 端联调工作。

内容:负责 K 歌自研小游戏容器的设计、开发、落地与优化,包括 iOS 容器从零到一的开发、C++ GFX 层的开发、Web 适配层的开发、游戏业务的接入落地,以及后续性能数据与业务数据的监控、分析与优化。该容器已在 K 歌全量上线,拥有 xx 万 DAU。

  1. 开发 iOS 端容器,实现加载器流程与微信小游戏对齐的 JSBinding 能力。
  1. 开发 C++ 扩展层,大幅提升渲染性能,从而提升了业务核心数据;并开发了配套的 Web 适配层能力。
  1. 设计并实现了资源子包加载与流式加载方案,并设计实现了 LRU 公用缓存管理能力,大幅减少加载耗时、提升启动留存率,优化用户体验。
  1. 设计并实现了容器本地调试方案,提升业务侧研发效率。
  1. 优化了渲染循环的实现、图片加载的调用链、JSCore 执行效率、后台线程管理等底层能力,优化了游戏的执行效率。
  1. 完善 SDK 封装与工程化设计,最终提供给酷狗等第三方 App 接入并上线。
  1. 设计了 iOS 端引擎的 JIT 方案、Android Code Caching 方案。

Kant (TME Flutter)跨端开发解决方案

职责:项目 Owner,兼 Flutter 端负责人,负责项目架构设计、进度管理、项目推广、Flutter 与 iOS 端的研发工作。

内容:从零设计并落地了多引擎的混合开发方案,包括混合栈框架、全流程构建与发布、研发侧接入、定制引擎体积优化、动态化方案集成、质量保障、灰度策略等工作。最终该解决方案落地了 QQ 音乐、Fan 直播、Moo 音乐、豆瓣 FM、波点音乐等多款 TME 集团应用,成为集团的 Flutter 解决方案。

  1. 设计并实现多引擎混合路由栈,支持丰富的路由能力 push/pop(popTo),提供 Flutter 容器业务按需使用,并申请专利。
  1. 设计了全面的灰度降级与崩溃降级逻辑,框架内置质量组件,支持异常捕获、上报委托、日志代理、降级注册、开发提示等能力。该组件后来也抽象成独立库(Hume),供集团内未使用 Kant 的 Flutter 业务接入使用。
  1. 设计事件钩子与自定义事件,包括路由事件、生命周期事件、引擎事件、前后台切换事件、各种通道的自定义事件等。内部通信层的事件管理由 pigeon 统一协议。
  1. 基于 Kraken 作为渲染框架开发 Kun,支持动态化方案。设计实现了资源加载方案、动态化路由跳转方案、JSAPI 能力打通、同构开发模式(壳工程+业务仓库+基础库兼容+kbc同构CI+发布)。研发过程中为 Kraken 贡献了代码,并加入了 Kraken 与 WebF 的 TSC。
  1. 支持代码注解注册路由,提供 AOP 定制 Flutter 框架与代码生成两种方案。
  1. 为 Kant 做了性能优化,包括引擎预热、减包优化;修复 Emoji 内存问题与 iOS 混合栈内存问题。
  1. 制定 QQ 音乐 Flutter 研发流程规范,制定 TME Flutter 页面准入规范。

Q 音 K 歌互通 Web 基础库

职责:项目 Owner,核心开发者(top1 贡献),负责搭建直播业务与互通业务的 Web 基础库,并负责后续的升级迭代。

内容:

  1. 支持多端互通,目前落地于 QQ 音乐、全民 K 歌、JOOX、懒人听书、波点音乐等应用中的 Web 页面。横向支撑多个业务团队接入使用,不断维持高可用和高口碑,目前接入业务日 PV 量级 2000 万+。
  1. 规范严格的流程管理,搭建了完备的 CI/CD、完备的版本绑定管理、完善的发布周知机制。
  1. 支持多产物,除了 IIFE 与 ES Module 产物,还提供了必选、可选、分端等产物,支持业务方便按需引入。
  1. 实现了完备的数据上报(Flow、错误、测速、返回码)与监控体系,除了无感接入,业务也可以独立接入上报 SDK。目前业务日上报量级 2 亿+(采样后)。
  1. 实现了可选的网关请求库,针对不同网关提供对应的请求方法,适配集团内多套网关,业务无需关注网络协议,统一方法调用。

TMELAND

职责:前端负责人,核心开发者,负责 Owner 核心项目与设计,负责设计与开发 TMELand 开放平台。

内容:

  1. 2021 年年底负责 TME 集团跨年音乐节 Web 侧研发,与 SDK 方、10 端 App 接入方沟通、对接,同时负责大部分前端模块开发,最终页面按质按量如期上线于 QQ 音乐、全民 K 歌、酷我音乐、酷狗音乐、酷狗繁星五个 App。
  1. 2022 年 H1,负责设计与开发 TMELAND 开放平台,提效 TMELAND 3D 项目研发;同时此开放平台也提供给其他部门与外部公司接入开发 3D 业务。
  1. 2023 年前,负责端渲染 SDK 的建设,并基于端渲染 SDK 对 3D 场景做了相关的性能优化。

Web 直播中台

职责:项目 Owner,核心开发者。负责设计 Web 侧直播中台架构与落地,代码复用、严格分支与版本管理,支持多端上线直播页面。目前已支持懒人畅听、波点音乐、JOOX、爱趣听接入直播中台。

直播常驻页

职责:负责 Q 音直播几乎全部的 Web 常驻页的维护工作,负责新常驻页的开发、处理外网反馈问题、定期跟进质量与性能优化,长线保持各页面秒开率 80% 以上。同时也是团队代码质量负责人,培养了对性能数据与代码规范的敏感度。

其他业务

职业早期负责过一些活动页的开发,也核心参与过 Hippy 项目从零到一的开发、Flutter 项目的开发、中台系统的开发、Pixel 2D 游戏的开发与微信小程序的开发。

其他有价值的内容

  1. Options 预检请求优化:设计优化方案,并推动网关、鉴权、后台框架组联合进行预检请求优化。(2023)
  1. 2D 游戏插件化方案:为 2D 大世界游戏设计了 JS 玩法插件化方案,动态加载玩法以优化性能,同时支持第三方接入开发。(2022)
  1. Dusk (JSRuntime for WebGPU)项目 Owner,独立研发的技术项目,基于 Dawn 开发 JSBinding,提供 WebGPU 的 JS 运行时环境,目前仍在开发中。(2023)
  1. 建设 Q 音直播间半屏 WebView 方案。(2021)
  1. Q 音直播 JSAPI RFC 审核人,JSBridge 维护者。(2021-2023)
  1. 参与 Q 音 K 歌离线包研发期间的联调工作,参与设计流控方案。(2021)
  1. 负责定位与优化 K 歌大盘网络请求耗时长的问题。(2022)
  1. 设计并实现了直播间挂件页面与直播间互通榜单等多个大流量页面。(2021)
  1. 积极参与开源社区:W3C Accessible Rich Internet Applications Working Group 成员,Kraken & WebF TSC 成员,Bevy、Nodejs、Chromium 贡献者。

相关分享与产出

👨🏻‍💻 分享

如何打造高性能游戏引擎(公司级分享)

Kant 高性能跨端框架原理(CVTE 受邀分享)

Flutter 混合开发架构与实战(腾讯云大学受邀分享)

Flutter 大前端训练营(公司级课程)

开发者视角下的 Apple 工作流(Apple iOS Club 受邀分享)

Chromium 渲染流水线——字节码到像素的一生(部门分享)

跨端框架技术揭秘与趋势分析(部门分享)

687 |

另著有专利 30 篇,其中 1 篇已公开,为第一发明人兼撰写人,另外 29 篇为第二发明人兼撰写人。(详情见附录)

附录

司内奖项

2024

社区&互动年度突出个人

社区&互动年度突出个人 TED 分享 Talk King

2023

集团 UP 计划训练营优胜团队

2022

688 |

QQ 音乐业务线 Q3 业务突破个人奖(青年优才奖)

H2 优秀员工

2021

689 |

H2 优秀员工

H1 优秀员工

2020

Q 音之星

腾讯云「云+社区」人气讲师

Hack Week QQ 音乐创新大赛:由你 Pick 奖

大前端特训营项目:人力资源部 Q2 优秀项目

H1 优秀员工

691 |

-------------------------------------------------------------------------------- /2023.html: -------------------------------------------------------------------------------- 1 | 邓国雄(Airing)的简历(2023)

邓国雄(Airing)的简历(2023)

前端高级开发工程师

腾讯音乐娱乐有限公司

深圳市,广东省 🇨🇳

职级:T10,团队骨干

T5→T6:2019.7 ~ 2020.9,本周期绩效:3+5

T6→T8:2020.9 ~ 2021.3,本周期绩效:5

T8→T9:2021.3 ~ 2021.9,本周期绩效:5

T9→T10:2021.9 ~ 2022.3,本周期绩效:5

T10→?:2022.3 ~ 至今,本周期绩效:4+5

677 |

678 |

679 |

本科: 2013-2017 / 广州大学教育技术系+软件工程

硕士: 2017-2019 / 中山大学哲学系

✍️ ursb.me

📧 airing@ursb.me

知乎: Airing

GitHub: github.com/airingursb

updated:

技能

  1. Web 开发:熟练掌握 Web 开发技术栈,熟悉 React 技术栈、构建与工程化、Web 性能分析与优化;具有基础类库与开放平台框架的设计与开发经验;具有 2D 游戏开发经验;熟悉浏览器内核。
  1. Flutter 与跨端开发:熟悉 Flutter 研发技术栈,具有从零设计开发跨端框架的经验,熟悉业内各大跨端方案;曾参与 OpenKraken 开源建设;具有 React Native、Hippy、Flutter、iOS、小程序开发经验。
  1. 3D 渲染:了解 Babylon 框架,熟悉 3D 开发流程,具有一定的 3D 开发经验与优化经验。
  1. 客户端/跨端开发:了解 iOS 原生开发,了解 Android 原生开发,了解 C++ 开发;具有少部分 iOS 项目开发经验与 Android 库开发经验。

技能

技术栈/语言方向掌握程度
TypeScriptWeb 前端100
前端框架 (React, Vue)Web 前端100
Hippy / React NativeWeb 前端终端95
小程序Web 前端90
Web 工程化 (Rollup, Webpack, etc..)Web 前端85
Flutter (Dart)终端80
NodeJS服务端70
3D 渲染 (Babylon)Web 前端70
iOS (Objective-C, Swift)终端60
JS Engine (V8, JSCore, QuickJS)终端60
Android (Kotlin, JNI)终端50
Render Engine (Blink)终端50
Deno服务端40
Rust终端20


项目经历

Kant (TME Flutter)跨端开发解决方案

职责:项目 Owner,兼 Flutter 端负责人,负责项目架构设计、进度管理、项目推广、Flutter 与 iOS 端的研发工作。

内容:从零设计并落地了多引擎的混合开发方案,包括混合栈框架、全流程构建与发布、研发侧接入、定制引擎体积优化、动态化方案集成、质量保障、灰度策略等工作。最终该解决方案落地了 QQ 音乐、Fan 直播、Moo 音乐、豆瓣 FM、波点音乐等多款 TME 集团应用,成为集团的 Flutter 解决方案。

  1. 设计并实现多引擎混合路由栈,支持丰富的路由能力 push/pop(popTo),提供 Flutter 容器业务按需使用,并申请专利。
  1. 设计了全面的灰度降级与崩溃降级逻辑,框架内置质量组件,支持异常捕获、上报委托、日志代理、降级注册、开发提示等能力。该组件后来也抽象成独立库(Hume),供集团内未使用 Kant 的 Flutter 业务接入使用。
  1. 设计事件钩子与自定义事件,包括路由事件、生命周期事件、引擎事件、前后台切换事件、各种通道的自定义事件等。内部通信层的事件管理由 pigeon 统一协议。
  1. 基于 Kraken 作为渲染框架开发 Kun,支持动态化方案。设计实现了资源加载方案、动态化路由跳转方案、JSAPI 能力打通、同构开发模式(壳工程+业务仓库+基础库兼容+kbc同构CI+发布)。研发过程中为 Kraken 贡献了代码,并加入了 Kraken 与 WebF 的 TSC。
  1. 支持代码注解注册路由,提供 AOP 定制 Flutter 框架与代码生成两种方案。
  1. 为 Kant 做了性能优化,包括引擎预热、减包优化;修复 Emoji 内存问题与 iOS 混合栈内存问题。
  1. 制定 QQ 音乐 Flutter 研发流程规范,制定 TME Flutter 页面准入规范。

Q 音 K 歌互通 Web 基础库

职责:项目 Owner,核心开发者(top1 贡献),负责搭建直播业务与互通业务的 Web 基础库,并负责后续的升级迭代。

内容:

  1. 支持多端互通,目前落地于 QQ 音乐、全民 K 歌、JOOX、懒人听书、波点音乐等应用中的 Web 页面。横向支撑多个业务团队接入使用,不断维持高可用和高口碑,目前接入业务日 PV 量级 2000 万+。
  1. 规范严格的流程管理,搭建了完备的 CI/CD、完备的版本绑定管理、完善的发布周知机制。
  1. 支持多产物,除了 IIFE 与 ES Module 产物,还提供了必选、可选、分端等产物,支持业务方便按需引入。
  1. 实现了完备的数据上报(Flow、错误、测速、返回码)与监控体系,除了无感接入,业务也可以独立接入上报 SDK。目前业务日上报量级 2 亿+(采样后)。
  1. 实现了可选的网关请求库,针对不同网关提供对应的请求方法,适配集团内多套网关,业务无需关注网络协议,统一方法调用。

TMELAND

职责:前端负责人,核心开发者,负责 Owner 核心项目与设计,负责设计与开发 TMELand 开放平台。

内容:

  1. 2021 年年底负责 TME 集团跨年音乐节 Web 侧研发,与 SDK 方、10 端 App 接入方沟通、对接,同时负责大部分前端模块开发,最终页面按质按量如期上线于 QQ 音乐、全民 K 歌、酷我音乐、酷狗音乐、酷狗繁星五个 App。
  1. 2022 年 H1,负责设计与开发 TMELAND 开放平台,提效 TMELAND 3D 项目研发;同时此开放平台也提供给其他部门与外部公司接入开发 3D 业务。
  1. 2023 年前,负责端渲染 SDK 的建设,并基于端渲染 SDK 对 3D 场景做了相关的性能优化。

Web 直播中台

职责:项目 Owner,核心开发者。负责设计 Web 侧直播中台架构与落地,代码复用、严格分支与版本管理,支持多端上线直播页面。目前已支持懒人畅听、波点音乐、JOOX、爱趣听接入直播中台。

直播常驻页

职责:负责 Q 音直播几乎全部的 Web 常驻页的维护工作,负责新常驻页的开发、处理外网反馈问题、定期跟进质量与性能优化,长线保持各页面秒开率 80% 以上。同时也是团队代码质量负责人,培养了对性能数据与代码规范的敏感度。

其他业务

职业早期负责过一些活动页的开发,也核心参与过 Hippy 项目从零到一的开发、Flutter 项目的开发、中台系统的开发、Pixel 2D 游戏的开发与微信小程序的开发。

其他有价值的内容:

  1. Options 预检请求优化:设计优化方案,并推动网关、鉴权、后台框架组联合进行预检请求优化。(2023)
  1. 2D 游戏插件化方案:为 2D 大世界游戏设计了 JS 玩法插件化方案,动态加载玩法以优化性能,同时支持第三方接入开发。(2022)
  1. Dusk (JSRuntime for WebGPU)项目 Owner,独立研发的技术项目,基于 Dawn 开发 JSBinding,提供 WebGPU 的 JS 运行时环境,目前仍在开发中。(2023)
  1. 建设 Q 音直播间半屏 WebView 方案。(2021)
  1. Q 音直播 JSAPI RFC 审核人,JSBridge 维护者。(2021-至今)
  1. 参与 Q 音 K 歌离线包研发期间的联调工作,参与设计流控方案。(2021)
  1. 负责定位与优化 K 歌大盘网络请求耗时长的问题。(2022)
  1. 设计并实现了直播间挂件页面与直播间互通榜单等多个大流量页面。(2021)
  1. 为 K 歌自研 Canvas 容器接入 JS Debugger。(2023)
  1. 积极参与开源社区:W3C Accessible Rich Internet Applications Working Group 成员,Kraken & WebF TSC 成员,bevy & nodejs 贡献者。

相关分享与产出

👨🏻‍💻 分享

Kant 高性能跨端框架原理(CVTE 受邀分享)

Flutter 混合开发架构与实战(腾讯云大学受邀分享)

Flutter 大前端训练营(公司级课程)

开发者视角下的 Apple 工作流(Apple iOS Club 受邀分享)

Chromium 渲染流水线——字节码到像素的一生(部门分享)

跨端框架技术揭秘与趋势分析(部门分享)

680 |

另著有专利 19 篇,其中一篇已公开,为第一发明人兼撰写人,另外 18 篇为第二发明人兼撰写人。(详情见附录)

附录

奖项

2023

入选集团 UP 计划训练营

2022

681 |

QQ 音乐业务线 Q3 业务突破个人奖兼青年优才奖

H2 优秀员工

2021

682 |

H2 优秀员工

H1 优秀员工

2020

Q 音之星

腾讯云「云+社区」人气讲师

Hack Week QQ 音乐创新大赛:由你 Pick 奖

大前端特训营项目:人力资源部 Q2 优秀项目

H1 优秀员工

🏢 专利

专利名状态角色
《一种页面导航方法、设备及可读存储介质》已公开撰写人第一发明人
《一种快捷发送跟随消息的技术方案》官审中发明人撰写人
《一种对即时聊天消息更精准的筛选方案》官审中发明人撰写人
《一种跨聊天窗口打通用户状态并支持快速互动的技术方案》官审中发明人撰写人
《一种根据管理目的提供不同界面和功能的聊天窗口技术方案》官审中发明人撰写人
《一种基于群聊场景多线程浏览并筛选消息的处理方案》官审中发明人撰写人
《一种基于多人内容聚合场景使用快捷手势查看内容的技术方案》官审中发明人撰写人
《基于社群场景中多任务并线进行的解决方案》官审中发明人撰写人
《一种基于聊天窗口敏感信息好友打码机制的技术实现方案》官审中发明人撰写人
《一种基于轻量快捷设置互动模式的多人语音房技术方案》官审中发明人撰写人
《一种基于多人内容聚合场景使用快捷手势查看内容的技术方案》官审中发明人撰写人
《一种基于(脱敏)场景进行消息处理及群聊通讯的技术方案》内审中发明人撰写人
《一种基于(脱敏)进行多个会话消息收发处理的技术方案》内审中发明人撰写人
《一种(脱敏)的语音发送方案》内审中发明人撰写人
《一种基于群聊话题内容的(脱敏)的技术实现方案》内审中发明人撰写人
《一种实时显示(脱敏)的即时通讯应用主页》内审中发明人撰写人
《一种智能生成视频剧集(脱敏)的技术方案》内审中发明人撰写人
《一种基于群聊场景可持续更新与(脱敏)管理技术方案》内审中发明人撰写人
《基于对视频剧集进行(脱敏)的生成方法》内审中发明人撰写人


683 |

--------------------------------------------------------------------------------