React脚手架V1.0

背景

最近开始捯饬React,想着学会了React就能把React Native给学习了,然后就能写App。为了能够在React Native上少踩坑,我搭建这个脚手架之后,准备开发一个博文发布系统,作为DEMO练练手。

依赖构成

  1. React核心
  2. React-router-dom 路由
  3. Redux 状态管理
  4. ESlint 代码格式管理
  5. Vite 打包工具
  6. Axios 网络请求库
  7. Antd UI库

搭建流程

1. 初始化React

1.1 模板初始化

我们可以直接使用Vite自带的模板,初始化React,在本教程中我使用的是template指令来初始化项目。

运行以下指令初始化项目

 # npm 6.0
 npm init @vitejs/app gublog(项目名称) --template react(模板名称)
 ​
 # npm 7.0+ (需要额外的双横线)
 npm init @vitejs/app gublog(项目名称) --(额外的双横线) --template react(模板名称)

运行指令后,npm将创建一个以项目名称命名的文件夹📁,来初始化项目。

初始化完成后的文件树结构为:

 root
 └── gublog(项目名称)
    ├── dist
    ├── node_modules
    ├── src
    ├── index.html
    ├── package-lock.json
    ├── package.json
    └── vite.config.js

1.2 启动环境

  1. cd 项目文件夹
  2. npm install #下载依赖
  3. npm run dev #启动开发环境
环境启动成功

出现上图的网页时,我们就已经搭建出Vite + React的开发环境

2. 安装React-router-dom

为了能够实现无刷新切换页面,此处我的脚手架也会引入官方提供的Router来做前端路由管理。

2.1 安装依赖

运行指令安装路由组件

 npm install react-router-dom --save-dev

2.2 注意⚠️

React-Router-Dom就是React Router V4的浏览器版本,原来文档的Router要被替换成BrowserRouter才能使用。为了不使用方面,我们可以使用as关键字来修改别名。

 import 'BrowserRouter' as 'Router' from 'react-router-dom'

这里我真的很想吐槽,搞一个React-Router就好了嘛🤷‍♂️,干嘛还搞一个React-Router-Dom。这东西本质上就是套娃再封装📦。而且最近的V4版本还舍弃了旧的Router标签,改成了BrowserRouter。真的是NT。

解决方法来源:

3. 安装Redux

安装Redux主要是为了使得组件的耦合降低,使得更容易的管理状态,因此被打包到脚手架当中。

3.1 安装依赖

 npm install redux --save-dev

4. 安装ESlint

4.1 安装依赖

 npm install eslint --save-dev

5. 安装Axios网络请求库

5.1 安装依赖

 npm install axios --save-dev

6. 安装AntdUI库

AntdUI是阿里针对React设计的一个UI库,开箱即用,有丰富的文档。(而且还能改颜色)

6.1 安装依赖

 npm install redux --save-dev

6.2 引入环境

  1. main.css中添加import 'antd/dist/antd.css'导入CSS库
  2. Main.jsx的代码头部添加import {组件名称} from antd导入组件

结尾

这篇文章就此告一段落。Axios和ESlint的使用我还在摸索中,后面还会继续更新,敬请期待。目前在使用这个脚手架重写GuBlog日志程序当中,后面时机成熟后也会同新版本的脚手架文章一同推出。

npm 安装、删除依赖命令

npm安装依赖

  • npm install xxx 利用 npm 安装xxx依赖到当前命令行所在目录
  • npm install xxx -g 利用npm安装全局依赖xxx
  • npm install xxx –save 安装并写入package.json的”dependencies”中
  • npm install xxx –save-dev 安装并写入package.json的”devDependencies”中

npm删除依赖

  • npm uninstall xxx 删除xxx依赖
  • npm uninstall xxx -g 删除全局依赖xxx

PPG式心率测量小程序的技术分享

故事

背景

去年6月份的时候,参加了微信小程序官方举办的《高校微信小程序开发大赛》,做出了《活力健身房》这个小程序。按照初版设计,除了可以检测用户的跑步数据外,还可以测量用户的静止心率。但由于个人除了要准备比赛,还要准备痛苦的概率论补考,所以导致日程太过于紧凑,因此在该情况下,我就只完成了第一个目标而忽略了第二个心率测量的目标没有实现。

改进

在暑假期间,处于追求完美的想法,我花了一部分的时间继续学习并完成了心率检测算法的V1.0版本。而后再在这周,时隔一年的时间,重写了检测算法,推出了V1.1的版本。(至于为什么算是1.1版,在文中会说明的😂)。

技术分享

今天我写这篇文章的主要目的是跟大家分享以下的三点内容:

  1. PPG式心率测量的原理
  2. PPG式心率测量的实现
  3. 应用到小程序端的难点

1.技术原理

光体积变化描记图法 (Photoplethysmography,简称PPG) 是借光电手段在活体组织中检测血液容积变化的一种无创检测方法。当一定波长的光束照射到指端皮肤表面,每次心跳时,血管的收缩和扩张都会影响光的透射 (例如在透射PPG中,通过指尖的光线) 或是光的反射 (例如在反射PPG中,来自手腕表面附近的光线)。当光线透过皮肤组织然后再反射到光敏传感器时,光照会有一定的衰减。像肌肉、骨骼、静脉和其他连接组织对光的吸收是基本不变的 (前提是测量部位没有大幅度的运动),但是动脉会不同,由于动脉里有血液的脉动,那么对光的吸收自然也会有所变化。[1]

PPG检测的核心是通过心脏跳动影响血管中血液光线的吸收率变化,进而影响血液对光的反射率,估算受测者的心率数据。用人话说,心脏的跳动,会影响血液反射光的强度。反映到图表上,就如下图所示,心脏的舒张和收缩,会影响光强变化,形成下图的波动曲线。而心率的估算,则是通过计算60s内,有多少个波峰或者波谷。比如60s内,图表上产生了60个个波峰,则意味着1s中,心脏收缩和扩张了一次,即跳动了一次,进而可以得出60BPM的心率数据。

PPG传感器工作原理

2.技术实现

根据技术原理可以知道,PPG检测中我们需要做的事情是,计算一段时间内出现了多少个波峰,即可估算出受测者的心率。由此我们需要考虑实现以下的几个功能:

  1. 获取视频流中的某一帧
  2. 检测传感器是否被覆盖
  3. 获取当前帧的光强数据
  4. 计算波峰个数
  5. 计算BPM

1.获取视频中的某一帧

在当今社会中,人人都会有一台的智能手机。而手机上最好的颜色传感器就是摄像头了,因此在小程序端的实现中,对于数据的来源主要是摄像头。

为了实现方便,这次我依旧是使用小程序作为我的开发平台。之所以使用小程序的核心原因是官方提供了摄像头的API,使得我可以通过简单的$API$就可以获取到来自用户摄像头的视频流数据,并且不用考虑兼容性的问题。

在小程序中,我是用的是wx.createCameraContext()API来获取到视频流,同时借助onCameraFrame()来直接获取到每一帧的视频信息,极大的降低了开发的难度。通过前述的API,我们可以直接获取到当前帧Uint8数组,也就是每个像素的RGBA值。

2.检测传感器是否被覆盖

为了避免外部光照影响血管对光线的反射,因此需要受测者的手指完全覆盖摄像头。为了检测摄像头是否覆盖,我们可以通过经验主义设定一个阈值,当每个像素的实际光强小于阈值,则代表传感器完全被覆盖,此时就可以开始测试。

3.获取当前帧的光强数据

通过API,我们可以获得视频流中特定的一帧的Uint8数据。之所以使用Uint8是因为在该RGBA中,每一个通道的颜色只有256种,而我们仅仅是需要获取该帧中的光强。因此选用Uint8可以大幅度减少运算量,提高运行效率。

通过经验主义的测量以及结合论文[2] [3]的理论支持,我们可知血液在红光和绿光的照射下的吸收率是最大的,也就意味着强度值是最大的。因此可以更好的检测到强度变化,所以在后续的开发当中,我们都将使用单个像素中的红绿通道的强度值,来作为数据的来源。由于只使用了其中两个通道的强度值,我们的运算量就可以几何级数减少。

从原来的 2^{32} 个数据转变为了 2^{16} 个数据

获取光强的方法是:

该帧的光强值 = \frac{单个通道的强度值}{像素的个数}

4.计算波峰个数

在1.0版本中我的实现方法是通过经验值测算出一条固定的基线,来判断历史采集的光强值,有多少个跃出基线的数据,就计作多少个波峰。

V1.0 固定基线法

但这种设计是有问题的,比如最右侧的波峰,因为各种外部原因强度没有达到基线,导致丢失。当通过人眼的辨识,这个波峰不属于噪声,应该是要被记录的。

另外通过测试我们可以很容易的发现下图的假波峰和假波谷的噪声信号,这种变化幅度过大的数据也应该是被丢弃的。

噪声曲线

因此在1.1版本中,基线的计算方法做了改进。通过动态基线可以适应复杂环境光线的变化,提高测量的效率和准确性。

V1.1 动态基线法

通过动态基线,判断有多少多少次实际的跃出,进而换算出有多少个波峰。

5.计算BPM

仅仅记录波峰个数是远远不够的,我们还要计算一次跃出所消耗的时间(从波谷到跃出基线到波峰所消耗的时间)。因为受测者的光线环境如果不稳定,含有频繁的光线变化,则可能导致光强变化幅度过大,造成数据的计算误差。因此我们还需要将跃出时间作为计算的一个因素,计算平均的跃出时间。最后计算出每分钟的心率次数:

BPM = \frac{测量最大时间}{平均跃出时间}

小程序端的技术难点

到目前为止,小程序端最大的难点不在于测量算法的开发上。反而是在优雅的展示上画了大量的时间。

  1. FrameData大小
  2. Canvas绘图效率低

1.FrameData大小。通过Camera组件,我们可以直接获取到手机的视频流。由于我们这个算法中仅仅需要计算帧的光强,所以仅仅需要最低质量的FrameData即可。即降低了资源的消耗也提升了算法运行的效率。通过frame-data属性,修改为small即可启用最低质量的FrameData。

2.Canvas绘图效率低。在去年小程序退出了Canvas 2D的绘图API,可以实现同层渲染。为了更高的渲染效率,我自然就是选择并使用了最新的API进行曲线的绘制。在电脑模拟器上的表现确实印证了效率更好的这一说法。但诡异的是在Android端上,Canvas2D的运行效率非常低,导致经常性假死,不知道怎么修复。因此只能暂时被搁置,待到日后有能力后再做修复。

收获

这次的开发通过学习更多前人的研究结论来帮助我将算法优化出来,收获满满。感觉到非常的振奋人心。期待后面能继续搞点好玩的DEMO。

未来的方向

最近看到Tensorflow的BlazeFace。可以用很小的体积的模型来识别人脸,感觉可以借此,结合PPG算法,实现rPPG式的检测算法,日后有时间可以继续搞一下,感觉会非常的好玩。同时Canvas的问题也需要被修复,或许能够通过WebGL来修复?但是我还不肯定,需要后续的实验才能证明,待到后面再修吧。

结尾

由于本人不是电子工程专业,所以上文中可能会涉及到部分不规范的说明和解释。如果您能够在评论中帮助我指出来并帮助我改正,我将十分感激您,谢谢。

参考

[1] ECG/PPG量测解决方案

[2] 不同波长近红外光下手掌静脉图像质量分析

[3] 血液成分对光吸收规律的实验研究

日常碎碎念 2021.6.20

上周总结

  1. 疫苗接种
  2. 期末考试
  3. 重写PPG式心率测量算法
  4. 学习React

1.疫苗接种。学校终于通知我们打疫苗了,下个月要去深圳实习,打了疫苗才能安心一点呀。打疫苗过程中真的是热死🥵人了,被热蒸气熏蒸,感觉人都快晕掉了,好在以后不用再接种了。(希望)

2.期末考试。上周四的时候,终于将最重要也是最难的两科考试考完了,普天同庆。虽然NT学校安排了一门开卷考试在7月2日。但是可以放松下来,随心所欲的学习也是不错的感觉。希望最后一门考试也能取得好成绩吧。

3.重写PPG式心率测量算法。之前在《活力健身房》中做了一个心率测量的功能。但是随着我的电脑更换,我那部分的代码被迫丢失了。因此趁着最近有空余时间了,整理了一下之前的思路,重写了整个心率测量的算法。并且由于最近也在学习React+React Native。所以希望将这套算法重写验证后,移植到React Native上,做出一个App上架到App Store中国呢赚一点零花钱。(到时候我也会单独写一篇文章来介绍算法的原理以及具体的实现方式)

3.学习React。下个月就要开始鹅厂的实习生活了,问了leader有什么内容需要我提前学习的。React就是入门的门槛了,后面还要转成React Native。看来跨端开发真的是未来5-6年的发展方向啊。UniAPP,Vue多端编译,React Native。另外React的JSX语法其实还挺有趣的,感觉小程序与React的实现非常相似,后面也打算出一些关于小程序底层的分析文章,到时候可以相互比较一下思路。

本周计划

  1. 学习React
  2. 完成《创新创业课程实训》
  3. 完成《PPG式心率测量小程序的技术分析》撰写
  4. 摸鱼

结尾

这一周的主旋律还是摸🐟为主,毕竟没有很难得考试了。可以花点时间摸摸鱼休息一下,如果能出门去逛一下就更好了

日常碎碎念 2021.6.14

上周总结

  1. 端午节假期
  2. 学校封校
  3. 软件测试与质量保证考试
  4. 看书《自制编程语言》

1. 端午节假期。学校为了提前放假,把后续的所有课程都提到6月的周末进行授课。因此导致端午假期其实都是在上课。(不幸中的万幸,主要的课程在5月底就已经结束,现在只剩下一个学校的企业实训课程,压力还算不是很大。)另外学校可能🤔是为了安慰大家,端午节居然开始派发粽子了。读了3年书,这是第一次。2020年和2021年真的是奇妙,什么新鲜事都见到了。

2.学校封校。由于学校需要配合当地的疫情防控要求,因此对校园实施了封校处理。但u1s1,我们学校就是在郊区,偏僻的不得了。平时也没啥人会专门流动到我们这里来,实在是想不通为啥要实施封校处理。封校处理也直接导致校外的商业气息消失的一干二净,非常的安静,静悄悄的,都没有烟火气了💔。另外不能出门喝咖啡☕️和剪头发💇‍♂️也是让人感到好不方便啊。(上一次为了去拍照,找了一个100块的理发师,现在看来100还是物有所值的。秒杀我平时去的60块的理发馆,起码头发长了,那个形态还是整齐的,下次还会回去剪。)

3.软件测试与质量保证考试。3月开放回校,4月雅思考试,5月面试大厂。时间飞逝,转眼间就到了6月,迎来了第一场考试。考试的手感还行,希望能够再接再厉,后续能够取得更好的成绩吧。

3.《自制编程语言》。最近618购物节,没啥好买的。在当当网上偶然瞥见了这本书,感觉非常的有趣,因此上网下载了一本PDF版的电子书来阅读。后悔当初学习编译原理的时候没早点看到这本书。作者通过生动的图像,以及平易近人的话语,来向读者介绍了程序语言以及编译器的工作原理,并在后面手把手教授读者自己开发一个编译型语言出来。个人觉得真的是非常有趣的一本书。目前刚刚把编译器的梗概介绍读完,正在跟着作者实用yacc(语法分析器)和lex(词法分析器)来开发一个编译器和编译语言。通过实践,能够更加明确的认识到上个学期学习的自动机,文法,归约,移进等名词,在实践中的应用。非常过瘾和令人兴奋🥰。读完之后我会单独写一篇读后感,希望到时候能够有人来看。

本周计划

  1. 软件工程师资格培训-期末考试
  2. PHP Web高级应用开发-期末考试
  3. 完成企业实训任务
  4. 继续读书

结尾

今天是6月14日端午节,不知道看到这篇博文的你吃粽子了吗?另外也祝你端午安康😊!

日常碎碎念 2021.06.06

本周总结

  1. 阿里实习Offer
  2. 主要课程结束
  3. 小程序大赛&交接
  4. 工作室容器化工作流
  5. 核酸检测
  6. 软件设计师资格考试和六级考试

1. 阿里实习Offer。终于等到了来自阿里的实习Offer,对于我一个来自三本的学生而言,真的是非常的惊喜了。去到了广州的支付宝质量保证与技术风险部,主要做的是内部工具。想到有机会接触到底层技术的开发,想想就令人很激动啊🥳。(可惜现在广州有疫情的牵制,不然上下班30min的优势真的是好爽啊!)

2.主要课程结束。大三下的课程转眼间就要结束了,下周就要开始准备考试了,感觉时间过的真的好快啊。同时6月已经悄然来临,2021年就要过去一半了,感觉时间流逝最快的是4月找实习的日子,平和🙃,焦虑😖,喜悦😝的感觉至今都难以忘怀,相信这段经历会伴随我一辈子吧。不过还是要端正态度,不骄不躁,好好迎接接下来的考试,不要把之前的优势丢失了,加油😎。

3.小程序大赛&交接。去年的《软件项目管理课程》中,召集了几位dalao,一起开发了一个课室签到小程序。今年年初被老师怂恿着,拿着这个小程序去参加了比赛。不过计划始终是赶不上变化,年初的时候,雄心壮志的立下了许多先进的目标,4月就开始各奔东西找实习,5月接OC摸🐟,导致6月只能把最原始的1.0版本交上去。老师也可能是看到这个原因,感觉我们靠不住,就找大二的dalao来接手了,希望他们不会像我这么摸,能够把小程序成功落地,造福学校的师生吧。(感觉自己就是个反面教材🤣)

4.工作室容器化工作流。最近终于下定决心,通过众筹,购入了一年的云服务器。开始构建工作室的容器化工作流了。之前都是需要先push到github上,等待学校管理员,pull到服务器上面的。自由度非常非常低,而且还会有很多的局限性。因此我希望这次可以借助这个机会,构建一条全自动化的工作流:上传Github->构建docker image->推送到docker container->上线。并且借助网页面板,能够在线管理服务。期望这样子可以实现后端服务的无缝迁移和运行。不论是哪一届,都能继承这套内部工具来进行业务的测试开发。彻底摆脱学校的限制🚫。

5.核酸检测。广州最近出现了大量的新冠疫情感染者,因此被要求进行全市的核酸检测。市区部分在前3-4天已经完成2-3次的检测任务了。但是我们这些郊区一直没有消息,昨天临时接到通知,要通宵做核酸检测。因此凌晨3点被拉出去做了核酸检测,真的是辛苦了医护人员了👨‍⚕️👩‍⚕️,广州加油。另外5.6号的时候,我因为喝了浓鸳鸯而通宵;没想到一个月后的6.6号我因为核酸检测,再次通宵,历史惊人的相似,真的是难忘的大学经历了😄。

6.软件设计师资格考试和六级考试。由于广州的疫情原因,导致这两门考试在广州的考点不得不延期举行。(其实就是取消6月的考试了)对于我来说,其实我是高兴的,主要是因为我没做多少的复习,去考试也是去浪费金钱💰和时间⌚️。反倒是我的舍友们损失惨重,每天都看见他们在努力💪学习,刷题到深夜,希望他们能够在之后的考试中获🉐️出色的成绩吧。

下周计划

  1. 软件测试与质量保证 考试
  2. 复习下周考试内容

实施情况

计划使用周日、周一、周二的时间进行复习,准备周三的考试。期望能够通过这三天的努力取得一个出色的成绩吧。

PHP和软件工程师的课程期末考试在下下周,因此同样需要耗费一定的时间来准备,目前计划周三考完试再进行准备。

结尾

明天就是6.7号,一年一度的高考日,还是要来了。在期待自己能够在下周取得好成绩的同时也祝福高考考生旗开得胜吧!

M1 Mac 配置&初始化 Nginx+PHP+MySQL环境

环境

  1. Homebrew🍺
  2. Xcode命令行工具
  3. PHP 8.0
  4. Nginx
  5. MySQL

1.安装Xcode命令行工具

执行命令 Xcode-select --install

2.安装Homebrew


访问 Homebrew 官网,点击访问官网
按照指引,安装Homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Homebrew常用指令

  • 安装package

brew install 包名

  • 卸载package

brew uninstall 包名

  • 检查package的信息

brew info 包名

  • Homebrew升级

sudo brew update

  • Homebrew搜索package

brew search 包名

  • 检视已安装的package

brew list

3.使用Homebrew安装Nginx

  • 安装Nginx

sudo brew install nginx

  • 启动Nginx

nginx
安装&启动完成后,从浏览器中输入localhost:8080即可访问到Nginx服务器的欢迎页面

  • 关闭Nginx

nginx -s sotp

  • 重启Nginx

nginx -s reload

  • 查看Nginx版本

nginx -v

4.安装PHP 8.0

我作为一个从5.5时代就开始做php开发的开发者,也是第一次使用8.0的稳定版。直接一步到位的原因是:更好的语法&JIT的支持,希望能够在8.0时代获得更好的性能。因此本教程,将会采用8.0版本的PHP进行安装。

  • 使用Homebrew安装PHP

brew install php
如果需要特定版本的php则包名改为`php@指定的版本号`即可

  • 启动&重启

php-fpm

  • 强制关闭php-fpm

sudo pkill -INT -o php-fpm

5.配置PHP

  • 进入php配置文件夹

通过brew info找到php配置文件的位置
brew info php

  • 编辑php.ini文件

vim php.ini

  • 守护PHP进程

默认安装的PHP仅仅会在前台运行,如果此时我们关闭命令窗口的话,php-fpm将会自动关闭,无法继续处理我们的php请求。
开启 `守护模式` 即可解决这一问题

1. 配置php-fpm.conf
vim php-fpm.conf
2. 查找 daemonize
直接键入/daemonize
3. 修改值为yes并且保存
daemonize = yes
虽然注释处,写了默认值应该为yes,但是不知道是什么原因,导致了默认值是no

  • 安装php拓展

通过Homebrew安装的php,自带了pecl。这是一个php拓展的包管理器,后续的拓展安装,仅仅需要通过该管理器安装即可。一般开发用不到,主要是用于实现加密或者网络的时候,可能需要通过该tab来安装

pecl version 查看版本信息

pecl help 可以查看命令帮助

pecl search xdebug 搜索可以安装的扩展信息

pecl install xdebug 安装扩展

pecl install http://pecl.php.net/get/redis-4.2.0.tgz 安装指定版本扩展

6.配置Nginx

  • 通过brew info找到Nginx的配置目录
  • 打开nginx.conf

vim nginx.conf

1. 修改启动端口为80

  • 找到listen关键词
server{ 
    listen 8080; // Nginx需要监听的接口 
    server_name localhost; 
    ...
}
  • 修改为80端口
server{ 
    listen 80; // Nginx需要监听的接口 
    server_name localhost; 
    ...
}

2. 修改默认入口文件
在index这一行中,加入index.php,将其也作为入口文件。

location / { 
    root html; 
    index index.html index.htm index.php;
}

3. 启用php流量转发
找到location ~.php$关键词,将注释删掉(删掉代码前面的’#’),启用php流量转发

location ~ .php$ { 
    root html; 
    fastcgi_pass 127.0.0.1:9000; 
    fastcgi_index index.php; 
    fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 
    include fastcgi_params;
}

4. 配置php流量转发规则
修改location ~.php$中的fastcgi_param配置项

将其从SCRIPT_FILENAME /scripts$fastcgi_script_name

修改为SCRIPT_FILENAME $document_root$fastcgi_script_name

Nginx常用命令

  • 查看报错文件的路径

nginx -V

nginx version: nginx/1.19.10
built by clang 12.0.0 (clang-1200.0.32.29)
built with OpenSSL 1.1.1k 25 Mar 2021
TLS SNI support enabled
configure arguments: 
...
--error-log-path=/opt/homebrew/var/log/nginx/error.log 
...

找到error-log-path关键字,后面的值即为错误报告的地址。
使用tail -f 文件名查看即可。

  • 检查配置文件正确性

nginx -t

  • 检查Nginx进程运行状态

ps -aux | grep nginx

7.验证PHP环境

  • 启动Nginx服务器
  • 启动php-fpm服务
  • 通过brew info nginx查询网页根目录
  • 在网页根目录下创建index.php

index.php代码:

<?php phpinfo(); ?>
  • 通过浏览器访问http://localhost/index.php

若出现PHP Version + 版本号 以及 php相关的信息则安装完成

php安装成功

8.安装MySQL

我当前的系统版本是BigSur,如果你是Catalina也是兼容的,下载最新版就好了。

  • 点击”No thanks, just start my download.”开始下载即可
  • 下载完成,解压双击运行pkg即可,按照步骤执行即可

管理MySQL

  • 通过访问系统偏好设置的MySQL即可管理MySQL服务
  • 通过GUI管理服务的启停

通过命令行管理MySQL

  • 查看MySQL版本

mysql -v

  • 登录MySQL服务器

mysql -u 用户名 -p
出现`Enter password`后输入你的密码回车,即可登录MySQL服务器。

  • 登出MySQL服务器

exit

通过phpMyAdmin管理MYsql

  • 访问官网下载phpMyAdmin即可,点击访问
  • 下载完成后,将phpmyadmin文件夹拖入网站根目录
  • 通过浏览器访问http://localhost/phpmyadmin即可

常见问题

  • 执行mysql显示command not found: mysql

这是由于没有将mysql指令加入到命令行窗口中的原因

解决方法:

  1. cd ~ 切换到用户目录
  2. 输入vim .bash_profile 打开命令行配置文件
  3. 输入export PATH=$PATH:/usr/local/mysql/bin
  4. 保存文件
  5. 运行source ~/.bash_profile加载配置文件
  6. 此时就可以顺利使用MySQL了

结尾

这篇教程主要目的是为了帮助我记录下Mac系统中配置环境的流程而写。方便我日后如果需要重装或者更换电脑的时候可以快速将环境搭建完成。希望这篇教程也能帮助到你,谢谢。

日常碎碎念 2021.5.26

上周总结

  1. 阿里素质测评
  2. 体质测试
  3. 工作室会议
  4. 海底捞聚餐

1. 阿里素质测评。之前被阿里捞起来面试莫名其妙的,面试官也在问我为什么没有素质测评,因此HR面之后就被安排去把素质测评补上了。现在还在等HR的回复,真的是等的黄花菜都要凉了,好在有一个鹅厂保底,不然等待⌛️真的是一个煎熬的过程呐。

2.体质测试。下学期就要晋升为大四的学生了,时间过的真的是飞快,转眼间就要从大学的课堂中步入社会了,感觉大学很充实,时间也过的很快。唯一让我不爽的就是每年的体质测试了。每次立定跳远和引体向上都是不合格,真的是好伤心💔。好在通过努力,最后还是拿到了60分合格的成绩,但这段经历真的是太痛苦了。

3.工作室会议。跟大家讨论了工作室的看板娘的设计(虽然我们是技术向工作室,但看板娘也很重要啊!),被通知了剩下这段时间的日程安排,跟技术组的朋友们做了交流。虽然工作室远远没有达到我所预期的样子,但好歹是慢慢跑起来了,相信2-3年后,我们会起来的。

4.海底捞聚餐。这个纯属自己糊逼,跟舍友夸下海口说拿到鹅厂offer就请大伙吃海底捞。自己作孽啊,吃饭钱包👛在滴血🩸,QAQ。(不过海底捞的服务真的好好啊!)

本周计划

  1. 软件设计师考试
  2. 参加组织的换届大会
  3. 继续学习基础知识
  4. 继续准备雅思

实施情况

软考就要在本周六(5.29)进行考试,正在紧张的进行准备。目前感觉选择题应该是有把握拿到合格✅的,但下午的案例题,说实话还没个底。继续加油准备吧!今天是周三了,利用今天,明天,后天,不到3天的时间,用心准备一下,我相信还是能够通过的。

一年一度的换届大会又来了,虽然会占用晚上的时间,但感觉作为组织的一份子,还是不要缺席的比较好,去合影留个纪念,毕竟是作为在校的一段记忆,还是要珍重的。

继续学习前端的基础知识并且了解相关项目的实践。比如React Native,lowcode可视化编程的落地实施等方面的信息和知识。

继续准备雅思,原计划是6月中,6月底进行二战雅思的。但可惜计划赶不上变化,5月底软考,6月中六级,6月中下期末考,6月底要去租房子。整个6月的行程被安排的满满当当的,因此还是计划9月或者10月二战雅思(期盼这一次能一步到位到6.5分😂)。

结尾

希望在接下来的考试中能够取得一个出色的成绩吧!加油!

为什么图片转Base64会多出30%的数据量

背景

由于最近在准备🐧厂的面试,被问及是否知道为什么url-loader将图片转换成Base64后,会有增加33%的数据量。因此,我开始从晚上搜集这方面的资料,但遗憾的是,大多的博文的关注点基本都是在实际应用(Webpack,前端优化…)或者是Base64如何进行编码,没有很清晰的阐述为什么会多出33%的数据量的过程和原因。因此,我希望可以通过这篇博文补充这方面的讯息。

为什么会多出30%的数据

当我们把3个Byte的数据转换成为Base64的字符时,根据Base64的规则,3个Byte的字符会转换成24个二进制位。Base64一位只有6个位二进制位,因此会产生4个Byte的字符。

但是现代计算机系统当中,一个字符要有8个二进制位来存储因此,4个字符对应的6个二进制位都要补充2个0,来转换成8个二进制位的字符存储到计算机当中。因此3个Byte(24位二进制位)的数据要用4个Byte(32位二进制位)来存储。并且32位中只有24位是用来存储数据的,剩下8位都是无用的补充位。

因此我们可以很简单的计算出输出:输入 = 4:3 (33% 数据冗余). 与此同时,我们同样可以总结出,输入n Bytes,输出就有(下图)那么长。

{\textstyle 4\left\lceil {\frac {n}{3}}\right\rceil }

总结

核心思路,原来三个Byte的数据,转换成Base64后,要用四个Byte来存储。多了1/3(33%)的数据要存储,所以数据量会增多。

把照片打包进bundle.js中,看来还是要因地制宜的。url-loader默认数值应该是8192bit(1024 byte),增大33%后就是增加了300byte。因此,url-loader主要还是用于打包只有几个像素的小文件比较适合。不会对整体的加载速度有过多的影响。

引用

https://en.wikipedia.org/wiki/Base64

http://www.ruanyifeng.com/blog/2008/06/base64.html