首页 文章 精选 留言 我的

精选列表

搜索[整理],共9145篇文章
优秀的个人博客,低调大师

CentOS下Find命令详解整理

locate 搜索命令 使用: #yuminstall-ymlocate安装 updatedb 生成db数据库,服务器不建议在工作时间生成,使用计划任务在凌晨启动 #find/etc/-name'sshd*'模糊搜索,搜索/etc目录下name为sshd的文件或目录 #find/etc/-typed-name"sshd*"模糊搜索,只搜索/etc目录下name为sshd的目录 #find/etc/-typef-name"sshd*"模糊搜索,只搜索/etc目录下name为sshd的文件 -type l 为连接文件 -type b 为block块设备 #stat 2.txt 查看 2.txt的time状态信息 参数: atime = access time 访问时间 mtime = modify time 创建(修改)时间 ctime = change time 改动时间 更改了文件内容,ctime一定会发生改变 查看文件内容,access会发生改变 实例: #find/etc/-typef-mtime-1 #一天以内/etc目录下修改过的文件 #find/etc/-typef-mtime+1 #一天前的/etc目录下修改过的文件 #find/etc/-typef-mtime+1-name"*.conf" #一天前的/etc目录下名为.conf且修改过的文件 #find/etc/-typef-o-mtime+1-o-name"*.conf" #一天前的/etc目录下名为.conf且修改过的文件如上两个“-o”均是或的意思 #find/etc/-typef-mmin-200 #200分钟以内/etc目录下修改过的文件 #find/etc/-typef-mmin-200-execls-l{}\; #200分钟以内/etc目录下修改过的文件, - exec 是指:执行 ls -l命令, {}表示对列出的结果再次交给 ls 一条条的执行 #find/etc/-typef-mmin-200-execmv{}{}.bak\; #然后对符合条件的文件全部改名为.bak 在日常工作中会用到 find 去查找Size大于多少多少的文件或者目录时 #find/etc/-typef-size-10M-execls-lh{}\; #列出来在/etc目录下类型为文件且大于10M的并ls-lh显示其详细信息

优秀的个人博客,低调大师

CentOS下iptables官方手册整理

目录: 1. 简介 2. 首先,什么是包过滤? 3. 快速入门指南 4. 数据包过滤流程 5. 具体如何使用Iptables命令实现过滤功能 6. 地址转换(NAT) 7. 排除建议 1. 简介 ———————————————————————————————————————————————— 读者们,大家好: 在这里我们假设你已经有一定的IP地址、网络地址、子网掩码、路由、DNS基础知识。如果没有建议你先阅读一下官网的networking-concepts-HOWTO文档。官网地址为:www.netfilter.org 当前我们的网络是不安全的。但问题是我们做网络限制,同时还需要提供快速、便利的网络通讯环境,而不是处于邪恶的目的。网络限制是一把双刃刀,但本文章并非解决这个问题。 所以刀在手如何使用完全取决于你。我相信你会把这些工具用到合理的地方,并能很好地使用这些工具。而不是用于其他目的。 ------------------------------------------------------------------------------------------------ 2. 首先,什么是包过滤? 包过滤是当一个数据包通过时,使用软件去查看包头信息并决定对该包的处理方式。你可以丢弃该数据包、接受该数据包亦或是其他更复杂的处理方式。 在Linux中包过滤已经集成到内核中了,甚至还可以做一些数据包欺骗,但基本原则还是查看数据包头并决定处理方式。 ------------------------------------------------------------------------------------------------ 2.1 为什么我们需要包过滤? 可控性、安全性、可监控性 可控性:当你在局域网中使用Linux连接另一个网络时(如:互联网),你可以允许或拒绝特定类型的数据。例如:数据包都会包含目标地址,这样你就可以防止数据包进入某个特定的网络。再举个例子,我使用浏览器访问某个网站,在该网站上全是广告,此时浏览器会浪费我的时间去下载这些广告信息。这时我可以告知包过滤工具不允许该网站的数据包通过以解决这个问题。 安全性:当你的Linux主机是复杂的互联网与有序的局域网之间的唯一主机时,你可以通过数据包限制让该Linux主机成为局域网与互联网之间的安全大门!比如:你可以会想允许所有的数据包进入互联网,但你会对从外网进来的死亡之ping感到忧虑。再如,你可能不希望有人可以telnet连接你的Linux主机,即使对方有密码也不可以。简单而言就是通过包过滤工具拒绝外网部分数据包进入本地。 可监控性:当有些不正常的数据流量出现时,包过滤工具可以及时通知你是非常不错的注意! ------------------------------------------------------------------------------------------------ 2.2 Linux系统如何过滤数据包 Linux内核从1.1开始就已经有包过滤功能。第一代产品是1994年诞生于BSD系统的ipfw。Linux2.0增强了该功能;用户可以使用ipfwadm控制内核过滤规则。Linux2.2是用户工具变更为ipchains。最后在Linux2.4中用户工具被重写,新的工具为iptables。 你需要一个支持netfilter架构的Linux内核:netfilter是在内核中的过滤架构,而且该架构可以使用插件动态加载。 Linux防火墙主要包括两个部分:一部分为netfilter是内核过滤的基础架构,一部分为iptables是用户工具,用来编辑具体的过滤规则提供给内核netfilter。 IPTABLES:该工具可以添加删除具体的过滤规则至内核包过滤表。这也意味着无论你如何设置防火墙规则,一旦机器重启所有的规则将丢失。 永久保存规则:你设置的防火墙规则被保存在内核中,但重启会丢失。你可以使用iptables-save和iptables-restore脚本实现永久保存与恢复。 备注:Linux防火墙所有的规则被保存在表中,默认Iptables防火墙有4个表:filter表(实现过滤功能),nat表(实现地址转换功能), mangle表(修改数据包的TOS、TTL等信息),raw表(实现数据包跟踪功能) 每个表中有多个数据链,而我们的具体规则被分门别类的链中。以下是每个表中的默认链: filter表:INPUT链(入站数据过滤),FORWARD链(转发数据过滤),OUTPUT链(出站数据过滤) nat表:PREROUTING链,POSTROUTING链,OUTPUT链 mangle表:PREROUTING链,POSTROUTING链,INPUT链,OUTPUT链,FORWARD链 raw表:OUTPUT链,PREROUTING链 ------------------------------------------------------------------------------------------------ 3. 快速入门指南 很多朋友使用单线PPP(拨号)连接互联网,并且不希望任何人访问你的网络,防火墙可以做如下设置。 首先加载过滤功能的模块: #insmod ip_conntrack #insmod ip_conntrack_ftp 以上两天命令也可以使用下面两天命令替换 #modprobe ip_conntrack #modprobe ip_conntrack_ftp 其次添加具体规则: # iptables -N block 新建规则链 # iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT 允许出站数据包的回应信息 # iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT 允许出站数据(自己可以访问外网) # iptables -A block -j DROP 其余数据包全部丢弃 # iptables -A INPUT -j block 入站数据时读取block链中的过滤规则 # iptables -A FORWARD -j block 转发数据时读取block链中的过滤规则 ------------------------------------------------------------------------------------------------ 4. 数据包过滤流程 内核的过滤表默认有三个链(链中具体存放过滤规则):INPUT,OUTPUT,FORWARD。 _____ Incoming / \ Outgoing -->[Routing ]--->|FORWARD|-------> [Decision] \_____/ ^ | | v ____ ___ / \ / \ |OUTPUT| |INPUT| \____/ \___/ ^ | | ----> Local Process ---- 三个圈中表示上面的三个链,当数据包到达上图中的某个圈中时,链即刻根据规则判断数据包的处理方式,如果链中的某个规则说丢弃该包,该数据包将立即被丢弃;如果链中规则说接受,则数据包继续向后传输。 每个链中包含有具体的规则,每个规则具体明确说明:什么数据包头信息做怎样的处理,如果你的数据包没有匹配第一个规则,则继续对比下一条规则。最后如果没有规则与你的数据包匹配,内核将读取链的默认规则。出于安全的考虑,默认规则一般会被设置为丢弃(DROP)。 1.数据包过来时内核先查看目标地址:这一步被称为路由。 2.如果该数据是发往本地的,则继续向下传递至INPUT链,当INPUT链允许该数据包,数据包进入本机等待程序接受数据。 3.否则,如果内核未开启数据转发功能,被转发的数据包将被直接丢弃,如果内核开启了数据转发功能,该数据包将传递给FORWARD链以转发数据,数据进入目标网络接口(网卡接口);此时如果 FORWARD链允许数据包通过,该数据包继续向后传递。 4.最后在本机的一个程序发送网络数据包时,数据包会立刻进入OUPUT链,根据具体规则决定允许或拒绝发送出去。 ------------------------------------------------------------------------------------------------ 5. 具体如何使用Iptables命令实现过滤功能 iptables有非常详尽的手册文档(man iptalbes),以下是iptables可以实现的几种不同的操作,我们从filter过滤表开始。 1. 创建新的自定义链 -N 2. 删除自定义链 -X 3. 改变默认策略 -P 4. 显示链规则 -L 5. 清空链中的规则 -F 6. 将包过滤统计信息清零 -Z 如果在链中维护具体规则: 1. 追加新的规则 -A 2. 插入新的规则 -I 3. 替换旧的规则 -R 4. 删除旧的规则 -D ------------------------------------------------------------------------------------------------ 5.1 操作单条规则 这是最基本的包过滤操作。通常你需要使用-A或-D命令选项,有时你还会使用到-I与-R命令选项。 每条规则需要指定匹配条件以及匹配后的处理方式(ACCEPT允许,DROP丢弃,REJECT拒绝,LOG日志等),如:你可能希望丢弃素有本地回环(127.0.0.1)的ICMP数据包,这样我们的匹配条件是:ICMP协议并且源地址是127.0.0.1 匹配后做DROP处理。 127.0.0.1是本地回环接口,即使你没有物理网卡,该接口一样存在。你可以使用ping命令产生这类数据包。 # ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=21.9 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 21.966/21.966/21.966/0.000 ms # iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP 添加一条规则 # ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes --- 127.0.0.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss 你可以看到第一次ping是成功的(-c 1 说明仅ping一次),然后我们追加了一条规则到INPUT链,该规则指定从127.0.0.1发送的ICMP协议的数据包将被丢弃。第二次再执行ping命令所有的数据100%丢失。 我们有两种方式可以删除规则,首先我们知道INPUT链中只有一条规则,我们可以使用编号删除: #iptables -D INPUT 1 删除INPUT链中的第一条规则 第二种方法类似与-A选项,使用-D替换-A。当你的规则比较复杂并搞不清编号时可以使用这种方式: #iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP ------------------------------------------------------------------------------------------------ 5.2 特定过滤规则 上面我们已经看到可以使用-p指定协议,-s指定源地址,但还有很多可以用来过滤的条件匹配符。下面我们分别介绍: 源地址与目标地址 源地址(-s,--source或--src),目标地址(-d,--destination或--dst)有四种使用方式:最常用的是使用名称,比如"localhost"或者"http://www.kernel.org"。第二种方法是使用IP地址如"127.0.0.1"。第三四种方法可以匹配IP地址区域,如"199.95.207.0/24"或"199.95.207.0/255.255.255.0"。它们都可以匹配199.95.207.0到199.95.207地址可以使用0/0匹配所有地址。 # iptables -A INPUT -s 0/0 -j DROP 拒绝所有源地址访问本机 取反匹配 很多标签"-s","-d"等都可以在后面添加"!"以表示否定匹配,如"-s ! localhost"将匹配所有非本地源地址。 协议匹配 匹配协议可以使用-p标签,协议的指定可以使用数字编号(如果你知道协议的编号)或使用名称(如"TCP","UDP","ICMP"等)。协议名称前可以添加"!"如"-p ! TCP"匹配所有非TCP协议数据包。 接口匹配 "-i(--in-interface)"和"-o(--out-interface)"匹配指定的接口。接口是真实的物理网卡接口,-i(数据包从哪个网卡进来的),-o(数据从哪个网卡出去的)。你可以使用ifconfig命令查看哪些接口是开启的。 注意:在INPUT链不可以使用-o选项,因为入站的数据不走出站接口。所以在INPUT链中的-o规则将无法匹配任何数据。 同理,在OUTPUT链中不可以使用-i选项。 数据段匹配 很多数据包因为太大无法一次完成数据的传输。此时数据包将被分割为数据片段再发送出去。接收端接受完数据后将把这些数据片段重新组合成完整的数据包。 但问题在于当数据被分割后,只有前面的初始数据片段包含全部的数据头部信息(IP,TCP,UDP,ICMP等),后续的数据片段仅包含数据包头部信息的一部分信息。这时去再检查后续数据片段的头部信息是不可能的。 当然,如果你想匹配第二个及后面被分片的数据,可以使用"-f"选项。 # iptables -A OUTPUT -f -d 192.168.1.1 -j DROP 丢弃发送至192.168.1.1的所有数据以及分片数据 扩展iptables规则 iptables有很好的可扩展性,也就是说内核架构与iptables工具都可以添加扩展功能。 内核功能扩展一般放在内核模块子目录中:/lib/modules/2.6.32-220.el6.i686/kernel/net/netfilter(这里以CentOS6.2为例)。这些模块在你使用iptables时会自动加载。 mac 该模块需要使用"-m mac"选项启用,这对应过滤进站数据包的源MAC地址很用帮助。 #iptables -I INPUT -m mac --mac-source 00:60:08:91:CC:B7 -j REJECT 拒绝MAC地址为00:60:08:91:CC:B7的数据包进入 limit 该模块需要使用"-m limit"选项启用,该功能对限制网速很有效。 #iptables -A OUTPUT -p tcp -m limit --limit 100/s -j ACCEPT 每秒包个数100以内将允许发送 #iptables -P OUTPUT REJECT 默认拒绝所有 说明:以上两天可以实现,当每秒包个数大于100时,拒绝所有连接。 应用实例 Syn-flood protection: # iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT Furtive port scanner: # iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT Ping of death: # iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT 状态匹配 该模块需要使用"-m state"选项启用,数据包的状态包括:NEW,ESTABLISHED,RELATED,INVALID NEW:创建连接的数据包 ESTABLISHED:通过已经创建的连接通道传输的数据包 RELATED:与已经创建的连接相关的数据包,如ICMP错误数据包 INVALID:无法识别的数据包 #iptables -A INPUT -m state --state NEW -j DROP 拒绝进站的连接请求(外网无法访问本机) #iptables -A INPUT -m state --state RESTABLISHED,RELATED -j ACCEPT 允许外网数据对本机的回应信息 #iptables -P OUTPUT ACCEPT 允许访问外网 ------------------------------------------------------------------------------------------------ 6. 地址转换(NAT) [ ] |>>> [Internet] >>>> (www.google.com) | [ ] v v _______________________ [ eth0:202.106.22.31 ] [ 网关 ] [____eth1:192.168.1.1___] | | v v [ ] >>> (PC:192.168.1.200) [ 交换机 ] >>> (PC:192.168.1.201) [ ] >>> (PC:192.168.1.202) 上图中局域网(192.168.1.0/24)通过交换机与公司网关连通在一起,网关与互联网可以实现通讯。现在我们使用iptables的SNAT功能实现内网所有主机上网。 实现步骤: 1. 开启网关路由功能(路由器就有该功能,如果是Linux软路由可以使用:#echo "1" > /proc/sys/net/ipv4/ip_forward命令开启) 2. 设置iptables的SNAT功能: #iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 202.106.22.31 上图中如果需要实现通过在外网任意主机通过访问公司网关IP地址:202.106.22.31,即可访问位于公司内部192.168.1.200上的Web服务器,我们可以使用iptables的DNAT功能实现。 实现步骤: 1. 开启网关路由功能 2. 设置iptables的DNAT功能: #iptables -t nat -A PREROUTING -i eth0 -d 202.106.22.31 --dport 80 -j DNAT --to-destination 192.168.1.200 7. 排除建议 1.注意过滤规则的顺序,如果规则的第一条拒绝所有tcp连接,第二条允许192.168.1.1访问本机的tcp连接,则第二条将无效。 #iptables -A INPUT -p tcp -j DROP #iptables -A INPUT -p tcp -s 192.168.1.1 -j ACCEPT 以上两条规则由于第一条规则已经丢弃所有的tcp数据包,所以不会再匹配第二条规则。 2.设置完规则后未保存,导致重启后所有规则丢失。解决方法:可以使用iptables-save,或service iptables save实现永久保存 #iptables-save > /etc/sysconfig/iptables #service iptables save 以上以CentOS为例,两天命令任选其一即可永久保存。 3.无效的规则及时删除,否则影响效率。 4.匹配端口号时必须指定协议,否则会报错。 5.公司有FTP服务器时,提前加载ftp模块:#modprobe ip_nat_ftp

优秀的个人博客,低调大师

Activity的生命周期整理

Activity主要的三种状态: Running(运行):在屏幕前台(位于当前任务堆栈的顶部) Paused(暂停):失去焦点但仍然对用户可见(覆盖Activity可能是透明或未完全遮挡) Stopped(停止):完全被另一个Activity覆盖 1. 首次进入一个Activity,会执行 onCreate -> onStart -> onResume 2. 按BACK键 onPause -> onStop -> onDestroy 3. HOME键 Home键退出:onPause -> onStop Home键回来:onRestart -> onStart -> onResume 4. 休眠/恢复 休眠: onPause 恢复: onResume 5. 旋转屏幕 a、 未设置android:configChanges(在AndroidManifest.xml中activity中进行配置): onPause -> onStop -> onDestory -> onCreate -> onStart -> onResume b、设置了android:configChanges="orientation|keyboardHidden":不会触发生命周期方法,但会执行onConfigurationChanged方法。 c、设置了android:configChanges="orientation"结果同b。 6. 来电 来电,显示来电界面: onPause -> onStop 关闭电话界面,重新回到当前Activity: onRestart -> onStart -> onResume 7. 其他Activity 进入下一个Activity: onPause -> onStop 从其他Activity返回至当前Acitivity: onRestart -> onStart -> onResume 本文转自94cool博客园博客,原文链接:http://www.cnblogs.com/94cool/p/3607093.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

docker错误信息整理

1、Error response from daemon: Cannot start container 7cb4a74f9ef7bcc6fa659e3473aac10bd430c18aac43b4f6633920742e159284: iptables failed: iptables -t nat -A DOCKER -p tcp -d 0/0 --dport 5000 -j DNAT --to-destination 192.168.42.8:5000 ! -i docker0: iptables: No chain/target/match by that name. 解决方案:重启docker 2、Docker无法启动 Could not find a free IP address range for interface 'docker0' 最方便的解决办法 2015-09-21 15:44 1294人阅读 评论(0) 收藏 举报 转载自:http://www.bubuko.com/infodetail-969451.html 阿里云的CentOS 6.6上安装Docker会无法启动,如果直接运行docker -d会看到错误提示: WARN[0000] You are running linux kernel version 2.6.32-573.3.1.el6.x86_64, which might be unstable running docker. Please upgrade your kernel to 3.10.0. INFO[0000] [graphdriver] using prior storage driver "devicemapper" INFO[0000] Listening for HTTP on unix (/var/run/docker.sock) WARN[0000] Running modprobe bridge nf_nat failed with message: , error: exit status 1 FATA[0000] Error starting daemon: Error initializing network controller: Error creating default "bridge" network: can't find an address range for interface "docker0" 关于docker进程没起来的原因可能会有很多,比如 模块没加载,系统内核版本过低,硬盘空间不足等等 一开始我以为是系统内核版本过低导致,百度又google了半天,还安装了3.10的内核库,都没用 最后看到有人说,虽然报警建议升级内核到3.10,但意义就是docker宣称在3.10下是stable,低于3.10不是就不能运行了,只是unstable而已,docker的依赖内核需要高于2.6.32就可以 其实本处的重要信息是报错最后一句,原因就是docker自动尝试的建立bridge的ip段正好被阿里云的路由表完全占据了 详细原因可以参见这个帖子:http://hanjianwei.com/2014/07/30/docker-on-aliyun/ 网上有好多类似的解决方法,不过好麻烦,这里主要说下最方便的解决方法 先su到root 找一下docker的配置文件: find / -name "docker" 一般会在 /etc/sysconfig/docker 编辑这个文件 vi /etc/sysconfig/docker 修改other_args=这一行为:other_args=-bip=192.168.100.1/24 保存退出 可以重启docker了 service docker restart 3、docker不能启动容器,报一下错误Error running DeviceCreate (createSnapDevice) dm_task_run failed 1) service docker stop 2) thin_check /home/docker/devicemapper/devicemapper/metadata 3) thin_check --clear-needs-check-flag /home/docker/devicemapper/devicemapper/metadata 4) service docker start Edit: –clear-needs-check-flag should be --clear-needs-check-flag . Minor but important. 4、重启docker服务器后 遇到 'device or resource busy'错误 如果有container在运行的时候重启 docker 服务, 可能会导致 container无法启动, 错误信息类似于 [plain] view plain copy print?在CODE上查看代码片派生到我的代码片 Error response from daemon: Cannot start container zookeeper: Error getting container ddf1dd91bbf46dc648268327f8f7c6fffaf2f19cda5cf1d97fdc701016d4332c from driver devicemapper: Error mounting '/dev/mapper/docker-8:1-525372-ddf1dd91bbf46dc648268327f8f7c6fffaf2f19cda5cf1d97fdc701016d4332c' on '/var/lib/docker/devicemapper/mnt/ddf1dd91bbf46dc648268327f8f7c6fffaf2f19cda5cf1d97fdc701016d4332c': device or resource busy 2015/01/26 04:42:07 Error: failed to start one or more containers 或者 [plain] view plain copy print?在CODE上查看代码片派生到我的代码片 d2859bd1f84b: Error pulling image (latest) from xxxxxx, Driver devicemapper failed to create image rootfs e6158e7962db43274de40fc3db65ad64811d43fe342dea633df20639f5a4e3cd: device e6158e7962db43274de40fc3db65ad64811d43fe342dea633df20639f5a4e3cd already exists 43fe342dea633df20639f5a4e3cd already exists c049b2b: Download complete e6158e7962db: Error downloading dependent layers 这是一个Docker的 bug 解决方式是先找出没有umount的路径 cat /proc/mounts | grep "mapper/docker" | awk '{print $2}' 然后依次unmount 5、挂载宿主机目录后,在容器内对其进行操作,报“Permission denied”。 可通过两种方式解决: 1> 关闭selinux。 临时关闭:# setenforce 0 永久关闭:修改/etc/sysconfig/selinux文件,将SELINUX的值设置为disabled。 2> 以特权方式启动容器 指定--privileged参数 如:# docker run -it --privileged -v /test:/soft centos /bin/bash 本文转自aaron428 51CTO博客,原文链接:http://blog.51cto.com/aaronsa/1744651,如需转载请自行联系原作者

优秀的个人博客,低调大师

兼容iOS 10 资料整理笔记

1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserNotifications的易用,功能也变得非常强大。 iOS 9 以前的通知 1.在调用方法时,有些方法让人很难区分,容易写错方法,这让开发者有时候很苦恼。 2.应用在运行时和非运行时捕获通知的路径还不一致。 3.应用在前台时,是无法直接显示远程通知,还需要进一步处理。 4.已经发出的通知是不能更新的,内容发出时是不能改变的,并且只有简单文本展示方式,扩展性根本不是很好。 iOS 10 开始的通知 1.所有相关通知被统一到了UserNotifications.framework框架中。 2.增加了撤销、更新、中途还可以修改通知的内容。 3.通知不在是简单的文本了,可以加入视频、图片,自定义通知的展示等等。 4.iOS 10相对之前的通知来说更加好用易于管理,并且进行了大规模优化,对于开发者来说是一件好事。 5.iOS 10开始对于权限问题进行了优化,申请权限就比较简单了(本地与远程通知集成在一个方法中)。 iOS 10 通知学习相关资料: UserNotifications: 苹果官方文档-苹果官方视频1-苹果官方视频2-苹果官方视频3活久见的重构 - iOS 10 UserNotifications 框架解析WWDC2016 Session笔记 - iOS 10 推送Notification新特性 2.ATS的问题 iOS 9中默认非HTTS的网络是被禁止的,当然我们也可以把NSAllowsArbitraryLoads设置为YES禁用ATS。不过iOS 10从2017年1月1日起苹果不允许我们通过这个方法跳过ATS,也就是说强制我们用HTTPS,如果不这样的话提交App可能会被拒绝。但是我们可以通过NSExceptionDomains来针对特定的域名开放HTTP可以容易通过审核。 参考学习文章如下:关于 iOS 10 中 ATS 的问题 3.iOS 10 隐私权限设置 iOS 10 开始对隐私权限更加严格,如果你不设置就会直接崩溃,现在很多遇到崩溃问题了,一般解决办法都是在info.plist文件添加对应的Key-Value就可以了。 上图的访问相册的Key添加错了,正确的是Privacy - Photo Library Usage Description。 以上Value值,圈出的红线部分的文字是展示给用户看的,必须添加。目前解决办法基本都一样,参考学习文章如下:兼容iOS 10:配置获取隐私数据权限声明 4.Xcode 8 运行一堆没用的logs解决办法 上图我们看到,自己新建的一个工程啥也没干就打印一堆烂七八糟的东西,我觉得这个应该是Xcode 8的问题,具体也没细研究,解决办法是设置OS_ACTIVITY_MODE : disable如下图: 相关问题连接:stackoverflow问答 5.iOS 10 UIStatusBar方法过期: 在我们开发中有可能用到UIStatusBar一些属性,在iOS 10 中这些方法已经过期了,如果你的项目中有用的话就得需要适配。上面的图片也能发现,如果在iOS 10中你需要使用preferredStatusBar比如这样: //iOS10 -(UIStatusBarStyle)preferredStatusBarStyle{returnUIStatusBarStyleDefault; } 6.iOS 10 UICollectionView 性能优化 随着开发者对UICollectionView的信赖,项目中用的地方也比较多,但是还是存在一些问题,比如有时会卡顿、加载慢等。所以iOS 10 对UICollectionView进一步的优化,因为叙述起来比较复杂耗费时间,在这里只提供学习参考文章如下:WWDC2016 Session笔记 - iOS 10 UICollectionView新特性 7.iOS 10 UIColor 新增方法 以下是官方文档的说明: Most graphics frameworks throughout the system, including Core Graphics, Core Image, Metal, and AVFoundation, have substantially improved support for extended-range pixel formats and wide-gamut color spaces. By extending this behavior throughout the entire graphics stack, it is easier than ever to support devices with a wide color display. In addition, UIKit standardizes on working in a new extended sRGB color space, making it easy to mix sRGB colors with colors in other, wider color gamuts without a significant performance penalty. Here are some best practices to adopt as you start working with Wide Color. In iOS 10, the UIColor class uses the extended sRGB color space and its initializers no longer clamp raw component values to between 0.0 and 1.0. If your app relies on UIKit to clamp component values (whether you’re creating a color or asking a color for its component values), you need to change your app’s behavior when you link against iOS 10. When performing custom drawing in a UIView on an iPad Pro (9.7 inch), the underlying drawing environment is configured with an extended sRGB color space. If your app renders custom image objects, use the new UIGraphicsImageRenderer class to control whether the destination bitmap is created using an extended-range or standard-range format. If you are performing your own image processing on wide-gamut devices using a lower level API, such as Core Graphics or Metal, you should use an extended range color space and a pixel format that supports 16-bit floating-point component values. When clamping of color values is necessary, you should do so explicitly. Core Graphics, Core Image, and Metal Performance Shaders provide new options for easily converting colors and images between color spaces. 因为之前我们都是用RGB来设置颜色,反正用起来也不是特别多样化,这次新增的方法应该就是一个弥补吧。所以在iOS 10 苹果官方建议我们使用sRGB,因为它性能更好,色彩更丰富。如果你自己为UIColor写了一套分类的话也可尝试替换为sRGB,UIColor类中新增了两个Api如下: +(UIColor*)colorWithDisplayP3Red:(CGFloat)displayP3Redgreen:(CGFloat)greenblue:(CGFloat)bluealpha:(CGFloat)alphaNS_AVAILABLE_IOS(10_0); -(UIColor*)initWithDisplayP3Red:(CGFloat)displayP3Redgreen:(CGFloat)greenblue:(CGFloat)bluealpha:(CGFloat)alphaNS_AVAILABLE_IOS(10_0); 8.iOS 10 UITextContentType //ThetextContentTypepropertyistoprovidethekeyboardwithextrainformationaboutthesemanticintentofthetextdocument.@property(nonatomic,copy)UITextContentTypetextContentTypeNS_AVAILABLE_IOS(10_0);//defaultisnil 在iOS 10UITextField添加了textContentType枚举,指示文本输入区域所期望的语义意义。 使用此属性可以给键盘和系统信息,关于用户输入的内容的预期的语义意义。例如,您可以指定一个文本字段,用户填写收到一封电子邮件确认uitextcontenttypeemailaddress。当您提供有关您期望用户在文本输入区域中输入的内容的信息时,系统可以在某些情况下自动选择适当的键盘,并提高键盘修正和主动与其他文本输入机会的整合。 9.iOS 10 字体随着手机系统字体而改变 当我们手机系统字体改变了之后,那我们App的label也会跟着一起变化,这需要我们写很多代码来进一步处理才能实现,但是iOS 10 提供了这样的属性adjustsFontForContentSizeCategory来设置。因为没有真机,具体实际操作还没去实现,如果理解错误帮忙指正。 UILabel*myLabel=[UILabelnew];/* UIFont的preferredFontForTextStyle:意思是指定一个样式,并让字体大小符合用户设定的字体大小。 */ myLabel.font=[UIFontpreferredFontForTextStyle:UIFontTextStyleHeadline];/* Indicateswhetherthecorrespondingelementshouldautomaticallyupdateitsfontwhenthedevice’sUIContentSizeCategoryischanged. Forthispropertytotakeeffect,theelement’sfontmustbeafontvendedusing+preferredFontForTextStyle:or+preferredFontForTextStyle:compatibleWithTraitCollection:withavalidUIFontTextStyle. *///是否更新字体的变化 myLabel.adjustsFontForContentSizeCategory=YES; 10.iOS 10 UIScrollView新增refreshControl iOS 10 以后只要是继承UIScrollView那么就支持刷新功能: @property(nonatomic,strong,nullable)UIRefreshControl*refreshControlNS_AVAILABLE_IOS(10_0)__TVOS_PROHIBITED; 11.iOS 10 判断系统版本正确姿势 判断系统版本是我们经常用到的,尤其是现在大家都有可能需要适配iOS 10,那么问题就出现了,如下图: 我们得到了答案是: //值为1 [[[[UIDevicecurrentDevice]systemVersion]substringToIndex:1]integerValue]//值为10.000000 [[UIDevicecurrentDevice]systemVersion].floatValue,//值为10.0 [[UIDevicecurrentDevice]systemVersion] 所以说判断系统方法最好还是用后面的两种方法,哦~我忘记说了[[UIDevice currentDevice] systemVersion].floatValue这个方法也是不靠谱的,好像在8.3版本输出的值是8.2,记不清楚了反正是不靠谱的,所以建议大家用[[UIDevice currentDevice] systemVersion]这个方法! Swift判断如下: if#available(iOS10.0,*){//iOS10.0print("iOS10.0"); }else{} 参考文章如下:iOS 日常工作之常用宏定义大全 12.Xcode 8 插件不能用的问题 大家都升级了Xcode 8,但是对于插件依赖的开发者们,一边哭着一边去网上寻找解决办法。那么下面是解决办法:让你的 Xcode8 继续使用插件 但是看到文章最后的解释,我们知道如果用插件的话,可能安全上会有问题、并且提交审核会被拒绝,所以建议大家还是不要用了,解决办法总是有的,比如在Xcode中添加注释的代码块也是很方便的。 13.iOS 10开始项目中有的文字显示不全问题 我用Xcode 8和Xcode 7.3分别测试了下,如下图: Xcode 8 Xcode 7 创建一个Label然后让它自适应大小,字体大小都是17最后输出的宽度是不一样的,我们再看一下,下面的数据就知道为什么升级iOS 10之后App中有的文字显示不全了: Xxode 8打印 Xcode 7.3打印 1个文字宽度:17.5 1个文字宽度:17 2个文字宽度:35 2个文字宽度:34 3个文字宽度:52 3个文字宽度:51 4个文字宽度:69.5 4个文字宽度:68 5个文字宽度:87 5个文字宽度:85 6个文字宽度:104 6个文字宽度:102 7个文字宽度:121.5 7个文字宽度:119 8个文字宽度:139 8个文字宽度:136 9个文字宽度:156 9个文字宽度:153 10个文字宽度:173.5 10个文字宽度:170 英文字母会不会也有这种问题,我又通过测试,后来发现英文字母没有问题,只有汉字有问题。目前只有一个一个修改控件解决这个问题,暂时没有其他好办法来解决。 单片机控制挖掘机炒菜不是梦 本文转自ljianbing51CTO博客,原文链接:http://blog.51cto.com/ljianbing/1854368 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Openstack完整搭建系统整理

Operating System How to login to Ubuntu(12.04) Server system Login as a normal user user: openstack password: password Obtain Root privilege sudo su - password: password Update Host configuration hostname controller echo "controller" > /etc/hostname cat > /etc/hosts << EOF 127.0.0.1 localhost 127.0.1.1 controller {put_eth0_ip_here} controller # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters EOF Configure the network Setup the network in Native OpenStack VM # NOTE: The current IP is statically assigned by our system. Please do not change it. vi /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.8.210 netmask 255.255.255.0 gateway 192.168.8.1 dns-nameservers 192.168.8.15 8.8.8.8 # 需在此配置DNS,不可直接修改/etc/resolv.conf文件 auto eth1 iface eth1 inet static address 192.168.8.211 netmask 255.255.255.0 auto eth2 iface eth2 inet static address 192.168.8.212 netmask 255.255.255.0 Restart the network service /etc/init.d/networking restart Enable IP forwarding # To permit IP packets pass through different networks,# the network card should be configured with routing capability. echo"net.ipv4.ip_forward = 1">>/etc/sysctl.conf sysctl -p Upgrade your system to the latest version Add software repository echo -en 'deb http://ubuntu-cloud.archive.canonical.com/ubuntu precise-updates/havana main\n deb-src http://ubuntu-cloud.archive.canonical.com/ubuntu precise-updates/havana main' \ >> /etc/apt/sources.list.d/havana.list Upgrade the system apt-get update && apt-get dist-upgrade Install NTP Install the package apt-get install -y ntp Update /etc/ntp.conf file # Here we set ntp.ubuntu.com as the direct source of time.# You will also find that a local time source # is also provided in case of internet time service interruption. sed -i 's/server ntp.ubuntu.com/ \ server ntp.ubuntu.com \ server 127.127.1.0 \ fudge 127.127.1.0 stratum 10/g' /etc/ntp.conf Restart NTP service service ntp restart Set the OpenStack installation environment # Create the environment variables cat > /root/novarc << EOF export OS_TENANT_NAME=admin export OS_USERNAME=admin export OS_PASSWORD=password export MYSQL_PASS=password export SERVICE_PASSWORD=password export RABBIT_PASSWORD=password export FIXED_RANGE=10.0.0.0/24 export FLOATING_RANGE=$(/sbin/ifconfig eth0 | awk '/inet addr/ {print $2}' \ | cut -f2 -d ":" | awk -F "." '{print $1"."$2"."$3}').224/27 export OS_AUTH_URL="http://localhost:5000/v2.0/" export SERVICE_ENDPOINT="http://localhost:35357/v2.0" export SERVICE_TOKEN=stackinsider export MASTER="$(/sbin/ifconfig eth0 \ | awk '/inet addr/ {print $2}' | cut -f2 -d ":")" export LOCAL_IP="$(/sbin/ifconfig eth1 \ | awk '/inet addr/ {print $2}' | cut -f2 -d ":")" EOF # Update the global environment variables.cat/root/novarc >>/etc/profile source /etc/profile MySQL Server Setup the MySQL password for administrator cat << MYSQL_PRESEED | debconf-set-selections mysql-server-5.5 mysql-server/root_password password $MYSQL_PASS mysql-server-5.5 mysql-server/root_password_again password $MYSQL_PASS mysql-server-5.5 mysql-server/start_on_boot boolean true MYSQL_PRESEED Install the packages apt-get -y install mysql-server python-mysqldb curl Allow external connections # Bind MySQL service to all network interfaces. sed-i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf Restart MySQL service service mysql restart Create Databases, Users, Privileges for OpenStack mysql -uroot -p$MYSQL_PASS << EOF CREATE DATABASE nova; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'controller' IDENTIFIED BY '$MYSQL_PASS'; CREATE DATABASE glance; GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'controller' IDENTIFIED BY '$MYSQL_PASS'; CREATE DATABASE keystone; GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'controller' IDENTIFIED BY '$MYSQL_PASS'; CREATE DATABASE cinder; GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'controller' IDENTIFIED BY '$MYSQL_PASS'; CREATE DATABASE neutron; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY '$MYSQL_PASS'; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'controller' IDENTIFIED BY '$MYSQL_PASS'; FLUSH PRIVILEGES; EOF Message Queue Server: RabbitMQ Install the packages # Install the messaging queue server. Typically it is RabbitMQ. apt-get-yinstallrabbitmq-server Change the default password rabbitmqctl change_password guest $RABBIT_PASSWORD OpenStack Identity Server: Keystone Install the packages apt-get -y install keystone Update /etc/keystone/keystone.conf sed -i -e " s/# admin_token = ADMIN/admin_token = $SERVICE_TOKEN/g; \ s/# bind_host = 0.0.0.0/bind_host = 0.0.0.0/g; \ s/# public_port = 5000/public_port = 5000/g; \ s/# admin_port = 35357/admin_port = 35357/g; \ s/# compute_port = 8774/compute_port = 8774/g; \ s/# verbose = True/verbose = True/g; \ s/# idle_timeout/idle_timeout/g" /etc/keystone/keystone.conf Update MySQL connection for Keyatone sed -i '/connection = .*/{s|sqlite:///.*|mysql://'"keystone"':'"$MYSQL_PASS"'@'"$MASTER"'/keystone|g}'\ /etc/keystone/keystone.conf Restart Keystone and Sync database service keystone restart keystone-manage db_sync Create users, tenants, services for OpenStack wget http://wiki.stackinsider.com/images/9/99/Ksdata.sh_.txt -O Ksdata.sh sed -i 's/quantum/neutron/g' Ksdata.sh sed -i 's/QUANTUM/NEUTRON/g' Ksdata.sh sh Ksdata.sh Create endpoints for OpenStack wget http://wiki.stackinsider.com/images/1/18/Ksendpoints.sh_.txt -O Ksendpoints.sh sed -i 's/quantum/neutron/g' Ksendpoints.sh sh Ksendpoints.sh OpenStack Image Server: Glance Install the packages apt-get -y install glance Update the credentials for Glance sed -i -e " s/%SERVICE_TENANT_NAME%/service/g; \ s/%SERVICE_USER%/glance/g; s/%SERVICE_PASSWORD%/$SERVICE_PASSWORD/g; \ " /etc/glance/glance-api.conf /etc/glance/glance-registry.conf Update MySQL connection for Glance sed -i '/sql_connection = .*/{s|sqlite:///.*|mysql://'"glance"':'"$MYSQL_PASS"'@'"$MASTER"'/glance|g}'\ /etc/glance/glance-registry.conf /etc/glance/glance-api.conf Setup notifier for Glance sed -i " s/notifier_strategy = noop/notifier_strategy = rabbit/g;\ s/rabbit_password = guest/rabbit_password = $RABBIT_PASSWORD/g;" \ /etc/glance/glance-api.conf Setup flavor for Glance cat << EOF >>/etc/glance/glance-api.conf flavor = keystone+cachemanagement EOF cat << EOF >>/etc/glance/glance-registry.conf flavor = keystone EOF Restart Glance services service glance-api restart service glance-registry restart Sync Glance database glance-manage db_sync Download Cirros image wget https://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img Upload Cirros image to Glance glance add name=cirros-0.3.0-x86_64 is_public=truecontainer_format=bare \ disk_format=qcow2 </root/cirros-0.3.0-x86_64-disk.img Check the image # Check the image ID to confirm if Glance operates normally. glance index OpenStack Block Storage: Cinder Install the packages apt-get install -y cinder-api cinder-scheduler cinder-volume iscsitarget \ open-iscsi iscsitarget-dkms python-cinderclient Prepare the logical volumnes for Cinder You can manage Cinder via a pre-prepared logical volumes "cinder-volumes", the size of which is 1.2GB. fdisk -l pvcreate /dev/vdb vgcreate cinder-volumes /dev/vdb Volume group "cinder-volumes" successfully created iSCSI configuration Enable the iSCSI target service sed -i 's/false/true/g'/etc/default/iscsitarget Re-configure the kernel modules dpkg-reconfigure iscsitarget-dkms Restart iSCSI services service iscsitarget restart && service open-iscsi restart Update the configuration file of Cinder cat >/etc/cinder/cinder.conf <<EOF [DEFAULT] sql_connection = mysql://cinder:$MYSQL_PASS@$MASTER/cinder rootwrap_config = /etc/cinder/rootwrap.conf api_paste_confg = /etc/cinder/api-paste.ini iscsi_helper = tgtadm volume_name_template = volume-%s volume_group = cinder-volumes verbose = True auth_strategy = keystone state_path = /var/lib/cinder lock_path = /var/lock/cinder volumes_dir = /var/lib/cinder/volumes rabbit_password = $RABBIT_PASSWORD EOF Update the credentials of Cinder sed -i -e " s/%SERVICE_TENANT_NAME%/service/g; \ s/%SERVICE_USER%/cinder/g; s/%SERVICE_PASSWORD%/$SERVICE_PASSWORD/g; " \ /etc/cinder/api-paste.ini Synchronize the database of Cinder cinder-manage db sync Restart the services of Cinder service cinder-api restart service cinder-scheduler restart service cinder-volume restart OpenStack Network Server: Neutron Install the Open vSwitch apt-get install -y openvswitch-switch apt-get install module-assistant module-assistant auto-install openvswitch-datapath 若遇kernel-header错误,则执行以下命令,再执行上一步命令即可: ln -s /usr/src/linux-headers-`uname -r`/include/generated/uapi/linux/version.h /lib/modules/`uname -r`/build/include/linux/ Configure the network bridge Configure the bridge for internal communication ovs-vsctl add-br br-int Configure the bridge for external communication ovs-vsctl add-br br-eth2 # Enable external network access under nested Open vSwitchifconfig br-eth2 promisc up Bind eth2 to the external bridge ovs-vsctl add-port br-eth2 eth2 Update the external bridge configuration vim /etc/network/interfaces # Modify the corresponding configuration auto eth2 iface eth2 inet manual up ifconfig$IFACE 0.0.0.0 up up ip linkset$IFACE promisc on down ip linkset$IFACE promisc off down ifconfig$IFACE down auto br-eth2 iface br-eth2 inet static address {put_eth2_ip_here}netmask 255.255.255.0 up ip linkset$IFACE promisc on down ip linkset$IFACE promisc off Restart the network service /etc/init.d/networking restart Install Neutron apt-get -y install neutron-server python-cliff \ neutron-plugin-openvswitch-agent \ neutron-dhcp-agent python-pyparsing Configure the RabbitMQ sed -i -e " s/# auth_strategy/auth_strategy/g; \ s/# fake_rabbit/fake_rabbit/g; \ s/# rabbit_host = localhost/rabbit_host = $MASTER/g; \ s/# rabbit_password = guest/rabbit_password = $RABBIT_PASSWORD/g"/etc/neutron/neutron.conf Configure the Neutron Update the general configuration for Neutron cat << EOF >>/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini [securitygroup] firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver [database]connection=mysql://neutron:$MYSQL_PASS@$MASTER/neutron [ovs] network_vlan_ranges = physnet1 bridge_mappings = physnet1:br-eth2 EOF Update the MySQL connection for Neutron sed -i '/connection = .*/{s|sqlite:///.*|mysql://'"neutron"':'"password"'@'"$MASTER"'/neutron|g}' \/etc/neutron/neutron.conf Update the metadata agent for Neutron sed -i -e " s/%SERVICE_TENANT_NAME%/service/g; s/%SERVICE_USER%/neutron/g; \ s/%SERVICE_PASSWORD%/$SERVICE_PASSWORD/g; "/etc/neutron/metadata_agent.ini Update the credentials for Neutron sed -i -e " s/%SERVICE_TENANT_NAME%/service/g; s/%SERVICE_USER%/neutron/g; \ s/%SERVICE_PASSWORD%/$SERVICE_PASSWORD/g; "/etc/neutron/neutron.conf Change the passphase of Neutron metadata agent sed -i -e " s/# metadata_proxy_shared_secret =/metadata_proxy_shared_secret \ = helloStackinsider/g; "/etc/neutron/metadata_agent.ini Change the passphase of Neutron dhcp agent sed -i -e " s/# interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver/interface_driver = \ neutron.agent.linux.interface.OVSInterfaceDriver/g; "/etc/neutron/dhcp_agent.ini Restart the Neutron services cd /etc/init.d/; for i in $(ls neutron-*); do sudo service $i restart; done OpenStack Controller Server: Nova Controller Install the packages apt-get -y install nova-api nova-cert nova-common pm-utils nova-conductor \ nova-scheduler python-nova python-novaclient nova-consoleauth novnc nova-novncproxy Configure Nova Update the credential for Nova sed -i -e " s/127.0.0.1/$MASTER/g; s/%SERVICE_TENANT_NAME%/service/g; \ s/%SERVICE_USER%/nova/g; s/%SERVICE_PASSWORD%/$SERVICE_PASSWORD/g; " \ /etc/nova/api-paste.ini Update the general configuration: /etc/nova/nova.conf cat >/etc/nova/nova.conf <<EOF [DEFAULT] # MySQL Connection # sql_connection=mysql://nova:$MYSQL_PASS@$MASTER/nova # nova-scheduler # rabbit_host=$MASTER rabbit_password=$RABBIT_PASSWORD #scheduler_driver=nova.scheduler.simple.SimpleScheduler #compute_scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler compute_scheduler_driver=nova.scheduler.simple.SimpleScheduler # nova-api # cc_host=$MASTER auth_strategy=keystone s3_host=$MASTER ec2_host=$MASTER nova_url=http://$MASTER:8774/v1.1/ ec2_url=http://$MASTER:8773/services/Cloud keystone_ec2_url=http://$MASTER:5000/v2.0/ec2tokens api_paste_config=/etc/nova/api-paste.ini allow_admin_api=true use_deprecated_auth=false ec2_private_dns_show_ip=True dmz_cidr=169.254.169.254/32 ec2_dmz_host=169.254.169.254 metadata_host=$MASTER metadata_listen=0.0.0.0 enabled_apis=ec2,osapi_compute,metadata # Networking # network_api_class=nova.network.neutronv2.api.API neutron_url=http://$MASTER:9696 neutron_auth_strategy=keystone neutron_admin_tenant_name=service neutron_admin_username=neutron neutron_admin_password=$SERVICE_PASSWORD neutron_admin_auth_url=http://$MASTER:35357/v2.0 libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtHybridOVSBridgeDriver linuxnet_interface_driver=nova.network.linux_net.LinuxOVSInterfaceDriver firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver #Metadata service_neutron_metadata_proxy = True neutron_metadata_proxy_shared_secret = helloStackinsider # Compute # compute_driver=libvirt.LibvirtDriver # Cinder # volume_api_class=nova.volume.cinder.API # Glance # glance_api_servers=$MASTER:9292 image_service=nova.image.glance.GlanceImageService # novnc # novnc_enable=true novncproxy_base_url=http://$MASTER:6080/vnc_auto.html vncserver_proxyclient_address=$MASTER vncserver_listen=$MASTER # Misc # logdir=/var/log/nova state_path=/var/lib/nova lock_path=/var/lock/nova #root_helper=sudo nova-rootwrap /etc/nova/rootwrap.conf rootwrap_config=/etc/nova/rootwrap.conf verbose=true #verbose=false EOF Synchronize Nova database nova-manage db sync Restart Nova services cd /etc/init.d/; for i in $( ls nova-* ); do sudo service $i restart; done OpenStack Compute Server: Nova Compute Install the Hypervisor apt-get install -y kvm libvirt-bin pm-utils Setup Cgroup support for libvirt cat << EOF >>/etc/libvirt/qemu.conf cgroup_device_acl = ["/dev/null", "/dev/full", "/dev/zero","/dev/random", "/dev/urandom","/dev/ptmx", "/dev/kvm", "/dev/kqemu","/dev/rtc", "/dev/hpet","/dev/net/tun", ] EOF Allow Live Migration sed -i '/#listen_tls/s/#listen_tls/listen_tls/;/#listen_tcp/s/#listen_tcp/listen_tcp/;/#auth_tcp/s/#auth_tcp/auth_tcp/; /auth_tcp/s/sasl/none/' \/etc/libvirt/libvirtd.conf Listen on TCP sed -i '/env libvirtd_opts/s/-d/-d -l/'/etc/init/libvirt-bin.conf sed -i '/libvirtd_opts/s/-d/-d -l/'/etc/default/libvirt-bin Restart libvirt-bin service service libvirt-bin restart Install the Nova Compute apt-get -yinstallnova-compute-kvm Modify the libvirt_type vi /etc/nova/nova-compute.conf libvirt_type=kvm 修改为 libvirt_type=qemu Restart Nova services cd /etc/init.d/; for i in $( ls nova-* ); do sudo service $i restart; done OpenStack Dashboard: Horizon Install Horizon apt-get -y install apache2 libapache2-mod-wsgi openstack-dashboard memcached python-memcache Prepare Tenant Network Create a bash script for preparation vi /root/prepare_network.sh #!/bin/bash # Create Tenant and User # tenant=TenantA user=UserA usermail=usera@stackinsider.com role=Member if keystone tenant-list | grep -q $tenant;then echo "Tenant $tenant existed!" else tenant_id=`keystone tenant-create --name $tenant | awk '/id/{print $4}'` fi if keystone user-list | grep -q $user;then echo "User $user existed!" else keystone user-create --name=$user --pass=password --tenant-id $tenant_id --email=$usermail fi keystone user-role-add --tenant $tenant --user $user --role $role # Create virtual router and sub-network # neutron net-create --tenant-id ${tenant_id} sharednet1 --shared --provider:network_type flat \ --provider:physical_network physnet1 neutron subnet-create --tenant-id ${tenant_id} sharednet1 192.168.100.0/24 --no-gateway \ --allocation-pool start=192.168.100.150,end=192.168.100.200 # 新建子网,配置共享网段 Execute the bash script to create network interconnection bash prepare_network.sh Set up the default security group rules # Obtain TenantA's default security group ID neutron --os-tenant-name TenantA --os-username UserA --os-password password --os-auth-url=http://localhost:5000/v2.0 security-group-list # Enable ICMP and TCP ports neutron security-group-rule-create --protocol icmp --direction ingress {TenantA security group ID} neutron security-group-rule-create --protocol icmp --direction egress {TenantA security group ID} neutron security-group-rule-create --protocol tcp --direction egress --port-range-min 1 --port-range-max 65535 {TenantA security group ID} neutron security-group-rule-create --protocol tcp --direction ingress --port-range-min 1 --port-range-max65535{TenantA security group ID} Start a VM Check the Ubuntu image # Check the image ID to confirm if Glance operates normally. glance index Generate ssh key and Upload it to Nova # Generate ssh key ssh-keygen # Upload ssh pub key to nova nova keypair-add key01 --pub-key~ /.ssh /id_rsa.pub Launch a VM nova --os-tenant-name TenantA --os-username UserA --os-password password --os-auth-url=http://localhost:5000/v2.0 boot --flavor 1 --image{the cirros ID from Glance} --security_group default --key-name key01 vm001 Check the VM status # Check your VM status nova --os-tenant-name TenantA --os-username UserA --os-password password \ --os-auth-url=http://localhost:5000/v2.0 list Access the VM instance using its flat IP # Obtain the VM's fixed IP nova --os-tenant-name TenantA --os-username UserA --os-password password \ --os-auth-url=http://localhost:5000/v2.0 list # You can find its fixed IP in the "Networks" section: sharednet1={flat IP}.# SSH to your VM when your VM is ACTIVEssh cirros@{put_flat_ip_here} Access the Dashboard http://controller/horizon(controller为主机名) Questions 执行“neutron--os-tenant-nameTenantA--os-usernameUserA--os-passwordpassword--os-auth-url=http://localhost:5000/v2.0 security-group-list”出现错误: “404 Not Found.The resource could not be found.” 解决: vi /etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini [securitygroup] # Firewall driver for realizing neutron security group function. # firewall_driver = neutron.agent.firewall.NoopFirewallDriver firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver 然后重启neutron服务: cd /etc/init.d/; for i in $( ls neutron-* ); do sudo service $i restart; done 本文转自 xxrenzhe11 51CTO博客,原文链接:http://blog.51cto.com/xxrenzhe/1351626,如需转载请自行联系原作者

优秀的个人博客,低调大师

elasticsearch的score相关资料(整理

核心概念理解:elastcsearch整个过程包括匹配+打分,其中匹配根据查询条件进行查询,打分根据查询回来的字段进行打分。 通过Function Score Query优化Elasticsearch搜索结果:http://blog.csdn.net/zxjiayou1314/article/details/53185287 关于elasticsearch function_score的使用:http://blog.csdn.net/nxgych/article/details/53096255 [Elasticsearch] 控制相关度:http://blog.csdn.net/dm_vincent/article/details/42201721 lucene全文检索基础:http://blog.csdn.net/napoay/article/details/50305287 lucence 搜索过程介绍:http://blog.csdn.net/forfuture1978/article/details/4711308 http://blog.csdn.net/forfuture1978/article/details/4745802 ElasticSearch相关性打分机制学习:https://zhuanlan.zhihu.com/p/24807506 elasticsearch二次打分官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/1.6/search-request-rescore.html

优秀的个人博客,低调大师

Hyperledger Fabric 架构设计整理

整个功能架构如下图所示。 包括三大组件:区块链服务(Blockchain)、链码服务(Chaincode)、成员权限管理(Membership)。 概念术语 • Auditability(审计性):在一定权限和许可下,可以对链上的交易进行审计和检查。 • Block(区块):代表一批得到确认的交易信息的整体,准备被共识加入到区块链中。 • Blockchain(区块链):由多个区块链接而成的链表结构,除了首个区块,每个区块都包括前继区块内容的 hash 值。 • Certificate Authority(CA):负责身份权限管理,又叫 Member Service 或 Identity Service。 • Chaincode(链上代码或链码):区块链上的应用代码,扩展自“智能合约”概念,支持 golang、nodejs 等,运行在隔离的容器环境中。 • Committer(提交节点):1.0 架构中一种 peer 节点角色,负责对 orderer 排序后的交易进行检查,选择合法的交易执行并写入存储。 • Confidentiality(保密):只有交易相关方可以看到交易内容,其它人未经授权则无法看到。 • Endorser(背书节点):1.0 架构中一种 peer 节点角色,负责检验某个交易是否合法,是否愿意为之背书、签名。 • Enrollment Certificate Authority(ECA,注册 CA):负责成员身份相关证书管理的 CA。 • Ledger(账本):包括区块链结构(带有所有的可验证交易信息,但只有最终成功的交易会改变世界观)和当前的世界观(world state)。Ledger 仅存在于 Peer 节点。 • MSP(Member Service Provider,成员服务提供者):成员服务的抽象访问接口,实现对不同成员服务的可拔插支持。 • Non-validating Peer(非验证节点):不参与账本维护,仅作为交易代理响应客户端的 REST 请求,并对交易进行一些基本的有效性检查,之后转发给验证节点。 • Orderer(排序节点):1.0 架构中的共识服务角色,负责排序看到的交易,提供全局确认的顺序。 • Permissioned Ledger(带权限的账本):网络中所有节点必须是经过许可的,非许可过的节点则无法加入网络。 • Privacy(隐私保护):交易员可以隐藏交易的身份,其它成员在无特殊权限的情况下,只能对交易进行验证,而无法获知身份信息。 • Transaction(交易):执行账本上的某个函数调用。具体函数在 chaincode 中实现。 • Transactor(交易者):发起交易调用的客户端。 • Transaction Certificate Authority(TCA,交易 CA):负责维护交易相关证书管理的 CA。 • Validating Peer(验证节点):维护账本的核心节点,参与一致性维护、对交易的验证和执行。 • World State(世界观):是一个键值数据库,chaincode 用它来存储交易相关的状态。 区块链服务 区块链服务提供一个分布式账本平台。一般地,多个交易被打包进区块中,多个区块构成一条区块链。区块链代表的是账本状态机发生变更的历史过程。 交易 交易意味着围绕着某个链码进行操作。 交易可以改变世界状态。 交易中包括的内容主要有: • 交易类型:目前包括 Deploy、Invoke、Query、Terminate 四种; • uuid:代表交易的唯一编号; • 链码编号 chaincodeID:交易针对的链码; • 负载内容的 hash 值:Deploy 或 Invoke 时候可以指定负载内容; • 交易的保密等级 ConfidentialityLevel; • 交易相关的 metadata 信息; • 临时生成值 nonce:跟安全机制相关; • 交易者的证书信息 cert; • 签名信息 signature; • metadata 信息; • 时间戳 timestamp。 交易的数据结构(Protobuf 格式)定义为: message Transaction { enum Type { UNDEFINED = 0; // deploy a chaincode to the network and call `Init` function CHAINCODE_DEPLOY = 1; // call a chaincode `Invoke` function as a transaction CHAINCODE_INVOKE = 2; // call a chaincode `query` function CHAINCODE_QUERY = 3; // terminate a chaincode; not implemented yet CHAINCODE_TERMINATE = 4; } Type type = 1; //store ChaincodeID as bytes so its encrypted value can be stored bytes chaincodeID = 2; bytes payload = 3; bytes metadata = 4; string uuid = 5; google.protobuf.Timestamp timestamp = 6; ConfidentialityLevel confidentialityLevel = 7; string confidentialityProtocolVersion = 8; bytes nonce = 9; bytes toValidators = 10; bytes cert = 11; bytes signature = 12; } 在 1.0 架构中,一个 transaction 包括如下信息: [ledger] [channel], proposal:[chaincode, ] **endorsement:[proposal hash, simulation result, signature] • endorsements: proposal hash, simulation result, signature • function-spec: function name, arguments • proposal: [channel,] chaincode, 区块 区块打包交易,确认交易后的世界状态。 一个区块中包括的内容主要有: • 版本号 version:协议的版本信息; • 时间戳 timestamp:由区块提议者设定; • 交易信息的默克尔树的根 hash 值:由区块所包括的交易构成; • 世界观的默克尔树的根 hash 值:由交易发生后整个世界的状态值构成; • 前一个区块的 hash 值:构成链所必须; • 共识相关的元数据:可选值; • 非 hash 数据:不参与 hash 过程,各个 peer 上的值可能不同,例如本地提交时间、交易处理的返回值等; 注意具体的交易信息并不存放在区块中。 区块的数据结构(Protobuf 格式)定义为: message Block { uint32 version = 1; google.protobuf.Timestamp timestamp = 2; repeated Transaction transactions = 3; bytes stateHash = 4; bytes previousBlockHash = 5; bytes consensusMetadata = 6; NonHashData nonHashData = 7; } 一个真实的区块内容示例: { "nonHashData": { "localLedgerCommitTimestamp": { "nanos": 975295157, "seconds": 1466057539 }, "transactionResults": [ { "uuid": "7be1529ee16969baf9f3156247a0ee8e7eee99a6a0a816776acff65e6e1def71249f4cb1cad5e0f0b60b25dd2a6975efb282741c0e1ecc53fa8c10a9aaa31137" } ] }, "previousBlockHash": "RrndKwuojRMjOz/rdD7rJD/NUupiuBuCtQwnZG7Vdi/XXcTd2MDyAMsFAZ1ntZL2/IIcSUeatIZAKS6ss7fEvg==", "stateHash": "TiIwROg48Z4xXFFIPEunNpavMxnvmZKg+yFxKK3VBY0zqiK3L0QQ5ILIV85iy7U+EiVhwEbkBb1Kb7w1ddqU5g==", "transactions": [ { "chaincodeID": "CkdnaXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9leGFtcGxlcy9jaGFpbmNvZGUvZ28vY2hhaW5jb2RlX2V4YW1wbGUwMhKAATdiZTE1MjllZTE2OTY5YmFmOWYzMTU2MjQ3YTBlZThlN2VlZTk5YTZhMGE4MTY3NzZhY2ZmNjVlNmUxZGVmNzEyNDlmNGNiMWNhZDVlMGYwYjYwYjI1ZGQyYTY5NzVlZmIyODI3NDFjMGUxZWNjNTNmYThjMTBhOWFhYTMxMTM3", "payload": "Cu0BCAESzAEKR2dpdGh1Yi5jb20vaHlwZXJsZWRnZXIvZmFicmljL2V4YW1wbGVzL2NoYWluY29kZS9nby9jaGFpbmNvZGVfZXhhbXBsZTAyEoABN2JlMTUyOWVlMTY5NjliYWY5ZjMxNTYyNDdhMGVlOGU3ZWVlOTlhNmEwYTgxNjc3NmFjZmY2NWU2ZTFkZWY3MTI0OWY0Y2IxY2FkNWUwZjBiNjBiMjVkZDJhNjk3NWVmYjI4Mjc0MWMwZTFlY2M1M2ZhOGMxMGE5YWFhMzExMzcaGgoEaW5pdBIBYRIFMTAwMDASAWISBTIwMDAw", "timestamp": { "nanos": 298275779, "seconds": 1466057529 }, "type": 1, "uuid": "7be1529ee16969baf9f3156247a0ee8e7eee99a6a0a816776acff65e6e1def71249f4cb1cad5e0f0b60b25dd2a6975efb282741c0e1ecc53fa8c10a9aaa31137" } ] } 世界观 世界观用于存放链码执行过程中涉及到的状态变量,是一个键值数据库。典型的元素为 [chaincodeID, ckey]: value 结构。 为了方便计算变更后的 hash 值,一般采用默克尔树数据结构进行存储。树的结构由两个参数(numBuckets 和 maxGroupingAtEachLevel)来进行初始配置,并由 hashFunction 配置决定存放键值到叶子节点的方式。显然,各个节点必须保持相同的配置,并且启动后一般不建议变动。 • numBuckets:叶子节点的个数,每个叶子节点是一个桶(bucket),所有的键值被 hashFunction 散列分散到各个桶,决定树的宽度; • maxGroupingAtEachLevel:决定每个节点由多少个子节点的 hash 值构成,决定树的深度。 其中,桶的内容由它所保存到键值先按照 chaincodeID 聚合,再按照升序方式组成。 一般地,假设某桶中包括M个 chaincodeID,对于chaincodeIDi,假设其包括 N个键值对,则聚合Gi内容可以计算为: 该桶的内容则为: 注:这里的 + 代表字符串拼接,并非数学运算。 链码服务 链码包含所有的处理逻辑,并对外提供接口,外部通过调用链码接口来改变世界观。 接口和操作 链码需要实现 Chaincode 接口,以被 VP 节点调用。 type Chaincode interface { Init(stub *ChaincodeStub, function string, args []string) ([]byte, error) Invoke(stub *ChaincodeStub, function string, args []string) ([]byte, error) Query(stub *ChaincodeStub, function string, args []string) ([]byte, error)} 链码目前支持的交易类型包括:部署(Deploy)、调用(Invoke)和查询(Query)。 部署:VP 节点利用链码创建沙盒,沙盒启动后,处理 protobuf 协议的 shim 层一次性发送包含 ChaincodeID 信息的 REGISTER 消息给 VP 节点,进行注册,注册完成后,VP 节点通过 gRPC 传递参数并调用链码 Init 函数完成初始化; 调用:VP 节点发送 TRANSACTION 消息给链码沙盒的 shim 层,shim 层用传过来的参数调用链码的 Invoke 函数完成调用; 查询:VP 节点发送 QUERY 消息给链码沙盒的 shim 层,shim 层用传过来的参数调用链码的 Query 函数完成查询。 不同链码之间可能互相调用和查询。 容器 在实现上,链码需要运行在隔离的容器中,超级账本采用了 Docker 作为默认容器。 对容器的操作支持三种方法:build、start、stop,对应的接口为 VM。 type VM interface { build(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool, reader io.Reader) error start(ctxt context.Context, id string, args []string, env []string, attachstdin bool, attachstdout bool) error stop(ctxt context.Context, id string, timeout uint, dontkill bool, dontremove bool) error } 链码部署成功后,会创建连接到部署它的 VP 节点的 gRPC 通道,以接受后续 Invoke 或 Query 指令。 gRPC 消息 VP 节点和容器之间通过 gRPC 消息来交互。消息基本结构为: message ChaincodeMessage { enum Type { UNDEFINED = 0; REGISTER = 1; REGISTERED = 2; INIT = 3; READY = 4; TRANSACTION = 5; COMPLETED = 6; ERROR = 7; GET_STATE = 8; PUT_STATE = 9; DEL_STATE = 10; INVOKE_CHAINCODE = 11; INVOKE_QUERY = 12; RESPONSE = 13; QUERY = 14; QUERY_COMPLETED = 15; QUERY_ERROR = 16; RANGE_QUERY_STATE = 17; } Type type = 1; google.protobuf.Timestamp timestamp = 2; bytes payload = 3; string uuid = 4;} 当发生链码部署时,容器启动后发送 REGISTER 消息到 VP 节点。如果成功,VP 节点返回 REGISTERED 消息,并发送 INIT 消息到容器,调用链码中的 Init 方法。 当发生链码调用时,VP 节点发送 TRANSACTION 消息到容器,调用其 Invoke 方法。如果成功,容器会返回 RESPONSE 消息。 类似的,当发生链码查询时,VP 节点发送 QUERY 消息到容器,调用其 Query 方法。如果成功,容器会返回 RESPONSE 消息。 成员权限管理 通过基于 PKI 的成员权限管理,平台可以对接入的节点和客户端的能力进行限制。 证书有三种,Enrollment,Transaction,以及确保安全通信的 TLS 证书。 注册证书 ECert:颁发给提供了注册凭证的用户或节点,一般长期有效; 交易证书 TCert:颁发给用户,控制每个交易的权限,一般针对某个交易,短期有效。 通信证书 TLSCert:控制对网络的访问,并且防止窃听。 新的架构设计 目前,VP 节点执行了所有的操作,包括接收交易,进行交易验证,进行一致性达成,进行账本维护等。这些功能的耦合导致节点性能很难进行扩展。 新的思路就是对这些功能进行解耦,让每个功能都相对单一,容易进行扩展。社区内已经有了一些讨论。 Fabric 1.0 的设计采用了适当的解耦,根据功能将节点角色解耦开,让不同节点处理不同类型的工作负载。 示例工作过程 客户端:客户端应用使用 SDK 来跟 Fabric 打交道,构造合法的交易提案提交给 endorser;收集到足够多 endorser 支持后可以构造合法的交易请求,发给 orderer 或代理节点。 Endorser peer:负责对来自客户端的交易进行合法性和 ACL 权限检查(模拟交易),通过则签名并返回结果给客户端。 Committer peer:负责维护账本,将达成一致顺序的批量交易结果进行状态检查,生成区块,执行合法的交易,并写入账本,同一个物理节点可以同时担任 endorser 和 committer 的 角色。 Orderer:仅负责排序,给交易们一个全局的排序,一般不需要跟账本和交易内容打交道。 CA:负责所有证书的维护,遵循 PKI。 示例交易过程

优秀的个人博客,低调大师

HDFS 常用操作分类汇总整理

1、HDFS文件的权限以及读写操作 HDFS文件的权限: 与Linux文件权限类似 r: read; w:write; x:execute,权限x对于文件忽略,对于文件夹表示是否允许访问其内容 如果Linux系统用户zhangsan使用hadoop命令创建一个文件,那么这个文件在HDFS中owner就是zhangsan HDFS的权限目的:阻止好人错错事,而不是阻止坏人做坏事。HDFS相信,你告诉我你是谁,我就认为你是谁 HDFS文件的读取: HDFS文件的写入: HDFS文件存储: 两个文件,一个文件156M,一个文件128在HDFS里面怎么存储? –Block为64MB –rapliction默认拷贝3份 HDFS文件存储结构: 2、HDFS下的文件操作 (1)列出HDFS文件 通过“-ls”命令列出HDFS下的文件 wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfs-ls (2)列出HDFS目录下某个文档中的文件 此处展示的是“-ls 文件名”命令浏览HDFS下名为in的文档中的文件 wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfs-lsin (3)上传文件到HDFS 此处展示的是“-put 文件1 文件2”命令将hadoop-0.20.2目录下的test1文件上传到HDFS上并重命名为test wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfs-puttest1test 注意:在执行“-put”时只有两种可能,即是执行成功和执行失败。在上传文件时,文件首先复制到DataNode上,只有所有的DataNode都成功接收完数据,文件上传才是成功的。 (4)将HDFS中的文件复制到本地系统中 此处展示的是“-get 文件1 文件2”命令将HDFS中的in文件复制到本地系统并命名为getin: wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfs-getingetin (5)删除HDFS下的文档 此处展示的是“-rmr 文件”命令删除HDFS下名为out的文档: wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfs-rmrout 执行命令后,查看只剩下一个in文件,删除成功: (6)查看HDFS下的某个文件 此处展示的是“-cat 文件”命令查看HDFS下in文件中的内容: wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfs-catin/* 输出: helloworld hellohadoop PS:bin/hadoop dfs 的命令远不止这些,但是本文的这些命令很实用,对于其他的操作,可以通过“-help commandName”命令所列出的清单来进一步的学习 3、管理与更新 (1)报告HDFS的基本统计信息 通过“-report”命令查看HDFS的基本统计信息 wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfsadmin-report 执行结果如下所示: 14/12/0205:19:05WARNconf.Configuration:DEPRECATED:hadoop-site.xmlfoundintheclasspath.Usageofhadoop-site.xmlisdeprecated.Insteadusecore-site.xml,mapred-site.xmlandhdfs-site.xmltooverridepropertiesofcore-default.xml,mapred-default.xmlandhdfs-default.xmlrespectively ConfiguredCapacity:19945680896(18.58GB) PresentCapacity:13558165504(12.63GB) DFSRemaining:13558099968(12.63GB) DFSUsed:65536(64KB) DFSUsed%:0% Underreplicatedblocks:1 Blockswithcorruptreplicas:0 Missingblocks:0 ————————————————- Datanodesavailable:1(1total,0dead) Name:127.0.0.1:50010 DecommissionStatus:Normal ConfiguredCapacity:19945680896(18.58GB) DFSUsed:65536(64KB) NonDFSUsed:6387515392(5.95GB) DFSRemaining:13558099968(12.63GB) DFSUsed%:0% DFSRemaining%:67.98% Lastcontact:TueDec0205:19:04PST2014 (2)退出安全模式 NameNode在启动时会自动进入安全模式。安全模式是NameNode的一种状态,在这个阶段,文件系统不允许有任何的修改。安全模式的目的是在系统启动时检查各个DataNode 上数据块的有效性,同时根据策略对数据块进行必要的复制和删除,当数据块的最小百分比数满足配置的最小副本数条件时,会自动退出安全模式。 wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfsadmin-safemodeleave (3)进入安全模式 wu@ubuntu:~/opt/hadoop-0.20.2$bin/hadoopdfsadmin-safemodeenter (4)添加节点 可扩展性是HDFS的一个重要的特性,向HDFS集群中添加节点是很容易实现的。添加一个新的DataNode节点,首先在新加的节点上安装好hadoop,要和NameNode使用相同的配置,修改HADOOP_HOME/conf/master文件,加入NameNode主机名。然后在NameNode节点上修改HADOOP_HOME/conf/slaves文件,加入新节点主机名。再建立到新节点无密码SSH连接,运行启动命令: $ bin/start-all.sh 通过http://(主机名):50070可查看到新的DataNode节点添加成功 (5)负载均衡 用户可以使用下面的命令来重新平衡DataNode上的数据块的分布: $ bin/start-balancer.sh 本文作者:佚名 来源:51CTO

优秀的个人博客,低调大师

【翻译+整理】.NET Core的介绍

.NET Core 是一个通用开发平台,它由微软和开源社区共同管理(git hub的.NET开源社区); 他支持Windows,macOS和Linux,并且可以运行在硬件设备中、云平台上和物联网嵌入式设备中; .NET Core的主要标志性特征如下: 弹性部署:他可以运行在你的应用内部,也可以被部署在一个服务器群集上; 跨平台:他可以运行在Windows,macOS和Linux上;也可以移植到其他操作系统上;被支持的操作系统、CPU和应用场景,将会随着时间推移,越来越多;未来微软和其他公司、个人都会为此做出贡献; 命令行工具:所有的产品应用都可以在命令行工具下执行 兼容性:.NET Core通过.NET标准库(.NET Standard Library)实现兼容性,其兼容.NET Framework, Xamarin 和 Mono 开源:它基于MIT 和 Apache 2开源,文档遵从CC-BY规范;.NET Core是.NET基金会的一个项目; 微软支持:微软支持.NET Core,具体信息请查阅:https://www.microsoft.com/net/core/support/ .NET Core的主要组成部分如下: .NET运行时(主要包括:类型系统、程序集加载、垃圾回收、原生程序的互操作接口、其他基础服务) 一批框架类库(主要包括:原始数据类型、应用组成类型、基础工具集) SDK工具集和语言编译器(.NET Core SDK提供最基础的开发支持) dotnet应用加载器(运行时选择器、运行时装载器、程序集加载规则、SDK工具装载器) 支持的语言如下: 可以用C# 和 F#来开发.NET Core的类库和应用; Visual Basic也将得到支持,但目前还没有; 编译器直接运行在.NET Core 中; 这样你可以随时随地编译你的.NET Core程序; (一般你不会直接使用.NET Core提供的编译器,你会直接使用SDK提供的工具来编译你的程序) 编译器可以很好的和多种不同的IDE或者文本编辑工具来结合; 比如:Visual Studio, Visual Studio Code, Sublime Text 和 Vim; 你可以到OmniSharp找到你想要的语言开发环境(注意OmniSharp是非微软官方支持的民间组织) .NET API和兼容性: .NET Core可以被理解为一个跨平台版本的.NET Framework,它处于.NET基础类库层(BCL) 它实现了.NET标准库的规范;它提供的API是.NET Framework的子集; 在某些情况下,并不是所有.NET Framework提供的类型都被.NET Core实现了; 想进一步了解.NET Core的路线图,可以看这里:https://github.com/dotnet/core/blob/master/roadmap.md 与.NET标准库(.NET Standard Library)的关系: .NET标准库是一种API技术规格, 它约束所有.NET实现必须遵从此规格, 只要遵从此规格的.NET的实现,就可以互相兼容; .NET Core是一种.NET标准库的实现; 工作内容: .NET Core自带命令行工具,可以运行独立的命令行程序、基于命令行的本地服务、基于命令行的文本游戏; 在.NET Core之上已经建立了一部分扩展应用模块,比如: ASP.NET Core Windows 10 Universal Windows Platform (UWP) Xamarin.Forms 分发方式: 官方使用两种方式分发.NET Core, 一种方式是把.NET Core的分法包发布到NuGet.org上去; 一种方式是发布独立的安装包; 你可以通过VisualStudio等工具获取.NET Core 2017年春天将发布.NET Core2.0

优秀的个人博客,低调大师

Android 动画使用的笔记整理

//=================【frame animation 帧动画】=============================== Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画。 Frame动画可以被定义在XML文件中,也可以完全编码实现。(animation-list,标签内容没有提示,就手动添加) 《studio 中 需要在drawable里边创建 frame动画的文件。animation-list》 实现方法两种: 1)xml中的实现方法 在/res下的anim或drawable目录中(/res/[anim |drawable]/filename.xml), 文件名可以作为资源ID在代码中引用; 1、[xml文件的语法] <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list> <item>元素代表一帧动画,android:drawable指定此帧动画所对应的图片资源,android:druation代表此帧持续的时间,整数,单位为毫秒。 Android:onshot如果定义为true的话,此动画只会执行一次,如果为false则一直循环。 2、图片放于drawable目录 ImageView image = (ImageView) findViewById(R.id.frame_image); image.setBackgroundResource(R.anim.frame); //将动画资源文件设置为ImageView的背景 //or xml.布局中,android:background="@anim/mywifi_animation" / //获取ImageView背景,此时已被编译成AnimationDrawable AnimationDrawable anim = (AnimationDrawable) image.getBackground(); anim.start(); //开始动画 在onCreate中调用AnimationDrawable的start方法时,窗口Window对象还没有完全初始化, AnimationDrawable不能完全追加到窗口Window对象中,那么该怎么办呢? 我们需要把这段代码放在onWindowFocusChanged方法中,当Activity展示给用户时,onWindowFocusChanged方法就会被调用,我们正是在这个时候实现我们的动画效果。 当然,onWindowFocusChanged是在onCreate之后被调用的,如图: public void stopFrame(View view) { if (anim.isRunning()) { //如果正在运行,就停止 anim.stop(); } } 2)Java代码实现的帧动画 public void runFrame(View view) { //完全编码实现的动画效果 AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //根据资源名称和目录获取R.java中对应的资源ID int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); //根据资源ID获取到Drawable对象 Drawable drawable = getResources().getDrawable(id); //将此帧添加到AnimationDrawable中 anim.addFrame(drawable, 300); } anim.setOneShot(false); //重复的次数 image.setBackgroundDrawable(anim); //将动画设置为ImageView背景 anim.start(); //开始动画 } //===========【Tween Animation:(补间动画)】================= 补间动画就是我们只需指定开始、结束的“关键帧“,而变化中的其他帧由系统来计算,不必自己一帧帧的去定义。 四种子类:AlphaAnimation(透明度动画)、ScaleAnimation(缩放动画)、TranslateAnimation(位移动画)、RotateAnimation(旋转度动画)。 /* 1.动画时间 duration 2.是否循环 3.开始位置坐标 4. 动画属性 ,由快到慢 etc */ AnimationSet animationSet = new AnimationSet(true); AlphaAnimation:淡入淡出动画 // 动画1:透明度变化: 1.0 fully opaque 完全不透明;0.0 fully transparent 完全透明 AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); alphaAnimation.setDuration(2000);// 持续时间 animationSet.addAnimation(alphaAnimation); imageView.startAnimation(animationSet); TranslateAnimation:位移动画 // 平移动画设置 TranslateAnimation translateAnimation = new TranslateAnimation(0, 150, 0, 0); // new TranslateAnimation( // Animation.RELATIVE_TO_SELF, 10f, Animation.RELATIVE_TO_SELF, 50.0f, // Animation.RELATIVE_TO_SELF, 10f, Animation.RELATIVE_TO_SELF, 50.0f); translateAnimation.setDuration(2000); translateAnimation.setInterpolator(new AccelerateInterpolator()); /** * TranslateAnimation * @setFillAfter的设置如果为true,则动画执行完之后效果定格在执行完之后的状态 * @setFillBefore的设置如果为true,则动画执行完之后效果定格在执行完之前的状态 * @setStartOffset设置的是一个long类型的值,是指动画延迟多少毫秒之后执行 * @setRepeatCount定义的是动画重复几次执行 */ translateAnimation.setRepeatCount(3); translateAnimation.setStartOffset(2000); animationSet.setFillAfter(false); animationSet.setFillBefore(true); animationSet.addAnimation(translateAnimation); imageView.startAnimation(animationSet); ScaleAnimation:缩放动画 // 前四个参数,x、y方向上从什么倍数缩放到什么倍数,后面四个参数是相对在什么位 // 置进行缩放。跟平移差不多一个意思 ScaleAnimation scaleAnimation = new ScaleAnimation(1, 0.1f, 1, 0.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); scaleAnimation.setDuration(2000); animationSet.addAnimation(scaleAnimation); imageView.startAnimation(scaleAnimation); RotateAnimation:旋转动画 // 后面的四个参数定义的是旋转的圆心位置 RotateAnimation rotateAnimation = new RotateAnimation(0, -359, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotateAnimation.setDuration(2000); rotateAnimation.setInterpolator(new LinearInterpolator());//恒定变化 rotateAnimation.setRepeatCount(-1); animationSet.addAnimation(rotateAnimation); imageView.startAnimation(animationSet); 以上是java的实现: //--------------------------------------------------------------- 以下是xml的实现补间动画的方法tween //res/anim 文件夹建立 *.xml动画的文件, 格式如下 <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="false" android:fillBefore="true"> <alpha android:duration="2000" android:fromAlpha="1.0" android:toAlpha="0" /> <!-- 透明度控制动画效果 alpha 浮点型值: fromAlpha 属性为动画起始时透明度 toAlpha 属性为动画结束时透明度 说明: 0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之间的float数据类型的数字 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 --> <translate android:duration="1000" android:fromXDelta="-50%p" android:toXDelta="0" /> <!-- translate 位置转移动画效果 整型值: fromXDelta 属性为动画起始时 X坐标上的位置 toXDelta 属性为动画结束时 X坐标上的位置 fromYDelta 属性为动画起始时 Y坐标上的位置 toYDelta 属性为动画结束时 Y坐标上的位置 注意: 不管是100%还是100%p,都应该是以控件所在的位置为起始点开始 没有指定fromXType toXType fromYType toYType 时候,默认是以自己为相对参照物 android:toXDelta="100%",表示自身的100%,也就是从View自己的位置开始。 android:toXDelta="80%p",表示父层View的80%,是以它父层View为参照的。 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 --> <rotate android:duration="3000" android:fromDegrees="0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toDegrees="+1080" /> <!-- rotate 旋转动画效果 浮点数型值: fromDegrees 属性为动画起始时物件的角度 toDegrees 属性为动画结束时物件旋转的角度 可以大于360度 说明: 当角度为负数――表示逆时针旋转 当角度为正数――表示顺时针旋转 (负数from――to正数:顺时针旋转) (负数from――to负数:逆时针旋转) (正数from――to正数:顺时针旋转) (正数from――to负数:逆时针旋转) pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 说明: 都是以物件所在的位置起始点 以上两个属性值 从0%-100%中取值 50%:物件的X或Y方向坐标上物件长度的一半的距离 50%p为物件在X或Y方向坐标上屏幕的一半的距离 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 --> <scale android:duration="5000" android:fromXScale="0.0" android:fromYScale="0.0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toXScale="4.0" android:toYScale="4.0" /> <!-- 尺寸伸缩动画效果 scale android:fillAfter="true" 动画停留在最后一帧。只在<set />里面在有作用 属性:interpolator 指定一个动画的插入器 使用android.res.anim中的资源时候发现有三种动画插入器 accelerate_decelerate_interpolator 加速-减速 动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator 减速- 动画插入器 其他的属于特定的动画效果 浮点型值: fromXScale 属性为动画起始时 X坐标上的伸缩尺寸 toXScale 属性为动画结束时 X坐标上的伸缩尺寸 fromYScale 属性为动画起始时Y坐标上的伸缩尺寸 toYScale 属性为动画结束时Y坐标上的伸缩尺寸 说明: 以上四种属性值 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大 pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 说明: 都是以物件所在的位置起始点 以上两个属性值 从0%-100%中取值 50%:物件的X或Y方向坐标上物件长度的一半的距离 50%p为物件在X或Y方向坐标上屏幕的一半的距离 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 布尔型值: fillBefore是指动画结束时画面停留在第一帧, fillAfter是指动画结束是画面停留在最后一帧。 最关键的问题是,这2个参数不能在</alpha>,</scale>,</translate>,</rotate>中设置,这是没有用的,必须 在动画xml文件的</set>节点中设置 fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用 startOffset, 动画多次执行的间隔时间,如果只执行一次,执行前会暂停这段时间, 单位毫秒 duration,一次动画效果消耗的时间,单位毫秒, 值越小动画速度越快 repeatCount,动画重复的计数,动画将会执行该值+1次 repeatMode,动画重复的模式,reverse为反向,当第偶次执行时,动画方向会相反。 restart为重新执行,方向不变 --> </set> //载入xml动画 //Animation animation = AnimationUtils.loadAnimation(ActivityMain.this, R.anim.name); AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(this, R.anim.tweentest); // 载入XML文件成Animation对象 view.startAnimation(animation); //动画的监听方法 int i = 0; for (Animation a : set.getAnimations()) { Log.e(TAG, " a = " + i++); if (i == 1) a.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { Log.e(TAG, " start "); } @Override public void onAnimationRepeat(Animation animation) { Log.e(TAG, " repeat "); } @Override public void onAnimationEnd(Animation animation) { Log.e(TAG, " end "); } }); } Activity 入场动画 Intent intent = new Intent(Activity01.this,Activity02.class); startActivity(intent); //1.启动的Activity02的动画;2.当前退出的Activity01的动画 overridePendingTransition(R.anim.myint,R.anim.alpha); //===========【Property Animation:(属性动画)】================= Android 3.0中才引进 :直接更改我们对象的属性 (1)ValueAnimator:包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。应用ValueAnimator有两个步骤 1计算属性值。 2根据属性值执行相应的动作,如改变对象的某一属性。 我们的主是第二步,需要实现ValueAnimator.onUpdateListener接口,这个接口只有一个函数onAnimationUpdate(),将要改变View对象属性的事情在该接口中do。 animation.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //do your work } }); (2)ObjectAnimator:继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,应该满足以下条件: 1.对象应该有一个setter函数:set(驼峰命名法) 2如下面的例子,像ofFloat之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数只设置了一个值的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法:get 3如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。 ObjectAnimator oa=ObjectAnimator.ofFloat(tv, alpha, 0f, 1f); oa.setDuration(3000); oa.start(); 如果不满足上面的条件,我们只能乖乖的使用ValueAnimator来创建动画。 (3)Animator.AnimatorListener:可以为Animator设置动画监听,需要重写下面四个方法。 onAnimationStart() onAnimationEnd() onAnimationRepeat() onAnimationCancel() 三种动画的优缺点: (1)Frame Animation(帧动画)主要用于播放一帧帧准备好的图片,类似GIF图片,优点是使用简单方便、缺点是需要事先准备好每一帧图片; (2)Tween Animation(补间动画)仅需定义开始与结束的关键帧,而变化的中间帧由系统补上,优点是不用准备每一帧,缺点是只改变了对象绘制,而没有改变View本身属性。因此如果改变了按钮的位置,还是需要点击原来按钮所在位置才有效。 (3)Property Animation(属性动画)是3.0后推出的动画,优点是使用简单、降低实现的复杂度、直接更改对象的属性、几乎可适用于任何对象而仅非View类,缺点是需要3.0以上的API支持,限制较大!但是目前国外有个开源库,可以提供低版本支持! 三种动画的demo下载地址: Frame动画简单的应用演示 http://download.csdn.net/detail/flyingsir_zw/9541211 Activity入场动画合集 积 分:1437上传资源:44下载资源:98总 排 名:第9346名上传权限:100MB

优秀的个人博客,低调大师

Hadoop I/O操作原理整理

I/O操作中的数据检查 校验和方式是检查数据完整性的重要方式。一般会通过对比新旧校验和来确定数据情况,如果两者不同则说明数据已经损坏。比如,在传输数据前生成了一个校验和,将数据传输到目的主机时再次计算校验和,如果两次的校验结果不同,则说明数据已经损坏。因为Hadoop采用HDFS作为默认的文件系统,因此具有两方面的数据完整性。 1、本地文件I/O的检查 本地文件系统的数据完整性由客户端负责,重点是在存储和读取文件时进行校验和的处理。每当Hadoop创建文件a时,Hadoop就会同时在同一文件夹下创建隐藏文件a.crc,这个文件记录了文件a的校验和。针对数据文件的大小,每512字节Hadoop就会生成一个32位的校验和(4字节)。 2、对HDFS的I/O数据进行检查 DataNode接收数据后,存储数据前。它接收数据一般有两种情况:一是用户从客户端上传数据;二是DataNode从其他DataNode上接收数据。Hadoop不会在数据每流动到一个DataNode时都检查校验和,它只会在数据流动到最后一个节点时检验校验和。 3、在MapReduce程序中使用压缩 设置Map处理后数据的压缩代码示例如下: JobConf conf = new JobConf(); conf.setBoolean("mapred.compree.map.output",true); //设置output输出压缩 conft.setBoolean("mapred.output.compress",true); conf.setClass("mapred.output.compression.codec",GzipCodec.class,CompressionCodec.class); 4、数据的I/O中序列化操作 序列化是将对象转化为字节流的方法,或者说用字节流描述对象的方法。与序列化相对的是反序列化,反序列化是将字节流转化为对象的方法。序列化有两个目的:进程间通信;数据持久性存储。 Hadoop采用RPC来实现进程间通信,一般而言,RPC的序列化机制有以下特点: 紧凑:紧凑的格式可以充分利用带宽,加快传输速度。 快速:能减少序列化和反序列化的开销,这会有效减少进程间通信的时间。 可扩展:可以逐步改变。 在Hadoop中,并没有采用JAVA提供的序列化机制,而是自己重新写了一个序列化机制Writables。Writables具有紧凑、快速的优点。但不易拓展。 Text 这是Hadoop中对string类型的重写,但是又与其有一些不同。Text使用标准的UTF-8编码,同时Hadoop使用变长类型VInt来存储字符串,其存储上线是2GB。Text类型与String类型的主要差别在于: 1、 Stirng的长度定义为String包含的字符个数;Text的长度定义为UTF-8编码的字节数。 2、String内的indexOf()方法返回的是char类型字符的索引。Text的find()方法返回的是字节偏移量。 3、String的charAt()方法返回的是指定位置的char字符;而Text的charAT()方法需要指定偏移量。 SequenceFile类 SequenceFile记录的是key/value对的列表,是序列化之后的二进制文件,因此是不能直接查看的。可通过:hadoop fs -text mySequenceFile查看 参考:《Hadoop实战》

优秀的个人博客,低调大师

Android 高级面试题目整理

阿里云双十一拼团活动:https://www.aliyun.com/1111/2019/group-buying-share 1. ThreadLocal的理解 可以保证线程的安全。在多个线程共享相同的数据的时候,会为每个线程创建单独的副本,在单独的副本上进行数据的操作,不会对其它线程的数据产生影响,保证了线程安全。 2. HashMap HashSet HashTable的区别? 都是集合,底层都是Hash算法实现的。HashMap是Hashtable的替代品,这两个都是双列集合,而HashSet是单列集合。HashMap线程不安全、效率高、可以存储null键和null值;Hashtable线程安全,效率低,不可以存储null键和null值。 3. 如何让HashMap可以线程安全? HashMap 在并发执行 put 操作时会引起死循环,导致 CPU 利用率接近100%。因为多线程会导致 HashMap 的 Node 链表形成环形数据结构,一旦形成环形数据结构,Node 的 next 节点永远不为空,就会在获取 Node 时产生死循环。使用下面三种替换方式:HashtableConcurrentHashMapSynchronized Map 4. Android对HashMap做了优化后推出的新的容器类是什么? SparseArray它要比 HashMap 节省内存,某些情况下比HashMap性能更好,按照官方问答的解释,主要是因为SparseArray不需要对key和value进行auto-boxing(将原始类型封装为对象类型,比如把int类型封装成Integer类型),结构比HashMap简单(SparseArray内部主要使用两个一维数组来保存数据,一个用来存key,一个用来存value)不需要额外的额外的数据结构(主要是针对HashMap中的HashMapEntry而言的)。 5. Java多线程之间如何通信 等待唤醒机制 6. 线程池的实现机制 向线程池提交任务,会依次启动核心线程,如果提交的任务数超过了核心线程数,会将任务保存到阻塞队列中,如果阻塞队列也满了,且继续提交任务,则会创建新线程执行任务,直到任务数达到最大线程数。此时如果再提交任务的话会抛出异常或者直接丢弃任务。通过Executor.execute()无法得到返回值,通过ExecutorService.submit()可以得到返回值。 7. RxJava中map和flatmap操作符的区别及底层实现 Map返回的是结果集,flatmap返回的是包含结果集的Observable。Map只能一对一,flatmap可以一对多、多对多。RxJava是通过观察者模式实现的。 8. 对消息机制中Looper的理解 Looper在消息机制中扮演的角色是创造无限循环从Messagequeue中取得消息然后分发。 9. 单例模式有哪些实现方式 饿汉模式(线程安全,调用效率高,但是不能延时加载)懒汉模式(线程安全,调用效率不高,但是能延时加载)双重检测锁模式(由于JVM底层模型原因,偶尔会出问题,不建议使用)静态内部类式(线程安全,调用效率高,可以延时加载)枚举类(线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用) 10. 通过静态内部类实现单例模式有哪些优点 线程安全,调用效率高,可以延时加载 11. synchronized volatile关键字有什么区别?以及还有哪些同样功能的关键字 (1) volatile是变量修饰符,而synchronized则作用于一段代码或者方法。(2) volatile只是在线程内存和main memory(主内存)间同步某个变量的值;而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。const、final、lock 12. 界面卡顿的原因有哪些? UI线程(main)有耗时操作视图渲染时间过长,导致卡顿 13. 造成OOM/ANR 的原因? OOM: (1)不恰当地使用static关键字 (2)内部类对Activity的引用 (3)大量Bitmap的使用会导致程序包运行时的内存消耗变大 (4)游标Cursor对象用完应该及时关闭 (5)加载对象过大 (6)相应资源过多,来不及释放。ANR: (1)在5秒内没有响应输入的事件(IO操作耗时、数据库操作复杂耗时、主线程非主线程产生死锁等待、网络加载/图片操作耗时、硬件操作耗时) (2)BroadcastReceiver在10秒内没有执行完毕(Service binder数量达到上限、Service忙导致超时无响应) 14. Activity与Fragment生命周期有何联系 在创建的过程中,是Activity带领着Fragment,在销毁的过程中,是Fragment带领着Activity。这里写图片描述 15. Glide三级缓存 内存缓存,磁盘缓存、网络缓存(由于网络缓存严格来说不算是缓存的一种,故也称为二级缓存)。缓存的资源分为两种:原图(SOURCE)、处理图(RESULT)(默认)。内存缓存:默认开启的,可以通过调用skipMemoryCache(true)来设置跳过内存缓存,缓存最大空间:每个进程可用的最大内存*0.4。(低配手机0.33)磁盘缓存:分为四种:ALL(缓存原图)、NONE(什么都不缓存)、SOURCE(只缓存原图)、RESULT(之后处理图),通过diskCacheStrategy(DiskCacheStrategy.ALL)来设置,缓存大小250M。 16. MVC、MVP、MVVM的原理 (1) MVC,Model View Controller,是软件架构中最常见的一种框架,简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示。当用户发出事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。这里写图片描述(2) MVP是MVC的演化。MVP的model层相对于MVC是一样的,而activity和fragment不再是controller层,而是纯粹的view层,所有关于用户事件的转发全部交由presenter层处理。presenter层充当了桥梁的作用,用于操作view层发出的事件传递到presenter层中,presenter层去操作model层,并且将数据返回给view层。这里写图片描述(3) MVVM和MVP的区别貌似不大,只不过是presenter层换成了viewmodel层,还有一点就是view层和viewmodel层是相互绑定的关系,这意味着当你更新viewmodel层的数据的时候,view层会相应的变动ui。这里写图片描述 17. 数据库的操作类型有哪些,如何导入外部数据库? (1) 增删改查(2) 将外部数据库放在项目的res/raw目录下。因为安卓系统下数据库要放在data/data/packagename/databases的目录下,然后要做的就是将外部数据库导入到该目录下,操作方法是通过FileInputStream读取外部数据库,再用FileOutputStrean把读取到的东西写入到该目录下。 18. 是否使用过 IntentService,作用是什么, AIDL 解决了什么问题? (1) IntentService继承自Service。由于Service运行在主线程,无法进行耗时操作。所以你需要在Service中开启一个子线程,并且在子线程中运行。为了简化这一操作,Android中提供了IntentService来进行这一处理。通过查看IntentService的源码可以看到,在onCreate中,我们开启了一个HandlerThread线程,之后获取HandlerThread线程中的Looper,并通过这个Looper创建了一个Handler。然后在onStart方法中通过这个Handler将intent与startId作为Message的参数进行发送到消息队列中,然后交由Handler中的handleMessage中进行处理。由于在onStart方法是在主线程内运行的,而Handler是通过工作者线程HandlerThread中的Looper创建的。所以也就是在主线程中发送消息,在工作者接收到消息后便可以进行一些耗时的操作。(2) 进程间通信 19. 是否使用过本地广播,和全局广播有什么差别? 本地广播的数据在本应用范围内传播,不用担心隐私数据泄露的问题。不用担心别的应用伪造广播,造成安全隐患。相比在系统内发送全局广播,它更高效。 20. Activity、 Window、 View 三者的差别, fragment 的特点? (1) Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸。(2) a. Fragment可以作为Activity界面的一部分组成出现; 可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用; 在Activity运行过程中,可以添加、移除或者替换Fragment; Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。 21. Handler、 Thread 和 HandlerThread 的差别 从Android中Thread(java.lang.Thread -> java.lang.Object)描述可以看出,Android的Thread没有对Java的Thread做任何封装,但是Android提供了一个继承自Thread的类HandlerThread(android.os.HandlerThread -> java.lang.Thread),这个类对Java的Thread做了很多便利Android系统的封装。android.os.Handler可以通过Looper对象实例化,并运行于另外的线程中,Android提供了让Handler运行于其它线程的线程实现,也是就HandlerThread。HandlerThread对象start后可以获得其Looper对象,并且使用这个Looper对象实例Handler。 22. 低版本 SDK 实现高版本 api 自己实现或使用注解@TargetApi annotation 23. launch mode 应用场景 (1) standard:标准的启动模式。 这里写图片描述(2) singleTop:单一顶部模式 如果Activity已经被开启,并且处于任务栈的栈顶,就不会创建新的Activity,而是复用这个已经开启的Activity。为了防止出现一些奇怪的用户体验,推荐使用单一顶部模式,整个任务栈可以有多个实例存在.应用场景:短信发送界面.这里写图片描述(3)singletask:单一任务栈 在整个任务栈里面只允许有一个当前Activity的实例存在如果要开启的Activity在任务栈中已经存在,直接复用这个已经存在的Activity,并且把这个Activity上面的所有的其他Activity给清空应用场景:如果一个Activity非常消耗内存和cpu资源,建议把这个Activity做成singletask的模式。浏览器的browserActivity这里写图片描述(4)singleinstance:单一实例. 整个手机操作系统只有一个实例存在,并且是运行在自己单独的任务栈里面.应用场景:通话界面的Activity这里写图片描述 24. touch 事件传递流程 事件处理包括三种情况,分别为:传递—-dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费—-onTouchEvent()函数和OnTouchListener。Android事件传递流程:(1) 事件都是从Activity.dispatchTouchEvent()开始传递(2) 事件由父View传递给子View,ViewGroup可以通过onInterceptTouchEvent()方法对事件拦截,停止其向子view传递(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数。(4) 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来,也就是说ACTION_DOWN必须返回true,之后的事件才会传递进来(5) OnTouchListener优先于onTouchEvent()对事件进行消费 View不处理事件流程图View不处理事件流程图 View处理事件流程图View处理事件流程图 事件拦截事件拦截 25.Android性能优化 一、代码优化 1.使用AndroidLint分析结果进行相应优化2.不使用枚举及IOC框架,反射性能低3.常量加static4.静态方法5.减少不必要的对象、成员变量6.尽量使用线程池7.适当使用软引用和弱引用8.尽量使用静态内部类,避免潜在的内存泄露9.图片缓存,采用内存缓存LRUCache和硬盘缓存DiskLRUCache10.Bitmap优化,采用适当分辨率大小并及时回收 二、布局优化 避免OverDraw过渡绘制优化布局层级避免嵌套过多无用布局当我们在画布局的时候,如果能实现相同的功能,优先考虑相对布局,然后在考虑别的布局,不要用绝对布局。使用标签把复杂的界面需要抽取出来使用标签,因为它在优化UI结构时起到很重要的作用。目的是通过删减多余或者额外的层级,从而优化整个Android Layout的结构。核心功能就是减少冗余的层次从而达到优化UI的目的!ViewStub 是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件。 三、ListView和GridView优化 1.采用ViewHolder复用convertView2.避免在getView中执行耗时操作3.列表在滑动状态时不加载图片4.开启硬件加速 26.Android内存泄漏 内存泄漏简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄露了。可能的原因有:1.注册没取消造成内存泄露,如:广播2.静态变量持有Activity的引用3.单例模式持有Activity的引用4.查询数据库后没有关闭游标cursor5.构造Adapter时,没有使用 convertView 重用6.Bitmap对象不在使用时调用recycle()释放内存7.对象被生命周期长的对象引用,如activity被静态集合引用导致activity不能释放8.使用Handler造成的内存泄露 原文地址:http://cloud.yundashi168.com/archives/964

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。