机器学习实战-学习笔记之KNN-手写数据识别
<机器学习实战>学习笔记之KNN-手写数据识别
<机器学习实战>学习笔记之KNN-手写数据识别
工厂模式 针对接口编程,可以隔离掉以后系统可能发生的一大堆改变 为了让系统有弹性,我们希望一个类是抽象类或接口.但如果这样,这些类或接口就无法直接实例化 根据类的类型,我们实例化正确的具体类,然后返回具体类的对象,这些具体类必须实现抽象类接口 但是压力来自于增加更多的具体类类型 把创建对象的代码从具体方法中抽离,把创建的过程搬到另一个对象中,这个对象只管如何创建对象. 我们称这个对象为工厂,现在我们就来实现一个披萨工厂 简单工厂模式 创建对象的过程在工厂类中 /** * 简单工厂 * 披萨工厂类 */publicclassSimplePizzaFactory { /** * 首先,在这个工厂类定义一个createPizza()方法,所有客户使用这个方法来实例化对象 * @param type:披萨类型 * @return Pizza */public Pizza createPizza(String type){ Pizza pizza=null; if(type.equals("cheese")){ pizza=new CheesePizza(); }elseif(type.equals("pepperoni")){ pizza=new Pepperoni(); } return pizza; } } 工厂方法模式 工厂方法用来处理对象的创建,并将这样的行为封装在子类中.这样,客户程序中关于超类的代码就和子类对象创建代码解耦了.工厂方法可能需要参数,也可能不需要. abstract Product factoryMethod(String type) abstract:工厂方法是抽象的 Product:工厂方法必须返回一个产品.超类中定义的方法,通常使用工厂方法的返回值 factoryMethod:工厂方法将客户(也就是超类中的代码,列入orderPizza())和实际创建具体产品的代码分割开来 type:工厂方法可能需要/不需要参数来制定所要的产品 项目地址 java设计模式实现 如果觉得有点收获,记得在项目上点star哦!
观察者模式(Observer) 让你的对象知悉现况 使用自定义的Subject(主题)与Observer(观察者模式) 设计原则 找出程序中会变化的方面,然后将其和固定不变的部分分离 在观察者模式中,会改变的事主题的状态,以及观察者的数目和类型.用这个模式,你可以改变依赖于主题状态的对象,却不改变主题.这就叫提前规划 针对接口编程,不针对实现编程 主题与观察者都使用接口:观察者利用主题的接口向主题注册,二主题利用观察者接口通知观察者.这样可以让两者之前运作正常,同时具有松耦合的优点 多用组合,少用继承 观察者模式利用"组合"将许多观察者组合进主题中.对象之前的这种关系不是通过继承产生的,而是在运行时利用组合的方式而产生的. 自己实现观察者模式 我们先定义主题接口 /** * 主题接口 */publicinterfaceSubject { publicvoidregisterObserver(Observer o); publicvoidremoveObserver(Observer o); publicvoidnotifyObservers(); } 定义观察者接口 /** * 观察者接口 */publicinterfaceObserver { publicvoidupdate(float temp,float humidity,float pressure); } 显示元素接口 /** * 显示元素接口 */publicinterfaceDisplayElement { publicvoiddisplay(); } 编写公告板实现,实现了观察者接口与显示元素接口 /** * 公告板实现 */publicclassCurrentConditionDisplayimplementsObserver,DisplayElement { privatefloat temperature; privatefloat humidity; private Subject weatherData; /** * 构造器需要weatherData对象(也就是主题)作为注册之用 * @param weatherData:天气对象 */publicCurrentConditionDisplay(Subject weatherData){ this.weatherData=weatherData; weatherData.registerObserver(this); } /** * display()方法就只是把最近的问的和湿度显示出来 */@Override publicvoiddisplay() { System.out.println("Current conditions:"+temperature+"F degree and "+humidity+"% humidity"); } /** * 当update被调用时,我们把温度和湿度保存起来,然后调用display * @param temp * @param humidity * @param pressure */@Override publicvoidupdate(float temp,float humidity,float pressure) { this.temperature=temp; this.humidity=humidity; display(); } } 天气数据实现主题接口 import java.util.ArrayList; /** * 天气数据类实现了Subject(主题)接口 */publicclassWeatherDataimplementsSubject { private ArrayList<Observer> observers; privatefloat temperature; privatefloat humidity; privatefloat pressure; publicWeatherData(){ observers=new ArrayList<>(); } @Override publicvoidregisterObserver(Observer o) { observers.add(o); } @Override publicvoidremoveObserver(Observer o) { int i=observers.indexOf(o); if(i>=0){ observers.remove(i); } } @Override publicvoidnotifyObservers() { for (Observer observer : observers) { observer.update(temperature, humidity, pressure); } } /** * 此方法会在气象值变化时被调用 */publicvoidmeasurementsChanged(){ notifyObservers(); } publicvoidsetMeasurements(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } } 来个测试吧 publicclass WeatherStation { publicstaticvoidmain(String[] args){ WeatherData weatherData=new WeatherData(); CurrentConditionDisplay currentConditionDisplay=new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(80,65,30.4f); } } #输出 Current conditions:80.0F degree and 65.0% humidity 使用java自带的Observer 定义显示元素接口 package Observable; publicinterfaceDisplayElement { publicvoiddisplay(); } 实现观察者接口和显示元素接口 package Observable; import java.util.Observable; import java.util.Observer; /** * 天气状况布告板 * Created by jimersylee on */publicclassCurrentConditionDisplayimplementsObserver,DisplayElement { Observable observable; privatefloat temperature; privatefloat humidity; publicCurrentConditionDisplay(Observable observable){ this.observable=observable; observable.addObserver(this); } publicvoidupdate(Observable obs,Object arg){ if(obsinstanceof WeatherData){ WeatherData weatherData=(WeatherData)obs; this.temperature=weatherData.getTemperature(); this.humidity=weatherData.getHumidity(); display(); } } publicvoiddisplay(){ System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity"); } } 实现观察者抽象类 package Observable; import java.util.Observable; /** * 使用java.util内置的观察者模式实现 * Created by jimersylee */publicclassWeatherDataextendsObservable { privatefloat temperature; privatefloat humidity; privatefloat pressure; publicWeatherData(){ } publicvoidmeasurementsChanged(){ setChanged(); notifyObservers(); } publicfloatgetTemperature(){ return temperature; } publicfloatgetHumidity(){ return humidity; } publicfloatgetPressure(){ return pressure; } publicvoidsetMeasurements(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } } 写个测试吧 package Observable; publicclass WeatherStation { publicstaticvoidmain(String[] args){ WeatherData weatherData=new WeatherData(); CurrentConditionDisplay currentConditionDisplay=new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(80,30,33.2f); } } #输出 Current conditions:80.0F degrees and 30.0% humidity 项目地址 java设计模式实现 如果觉得有点收获,记得在项目上点star哦!
软件开发的一个不变真理 不变的就是变化 驱动改变的因素很多.找出你的应用中需要改变代码的原因 用户需要新的功能 需要推出新的活动 应用改版 为了更好的性能 继承不能很好的解决问题,因为对象的行为在子类里不断地改变,并且让所有子类都有这些行为是不恰当的. 使用Fooable等接口,只用能实现的类才继承Fooable接口,但是java接口不具有实现代码,所以继承接口无法达到代码的复用. 引出一个设计原则 找出应用中可能需要变化之处,把它独立出来,不要和那些不需要变化的代码混在一起 设计原则 针对接口编程,而不是针对实现编程 假设有很多鸭子,有真鸭,模型鸭,如何实现他们的行为呢? 先定义个一个抽象的Duck类 /** * 鸭子的抽象类 */publicabstractclassDuck{ private String _headColor="yellow";//Duck对象必备的属性public Stringget_headColor() { return _headColor; } publicvoidset_headColor(String _headColor) { this._headColor = _headColor; } public IFlyBehavior flyBehavior;//为行为接口类型声明引用变量,所有鸭子子类都继承他们public IFlyBehaviorgetFlyBehavior() { return flyBehavior; } publicvoidsetFlyBehavior(IFlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public IQuackBehaviorgetQuackBehavior() { return quackBehavior; } publicvoidsetQuackBehavior(IQuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public IQuackBehavior quackBehavior;//同上publicDuck(){ } publicvoidperformQuack(){ quackBehavior.quack();//委托给行为类 } publicvoidperformFly(){ flyBehavior.fly();//委托给行为类 } publicabstractvoiddisplay(); /** * Duck必备的行为 */publicvoidswim(){ System.out.println("All ducks float,even decoys!"); } } 绿头鸭继承Duck /** * 绿头鸭类 */publicclassMallardDuckextendsDuck { publicMallardDuck(){ quackBehavior=new Quack();//绿头鸭使用Quack类处理叫,所以当performQuack()被调用时,叫的职责被委托给Quack flyBehavior=new FlyWithWings();//同理 } publicvoiddisplay(){ System.out.println("I'm a real Mallard duck"); } } 模型鸭 /* * 模型鸭 */publicclassModelDuckextendsDuck { publicModelDuck(){ flyBehavior=new FlyNoWay();//一开始,模型鸭不会飞 quackBehavior=new Quack();//一开始,模型鸭会呱呱叫 } @Override publicvoiddisplay() { } } 鸭子的鸣叫行为接口类 /** * 叫行为接口类 */publicinterfaceIQuackBehavior{ publicvoidquack(); } 鸭子的飞行行为接口类 /** * 飞行行为接口类 */publicinterfaceIFlyBehavior{ publicvoidfly(); } 各种实现了飞行行为的实现类 /** * 这是飞行行为的实现,给真会飞的鸭子用 */publicclassFlyWithWingsimplementsIFlyBehavior { @Override publicvoidfly() { System.out.println("fly with wings"); } } /** * 火箭动力的飞行行为 */publicclassFlyWithRocketimplementsIFlyBehavior { @Override publicvoidfly() { System.out.println("I'm flying with a rocket!"); } } /** * 这是飞行行为的实现,给不会飞的鸭子用 */publicclassFlyNoWayimplementsIFlyBehavior { @Override publicvoidfly() { System.out.println("I can't fly!"); } } 各种实现了鸣叫行为的实现类 /** * 叫的实现,给会呱呱叫的鸭子用 */publicclassQuackimplementsIQuackBehavior { @Override publicvoidquack() { System.out.println("Quack,gua gua gua!"); } } /** * 鸭子叫的沉默实现,给不会叫的鸭子用 */publicclassQuackMuteimplementsIQuackBehavior { @Override publicvoidquack() { System.out.println("<<Silence>>"); } } 测试我们的鸭子们 publicclassTest { publicstatic void main(String args[]){ MallardDuck mallardDuck=new MallardDuck(); mallardDuck.display(); mallardDuck.performFly(); mallardDuck.performQuack(); //搞一只模型鸭 ModelDuck md=new ModelDuck(); md.performFly();//第一次调用飞行时,委托给FlyNoWay md.setFlyBehavior(new FlyWithRocket());//继承来的设置飞行模式的方法,给予火箭动力 md.performFly();//现在能飞啦~ } } //输出 Bobble gobble I'm flying a short distance gua!gua!gua! I'm flying a long distance Bobble gobble I'm flying a short distance I'm flying a short distance I'm flying a short distance I'm flying a short distance I'm flying a short distance 项目地址 java设计模式实现 如果觉得有点收获,记得在项目上点star哦!
文件和目录: # cd /home 进入 '/home' 目录 # cd .. 返回上一级目录 # cd ../.. 返回上两级目录 # cd - 返回上次所在目录 # cp file1 file2 将file1复制为file2 # cp -a dir1 dir2 复制一个目录 # cp -a /tmp/dir1 . 复制一个目录到当前工作目录(.代表当前目录) # ls 查看目录中的文件 # ls -a 显示隐藏文件 # ls -l 显示详细信息 # ls -lrt 按时间显示文件(l表示详细列表,r表示反向排序,t表示按时间排序) # pwd 显示工作路径 # mkdir dir1 创建 'dir1' 目录 # mkdir dir1 dir2 同时创建两个目录 # mkdir -p /tmp/dir1/dir2 创建一个目录树 # mv dir1 dir2 移动/重命名一个目录 # rm -f file1 删除 'file1' # rm -rf dir1 删除 'dir1' 目录及其子目录内容 查看文件内容: # cat file1 从第一个字节开始正向查看文件的内容 # head -2 file1 查看一个文件的前两行 # more file1 查看一个长文件的内容 # tac file1 从最后一行开始反向查看一个文件的内容 # tail -3 file1 查看一个文件的最后三行 文本处理: # grep str /tmp/test 在文件 '/tmp/test' 中查找 "str" # grep ^str /tmp/test 在文件 '/tmp/test' 中查找以 "str" 开始的行 # grep [0-9] /tmp/test 查找 '/tmp/test' 文件中所有包含数字的行 # grep str -r /tmp/* 在目录 '/tmp' 及其子目录中查找 "str" # diff file1 file2 找出两个文件的不同处 # sdiff file1 file2 以对比的方式显示两个文件的不同 查找: # find / -name file1 从 '/' 开始进入根文件系统查找文件和目录 # find / -user user1 查找属于用户 'user1' 的文件和目录 # find /home/user1 -name \*.bin 在目录 '/ home/user1' 中查找以 '.bin' 结尾的文件 # find /usr/bin -type f -atime +100 查找在过去100天内未被使用过的执行文件 # find /usr/bin -type f -mtime -10 查找在10天内被创建或者修改过的文件 # locate \*.ps 寻找以 '.ps' 结尾的文件,先运行 'updatedb' 命令 # find -name '*.[ch]' | xargs grep -E 'expr' 在当前目录及其子目录所有.c和.h文件中查找 'expr' # find -type f -print0 | xargs -r0 grep -F 'expr' 在当前目录及其子目录的常规文件中查找 'expr' # find -maxdepth 1 -type f | xargs grep -F 'expr' 在当前目录中查找 'expr' 压缩和解压: # bzip2 file1 压缩 file1 # bunzip2 file1.bz2 解压 file1.bz2 # gzip file1 压缩 file1 # gzip -9 file1 最大程度压缩 file1 # gunzip file1.gz 解压 file1.gz # tar -cvf archive.tar file1 把file1打包成 archive.tar (-c: 建立压缩档案;-v: 显示所有过程;-f: 使用档案名字,是必须的,是最后一个参数) # tar -cvf archive.tar file1 dir1 把 file1,dir1 打包成 archive.tar # tar -tf archive.tar 显示一个包中的内容 # tar -xvf archive.tar 释放一个包 # tar -xvf archive.tar -C /tmp 把压缩包释放到 /tmp目录下 # zip file1.zip file1 创建一个zip格式的压缩包 # zip -r file1.zip file1 dir1 把文件和目录压缩成一个zip格式的压缩包 # unzip file1.zip 解压一个zip格式的压缩包到当前目录 # unzip test.zip -d /tmp/ 解压一个zip格式的压缩包到 /tmp 目录 yum工具: # yum -y install [package] 下载并安装一个rpm包 # yum localinstall [package.rpm] 安装一个rpm包,使用你自己的软件仓库解决所有依赖关系 # yum -y update 更新当前系统中安装的所有rpm包 # yum update [package] 更新一个rpm包 # yum remove [package] 删除一个rpm包 # yum list 列出当前系统中安装的所有包 # yum search [package] 在rpm仓库中搜寻软件包 # yum clean [package] 清除缓存目录(/var/cache/yum)下的软件包 # yum clean headers 删除所有头文件 # yum clean all 删除所有缓存的包和头文件 网络: # ifconfig eth0 显示一个以太网卡的配置 # ifconfig eth0 192.168.1.1 netmask 255.255.255.0 配置网卡的IP地址 # ifdown eth0 禁用 'eth0' 网络设备 # ifup eth0 启用 'eth0' 网络设备 # iwconfig eth1 显示一个无线网卡的配置 # iwlist scan 显示无线网络 # ip addr show 显示网卡的IP地址 其他: # su - 切换到root权限(与su有区别) # shutdown -h now 关机 # shutdown -r now 重启 # top 罗列使用CPU资源最多的linux任务 (输入q退出) # pstree 以树状图显示程序 # man ping 查看参考手册(例如ping 命令) # passwd 修改密码 # df -h 显示磁盘的使用情况 # cal -3 显示前一个月,当前月以及下一个月的月历 # cal 10 1988 显示指定月,年的月历 # date --date '1970-01-01 UTC 1427888888 seconds' 把一相对于1970-01-01 00:00的秒数转换成时间 Ctrl + u 删除光标之前到行首的字符 Ctrl + k 删除光标之前到行尾的字符 Ctrl + c 取消当前行输入的命令,相当于Ctrl + Break Ctrl + a 光标移动到行首(ahead of line),相当于通常的Home键 Ctrl + e 光标移动到行尾(end of line) Ctrl + f 光标向前(forward)移动一个字符位置 Ctrl + b 光标往回(backward)移动一个字符位置 Ctrl + l 清屏,相当于执行clear命令 Ctrl + r 显示:号提示,根据用户输入查找相关历史命令(reverse-i-search) Ctrl + w 删除从光标位置前到当前所处单词(word)的开头 Ctrl + t 交换光标位置前的两个字符 Ctrl + y 粘贴最后一次被删除的单词 Ctrl + Alt + d 显示桌面 Alt + b 光标往回(backward)移动到前一个单词 Alt + d 删除从光标位置到当前所处单词的末尾 Alt + F2 运行 Alt + F4 关闭当前窗口 Alt + F9 最小化当前窗口 Alt + F10 最大化当前窗口 Alt + Tab 切换窗口 Alt +按住左键 移动窗口(或在最下面的任务栏滚动鼠标滑轮) [鼠标中间键] 粘贴突出显示的文本。使用鼠标左键来选择文本。把光标指向想粘贴文本的地方。点击鼠标中间键来粘贴。 [Tab] 命令行自动补全。使用 shell 提示时可使用这一方式。键入命令或文件名的前几个字符,然后按 [Tab] 键,它会自动补全命令或显示匹配键入字符的所有命令。 在桌面或文件管理器中直接按 / 就可以输入位置,打开文件管理器。 快速搜索:在 vi 或 Firefox 中直接按 / 即可进入搜索状态。 网站链接和图片可直接拖放到桌面或者目录,可以马上下载。 直接将文件管理器中的文件拖到终端中就可以在终端中得到完整的路径名。 在滚动条的空白处点击鼠标中键,屏幕即滚动到那个地方。
安装了一个新的app 叫微习惯 督促自己每天都做一些事 今天努力完成了所有小事 就差一个30分钟的写作了 于是现在在写 每做完一件事然后打勾 还是很有成就感的 父母在我很小的时候就教育我 说人生最难的就是坚持 小时候不以为意 现在明白了 人都是倾向于虎头蛇尾的 坚持的确是件最难的事 但是 我希望可以改变 可以从一个个的小习惯开始 改变自己 加油 明天早点起床
七月二十三日, 晴,好热 于是去游泳。 一个人,一条裤衩,不戴泳镜,更不需要救生圈。 地点是泄洪坝底下下冲刷而成的水潭,虽没有桃花潭水深千尺,但是十尺还是有的。前几日连绵大雨,所以泄洪了,于是水潭中都是新鲜的水库水,经过水的冲刷,现在水底很清澈,可以直接看到水底。也没有水藻。非常适合游泳呐。 在靠近岸边的地方下水,岸边还是很浅的,踩着圆润的水底砂石,仿佛有种回到童年的感觉。那个瘦瘦小小的小孩,双手撑在河底,双脚扑腾着学习游泳的小孩。嘴巴进水,鼻子进水,咳嗽,鼻酸,长时间潜水后强烈想要呼吸的感觉,潜到深处胸腔感受到的压力,以及水中唯一听得到的隆隆声,虽历历在目,声声在耳,却是多久没感受过了。 自由泳,蛙泳,仰泳,潜泳,狗刨式,全部来一套。原来游泳这个技能,一旦学会,就完全不会忘呢。什么学会呢,先天技能,幼时就在子宫里游来游去。 水底的世界就像是近视眼看到的世界一样,模糊,但是色彩斑斓。尤其对白色的物体尤为敏感。白色的石头,闪着光。随意潜入水中,就可以捞起一些石头,这是幼时最喜爱的游泳游戏。可是现在,却没有幼时的欣喜。
理解Linux系统负荷load average Update time: July 21, 2022 10:27 AM 一、查看系统负荷 如果你的电脑很慢,你或许想查看一下,它的工作量是否太大了。 在Linux系统中,我们一般使用uptime命令查看(w命令和top命令也行)。(另外,它们在苹果公司的Mac电脑上也适用。) 你在终端窗口键入uptime,系统会返回一行信息。 这行信息的后半部分,显示"load average",它的意思是"系统的平均负荷",里面有三个数字,我们可以从中判断系统负荷是大还是小。 为什么会有三个数字呢?你从手册中查到,它们的意思分别是1分钟、5分钟、15分钟内系统的平均负荷。 如果你继续看手册,它还会告诉你,当CPU完全空闲的时候,平均负荷为0;当CPU工作量饱和的时候,平均负荷为1。 那么很显然,“load average"的值越低,比如等于0.2或0.3,就说明电脑的工作量越小,系统负荷比较轻。 但是,什么时候能看出系统负荷比较重呢?等于1的时候,还是等于0.5或等于1.5的时候?如果1分钟、5分钟、15分钟三个值不一样,怎么办? 二、一个类比 判断系统负荷是否过重,必须理解load average的真正含义。下面,我根据"Understanding Linux CPU Load"这篇文章,尝试用最通俗的语言,解释这个问题。 首先,假设最简单的情况,你的电脑只有一个CPU,所有的运算都必须由这个CPU来完成。 那么,我们不妨把这个CPU想象成一座大桥,桥上只有一根车道,所有车辆都必须从这根车道上通过。(很显然,这座桥只能单向通行。) 系统负荷为0,意味着大桥上一辆车也没有。 系统负荷为0.5,意味着大桥一半的路段有车。 系统负荷为1.0,意味着大桥的所有路段都有车,也就是说大桥已经"满"了。但是必须注意的是,直到此时大桥还是能顺畅通行的。 系统负荷为1.7,意味着车辆太多了,大桥已经被占满了(100%),后面等着上桥的车辆为桥面车辆的70%。以此类推,系统负荷2.0,意味着等待上桥的车辆与桥面的车辆一样多;系统负荷3.0,意味着等待上桥的车辆是桥面车辆的2倍。总之,当系统负荷大于1,后面的车辆就必须等待了;系统负荷越大,过桥就必须等得越久。 CPU的系统负荷,基本上等同于上面的类比。大桥的通行能力,就是CPU的最大工作量;桥梁上的车辆,就是一个个等待CPU处理的进程(process)。 如果CPU每分钟最多处理100个进程,那么系统负荷0.2,意味着CPU在这1分钟里只处理20个进程;系统负荷1.0,意味着CPU在这1分钟里正好处理100个进程;系统负荷1.7,意味着除了CPU正在处理的100个进程以外,还有70个进程正排队等着CPU处理。 为了电脑顺畅运行,系统负荷最好不要超过1.0,这样就没有进程需要等待了,所有进程都能第一时间得到处理。很显然,1.0是一个关键值,超过这个值,系统就不在最佳状态了,你要动手干预了。 三、系统负荷的经验法则 1.0是系统负荷的理想值吗? 不一定,系统管理员往往会留一点余地,当这个值达到0.7,就应当引起注意了。经验法则是这样的: 当系统负荷持续大于0.7,你必须开始调查了,问题出在哪里,防止情况恶化。 当系统负荷持续大于1.0,你必须动手寻找解决办法,把这个值降下来。 当系统负荷达到5.0,就表明你的系统有很严重的问题,长时间没有响应,或者接近死机了。你不应该让系统达到这个值。 四、多处理器 上面,我们假设你的电脑只有1个CPU。如果你的电脑装了2个CPU,会发生什么情况呢? 2个CPU,意味着电脑的处理能力翻了一倍,能够同时处理的进程数量也翻了一倍。 还是用大桥来类比,两个CPU就意味着大桥有两根车道了,通车能力翻倍了。 所以,2个CPU表明系统负荷可以达到2.0,此时每个CPU都达到100%的工作量。推广开来,n个CPU的电脑,可接受的系统负荷最大为n.0。 五、多核处理器 芯片厂商往往在一个CPU内部,包含多个CPU核心,这被称为多核CPU。 在系统负荷方面,多核CPU与多CPU效果类似,所以考虑系统负荷的时候,必须考虑这台电脑有几个CPU、每个CPU有几个核心。然后,把系统负荷除以总的核心数,只要每个核心的负荷不超过1.0,就表明电脑正常运行。 怎么知道电脑有多少个CPU核心呢? “cat /proc/cpuinfo"命令,可以查看CPU信息。“grep -c ‘model name’ /proc/cpuinfo"命令,直接返回CPU的总核心数。 六、最佳观察时长 最后一个问题,“load average"一共返回三个平均值—-1分钟系统负荷、5分钟系统负荷,15分钟系统负荷,—-应该参考哪个值? 如果只有1分钟的系统负荷大于1.0,其他两个时间段都小于1.0,这表明只是暂时现象,问题不大。 如果15分钟内,平均系统负荷大于1.0(调整CPU核心数之后),表明问题持续存在,不是暂时现象。所以,你应该主要观察"15分钟系统负荷”,将它作为电脑正常运行的指标。
环境:CentOS7 1.下载安装包 在https://jenkins.io/download/找到相应的包下载地址 wget https://pkg.jenkins.io/redhat/jenkins-2.76-1.1.noarch.rpm 2.安装包 sudo rpm -i jenkins-2.76-1.1.noarch.rpm 3.启动jenkins sudo service jenkins start 4.配置nginx vim /etc/nginx/conf.d/jenkins.conf server { 2listen 443; 3 server_name jenkins.jimersylee.com; 4 ssl on; 5 ssl_certificate /data/ssl_cert/Nginx/1_jimersylee.com_bundle.crt; 6 ssl_certificate_key /data/ssl_cert/Nginx/2_jimersylee.com.key; 7 ssl_session_timeout 5m; 8 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;#按照这个协议配置9 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置10 ssl_prefer_server_ciphers on; 11# root /data/www/www;12 13indexindex.htmlindex.htmindex.php; 14 location / 15 { 16 proxy_pass http://127.0.0.1:8080; 17 } 18 19 access_log /data/logs/jenkins/jenkins.log main; 20 } 21 22 server { 23listen 80; 24 server_name jenkins.jimersylee.com; 25 rewrite ^ https://$server_name$request_uri? permanent; 26 } 5.访问https://jenkins.jimersylee.com/ 发现没有账号密码,修改jenkins为不需要账号密码 ...
前言 近期,阅读了<谷歌的软件工程>,记录一下. 我对谷歌这家公司还是比较好奇和欣赏的,不管都是对于拉里佩奇,还是现在阿尔法特(谷歌母公司)的CEO 桑达尔·皮查伊, 个人都非常敬佩.毕竟都是有真正实力的大佬. 谷歌运行着目前世界上最大的服务器集群,这个不容置疑.我个人也非常好奇,如此庞大的规模的机器,他们如何调度,如何监控,我们这种小公司是否有可以借鉴的地方.因此,当我发现这本书的时候,我觉得这就是我一直寻找的书. 其实在这之前,我已经看过<Sre google运维解密>,收获良多,我的DevOps概念就是从这本书中学来的.个人在之后的工作中也引入了这套工作流程,砍掉了运维工程师,由开发自己负责从开发部署,持续运维监控的全流程,开发人员反馈良好,接触到了很多之前不可能接触到的生产服务器,积累了宝贵的线上故障处理经验,培养了项目主人公的感觉. 以下为书籍内容的摘抄,仅供参考. 第一章 失败奖励 在谷歌X部门——该部门负责研究自动驾驶汽车和通过热气球提供互联网接入等 “登月计划”——故意将失败次数纳入其激励系统。人们会想出一些稀奇古怪的想法,同事们也会受到积极的鼓励尽快实现它们。每个人都会得到奖励(甚至是竞争),看看他们能在一段固定的时间内反驳或否定多少观点。只有当一个概念真的不能在白板上被所有同行揭穿时,它才能进入早期原型。 无责的事后文化 在谷歌X部门——该部门负责研究自动驾驶汽车和通过热气球提供互联网接入等 “登月计划”——故意将失败次数纳入其激励系统。人们会想出一些稀奇古怪的想法,同事们也会受到积极的鼓励尽快实现它们。每个人都会得到奖励(甚至是竞争),看看他们能在一段固定的时间内反驳或否定多少观点。只有当一个概念真的不能在白板上被所有同行揭穿时,它才能进入早期原型。 谷歌味儿 谷歌最终解决了这个问题,明确定义了我们所说的“谷歌特质”(Googleyness)——我们所寻找的一套属性和行为,代表了强大的领导力,体现了 “谦逊、尊重和信任”: 在模棱两可中茁壮成长 即使在环境不断变化的情况下,也能处理相互冲突的信息或方向,建立共识,并对问题做出改进。 重视反馈 谦虚优雅地接受和给出反馈,理解反馈对个人(和团队)发展的价值。 走出舒适区 能够设定宏伟的目标并去追求,即使有来自他人的抵制或惰性。 客户第一 对谷歌产品的用户抱有同情和尊重,并追求符合其最佳利益的行动。 关心团队 对同事抱有同情心和尊重,并积极主动地帮助他们,提高团队凝聚力。 做正确的事 对自己所做的一切有强烈的主人感;愿意做出困难或不易的决定以保护团队和产品的完整。 每个专家都曾经是菜鸟:一个组织的成功取决于其员工的成长和投入。 离开营地时要比你发现时更干净 如何激励人们记录工作 传统上,鼓励工程师记录他们的工作可能是困难的。编写文档需要消耗编码的时间和精力,而且这些工作所带来的好处并不直接,大部分是由其他人获益的。鉴于许多人可以从少数人的时间中获益,像这样的不对称权衡对整个组织来说是好的,但如果没有好的激励措施,鼓励这样的行为是很有挑战性的。我们在第57页的 “激励和认可 “一节中讨论了其中的一些结构性激励。 奖励方式 工作阶梯的期望是一种自上而下引导文化的方式,但文化也是自下而上形成的。在谷歌,同行奖金计划是我们拥抱自下而上文化的一种方式。同行奖金是一种货币奖励和正式认可,任何谷歌员工都可以将其授予任何其他谷歌员工,以表彰他们的超越性工作。例如,当Ravi将同行奖金发给Julia,因为她是一个邮件列表的顶级贡献者——定期回答问题,使许多读者受益,他公开承认她的知识共享工作及其对团队以外的影响。由于同行奖金是由员工驱动的,而不是由管理层驱动的,因此它们可以产生重要而强大的基层效应。 第三章 知识分享 内容提要 心理安全是培养知识共享环境的基础。 从小事做起:问问题,把事情写下来。 让人们可以很容易地从专家和有记录的参考资料中获得他们需要的帮助。 在系统的层面上,鼓励和奖励那些花时间去教授和扩大他们的专业知识,而不仅仅是他们自己、他们的团队或他们的组织。 没有什么灵丹妙药:增强知识共享文化需要多种策略的结合,而最适合你的组织的确切组合可能会随着时间的推移而改变。 第四章 公平工程 偏见是默认的。 多样性是正确设计综合用户群所必需的。 包容性不仅对于改善代表不足的群体的招聘渠道至关重要,而且对于为所有人提供一个真正支持性的工作环境也至关重要。 产品速度必须根据提供对所有用户真正有用的产品来评估。与其发布一个可能对某些用户造成伤害的产品,还不如放慢速度。 第六章 规模优先 至此,假设我们已经知道了领导的本质,那么到底什么才能让你提升为一个真正优秀的管理者呢?这就是我们这里想要讨论的,我们称之为“管理上的三个总是”:始终保持决断力,始终保持离开,始终保持扩张。 第七章 测试工程效率 如何测量软件过程 在谷歌,我们使用目标/信号/指标(GSM/ goal signal metric)框架来指导指标创建。 目标是一个期望的最终结果。它是根据你希望在高层次上理解的内容来表述的,不应包含对具体测量方法的引用。。 信号是你如何知道你已经实现了最终结果。信号是我们想要衡量的东西,但它们本身可能是不可测量的。 指标是信号的代表。它是我们实际上可以测量的东西。它可能不是理想的测量,但它是我们认为足够接近的东西。 第十章 文档 工程师们越是把文档工作当作软件开发的必要任务之一,他们就越是不反感写文档的前期成本,也就越能获得长期的收益。此外,让文档工作变得更容易,可以减少这些前期成本。 写文档的秘诀 5W,who,what,when. where, why who: 文档受众 what: 确定文档用途的内容 when: 何时确定本文件的创建、审查或更新时间 where: 文档应该放在哪里 why: 设定文件的目的 第十一章 测试概述 GWS的经验告诉我们的一个重要启示是,你不能仅仅依靠程序员的能力来避免产品缺陷。即使每个工程师只是偶尔写一些bug,当你有足够多的人在同一个项目上工作时,你也会被不断增长的缺陷列表所淹没。想象一下,一个假设的100人的团队,其工程师非常优秀,他们每个人每月只写一个bug。而这群了不起的工程师在每个工作日仍然会产生5个新的bug。更糟糕的是,在一个复杂的系统中,修复一个错误往往会导致另一个错误,因为工程师们会适配已知的bug并围绕它们编写代码。 概要 ...