最近文章

给本地localhost域名添加https证书

本文介绍如何给本地域名localhost添加证书,但此方法仅限在开发环境使用。在生产环境中,强烈禁止使用自签名证书。创建认证中心(Certificate authority,CA)生成RootCA.pem, RootCA.key 以及 RootCA.crt:openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyo
标签:

升级到Ionic 5报错Error: Angular JIT compilation failed: '@angular/compiler' not loaded!

一个app使用的是Ionic以及angular开发的,升级到Ionic 5,angular 9。升级如下:npm install @ionic/angular@latest @ionic/angular-toolkit@latest --save-exact --saveng update @angular/core @angular/cli运行时报错:Error: Angular JIT com
标签:

CentOS查看软件安装路径及环境变量

在Linux下,我们经常要查看软件的安装路径以及查看设置环境变量。CentOS查看软件安装路径1、通过rpm查看查看软件是否安装。首先我们需要查看软件是否已经安装,或者说查看安装的软件包名称。如查找是否安装mysql$rpm -qa| grep mysql 2、接着根据 rpm -ql 列出软件包安装的文件rpm -ql mysql-libs-5.1.71-1.e16.x86_643、综合上述以上
标签:

Linux 系统用户账号的管理

1. 用户账号的优势 帮助系统管理员对使用系统的用户进行跟踪 控制用户对系统资源的访问 帮助用户组织文件,为用户提供安全保护 2. 添加新的用户添加命令useradd 选项 用户名常用选项-d<目录>, 设置用户主目录,默认值为用户的登录名,并放在 /home 目录下;如果此目录不存在,则同时使用 -m 选项,可以创建主目录。-g<用户组>,指
标签:

解决Android Studio 出现 unable to access android sdk add-on list的方法

出现这个提示的原因主要是因为电脑第一次安装 Android Studio,启动后 Android Studio 没有检测到电脑有 SDK ,所以才有这个提示,unable to access android sdk add-on list下面说一下解决方法:解决方法如果是 windows 系统,在 Android Studio 的安装目录下,找到 binidea.properties 文件。如果是
标签:

CentOS7启动及排错

UEFi或BIOS初始化,运行POST开机自检 选择启动设备 引导装载程序, centos7是grub2 加载装载程序的配置文件:/etc/grub.d//etc/default/grub/boot/grub2/grub.cfg 加载initramfs驱动模块加载内核选项 内核初始化,centos7使用systemd代替init 执行initrd.target所有
标签:

ScheduledExecutorService方法scheduleAtFixedRate与scheduleWithFixedDelay的区别

先看ScheduledExecutorService类的scheduleAtFixedRate()和scheduleWithFixedDelay()的方法签名。scheduleAtFixedRatepublic ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
标签:

Tomcat 8.5新安装环境初步配置优化

下载安装Tomcatwget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.gztar zxf apache-tomcat-8.5.37.tar.gz -C /usr/localmv /usr/local/apache-tomcat-8.5.37 /usr/local/t
标签:

systemctl解决Nginx奔溃后实现自动重启

解决程序奔溃自动重启是Systemd的一个特性,它有一组命令构成,涉及到系统管理的方方面面。其中systemctl是 Systemd 的主命令,用于管理系统。我们使用Systemd的自动重启特性,来实现nginx奔溃后自动重启。执行命令:systemctl edit nginx在[Service]节点上修改如下:[Service]Restart=alwaysRestartSec=1Type=for
标签:

MySQL使用NOT IN存在null值导致结果错误的解决方法

house表:create table house (address varchar(200) not null, heating varchar(50));表中有两个字段,address地址,不能为null,凉爽程度heating 可以为null。插入记录:insert into house values ('A', null),('B','hot');in查询语句:select address
标签:

Java判断ip是否属于指定的ip网段

同一网段的ip是有相同的网络标识。ip地址和子网掩码做“与”运算的到的结果为网络标识比如两个IP:172.16.1.100(子网掩码:255.255.0.0)和172.16.2.100(子网掩码:255.255.0.0)。首先把ip地址和子网掩码转换为二进制,做与运算,然后转换为十进制,得到的结果为:172.16.0.0。所以可以说这两个ip是属于172.16.0.0网段。网段表示方式172.16
标签:

Nginx重定向http到https

Nginx重定向http到https:方法一【推荐】使用响应码301,301内容参考HTTP 301 Moved Permanently。server {     listen         [::]:80;  &nb
标签:

Windows MySQL5.7.19安装失败:This application requires Visual Studio 2013 Redistributable

已安装Visual Studio 2013 Redistributable,安装MySQL5.7.19时报错。错误信息:1: Action 13:23:11: INSTALL. 1: 1: MySQL Server 5.7 2: {F08E9C75-A42E-4962-8760-
标签:

【Java面试题】不使用if-else等条件语句,如果输入值为1返回0,输入值为0返回1

Java 面试题:不使用条件语句实现方法,输入值为0返回1,输入值为1返回0。答案1return 1 - value; 答案2使用异或运算^return value ^ 1;
标签:

关于Java异常

在这篇博文里,我们思考下检查异常 (checked exception)和非检查异常(unchecked exception),特别是它们在函数式编程里的影响。十几年前Java出现时,在当时它是相当有创意的。特别是它的异常处理机制,相对先前的C/C++有了很大的提高。例如,读取文件可以出现很多异常:文件可以不存在,可以为只读等等。相关Java的伪代码类似于:File&
标签:

使用Tomcat需要掌握的基本内容

首先要知道:Tomcat是一个Servlet/JSP容器。Tomcat作为一个Web应用服务器软件,它的核心功能是实现由JCP(Java Community Process)制定的Java Servlet,(JSP)JavaServer Pages, (EL)Java Expression Language 和&nbs
标签:

Red Hat/CentOS的Nginx升级

在Linux系统,尽量不需要使用源码编译来安装软件,这样容易和系统的包管理混淆。此次升级是nginx1.0.15升级到nginx1.12.1升级前查看nginx版本$ nginx -v nginx version: nginx/1.0.15 查看系统版本# lsb_release -a LSB Version:  :base-4
标签:

Nginx gzip对javascript文件压缩无效

问题Nginx从1.0.15升级到1.12.1后,原来开启的gzip对javascript文件压缩失效了。原来nginx的gzip相关配置如下gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 2; gzip_types text/plain applicati
标签:

【Android Instant App】报错:Your Instant App APKs contain the domain 'xxx.com' that is already in use by another app

问题两个Android的Instant App使用相同的域名报错:Your Instant App APKs contain the domain 'xxx.com' that is already in use by another ap
标签:

MacOSX启动XAMPP-VM报错:Error starting "XAMPP" stack: cannot calculate MAC address: signal: killed

问题在MacOS启动xampp-vm时报错:INFO: Starting "XAMPP" stackERROR: Error starting "XAMPP" stack: cannot calculate MAC address: sig
标签:

CentOS安装JDK

CentOS下有三种方式安装JDK。下载压缩包安装1. 下载压缩包参考Linux使用wget和curl下载jdk。2. 新建安装目录,并解压安装包到安装目录[root@iZ9 ~]# mkdir/usr/java [root@iZ9 ~]# cd /usr/java [root@iZ9 ~]#  tar -zxvf jdk-8u
标签:

Angular Material2报错:'md-form-field' is not a known element

问题使用Angular Material 2的md-form-field报未知元素的错误。错误信息如下:Uncaught Error: Template parse errors: 'md-form-field' is not a known element:  1. 
标签:

Android Instant App报错:Your site 'xxxxx.com' has not been linked through the Digital Assets Link protocol to your app

问题上传Android的Instant app时报错:Your site 'xxxxx.com' has not been linked through the Digital Assets Link protocol to your ap
标签:

Android Gradle报错:Failed to resolve: com.google.android.gms:play-services:11.2.0

问题更新com.google.android.gms:play-services到11.2.0后报错:Error:(20, 10) Failed to resolve: com.google.android.gms:play-services:11.2.0Install Repository and sync 
标签:

AngularJS非字符插值计算规则

在AngularJS里,插值会把嵌入的表达式转换为字符串,对于非字符串转换规则如下:1、undefined和null转换为空字符串''。2、如果值是一个Object对象,但不是Number,Date和Array类型,$interpolate变量会先查找用户自定义的toString()函数,如果找到了,使用toString()函数来转换为字符串。注意,这里的用户自定义意味myObject.toStr
标签:

Java 数值相等判断详解(特别注意包装类型之间的比较)

Java数值类型分为基本类型,包装类型。基本类型:byte、short、 int、long、float和double包装类型:Byte、Short、Integer、Long、Float和Double数值比较可分为基本类型之间比较,基本类型与包装类类型比较,包装类型之间的比较。基本类型比较基本类型之间只能使用“==”做相等比较。比较结果就是数值是否相等。int a=1, 
标签:

Linux使用wget和curl下载jdk

在Linux下安装jdk主要有两种方式:下载安装包手动安装和使用Linux的安装工具(yum或ubuntu的apt)安装。使用Linux安装工具安装的是OpenJDK,如果我们想安装oracle的JDK则需要下载安装包手动安装。下载Oracle JDK需要接受license,在Linux可以使用wget和curl来下载Wget下载Java 8u15164位的tar.gz和rpm
标签:

查看MySQL数据库空间使用情况

information_schema是MySQL的系统数据库,information_schema里的tables表存放了整个数据库各个表的使用情况。可以使用sql来统计出数据库的空间使用情况,相关字段:table_schema:数据库名table_name:表名table_rows:记录数data_length:数据大小index_length:索引大小统计表使用空间mysql> select
标签:

Java HTTP代理设置以及认证

代理设置java http/https设置代理有两种方式:使用系统属性设置以及使用Proxy设置。使用系统属性设置代理String PROXY_HOST = "127.0.0.1";//代理服务器地址 String PROXY_PORT = "80";//代理服务器端口   //HTTP代理 System.setProperty("http.proxyHost", PROXY_HOST); Sy
标签:

Angular CLI 新建Bootstrap项目报Bootstrap dropdown require Popper.js错误

问题基于Angular cli新建bootstrap项目,angular-cli.json的script配置如下:"scripts": [ "../node_modules/jquery/dist/jquery.slim.min.js", "../node_modules/bootstrap/dist/js/bootstrap.min.js", "../node_modules/pop
标签:

给本地localhost域名添加https证书

本文介绍如何给本地域名localhost添加证书,但此方法仅限在开发环境使用。在生产环境中,强烈禁止使用自签名证书

创建认证中心(Certificate authority,CA)

生成RootCA.pem, RootCA.key 以及 RootCA.crt:

openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

Example-Root-CA是一个用例的名称,实际使用中可以把它为你自己要的名字。

域名证书

假设有两个本地机器域名fake1.local和fake2.local,这两个域名使用hosts文件将其指向127.0.0.1。

创建domains.ext列出所有的本地域名:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = fake1.local
DNS.3 = fake2.local

生成localhost.key, localhost.csr以及localhost.crt文件:

openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=CN/ST=Guandong/L=Shenzhen/O=Example-Certificates/CN=localhost.local"
openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt

示例里的省份,城市可以替换为自己的地址。

配置webserver,这里的示例使用的是apache:

SSLEngine on
SSLCertificateFile "C:/example/localhost.crt"
SSLCertificateKeyFile "C:/example/localhost.key"

信任本地CA

站点加载有关自签名证书时会有警告。为了获得绿色锁,必须将新的本地CA添加到受信任的根证书颁发机构。

Windows 10: Chrome, IE11 以及 Edge

Windows 10是能识别.crt文件,右键RootCA.crt文件,然后执行安装,就会弹出导入证书的窗口。

这样Chrome,IE11以及Edge就会显示绿色锁。

Window10:Firefox

对于Firefox,有两种方法来让浏览器信任我们自签名的证书:

1、在浏览器的地址栏,打开about:config,把security.enterprise_roots.enabled 设置为true。

2、在浏览器导入证书:

在地址栏输入about:preferences#privacy > 证书(Certificats) > 导入(Import) > RootCA.pem > 确定网站

升级到Ionic 5报错Error: Angular JIT compilation failed: '@angular/compiler' not loaded!

一个app使用的是Ionic以及angular开发的,升级到Ionic 5,angular 9。升级如下:

npm install @ionic/angular@latest @ionic/angular-toolkit@latest --save-exact --save
ng update @angular/core @angular/cli

运行时报错:

Error: Angular JIT compilation failed: '@angular/compiler' not loaded!
- JIT compilation is discouraged for production use-cases! Consider AOT mode instead.
- Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?
- Alternatively provide the compiler with 'import "@angular/compiler";' before bootstrapping.
at getCompilerFacade (core.js:610)
at Function.get (core.js:16065)
at getInjectableDef (core.js:362)
at injectableDefOrInjectorDefFactory (core.js:16816)

解决方法一(推荐)

在main.ts文件里导入@angular/compiler。

import '@angular/compiler';

方法二:

在angular.json,把"aot": true 改为 "aot: false。

方法三:

在ionic执行命令添加--aot=false:

ionic serve -- --aot=false

其中方法二和方法三是不推荐,aot会提高性能。

CentOS查看软件安装路径及环境变量

在Linux下,我们经常要查看软件的安装路径以及查看设置环境变量。

CentOS查看软件安装路径

1、通过rpm查看

查看软件是否安装。首先我们需要查看软件是否已经安装,或者说查看安装的软件包名称。如查找是否安装mysql

$rpm -qa| grep mysql

2、接着根据 rpm -ql 列出软件包安装的文件

rpm -ql mysql-libs-5.1.71-1.e16.x86_64

3、综合上述以上的问题,可以直接使用 rpm -qal |grep mysql 查看mysql所有安装包的文件存储位置

rpm -qal | grep mysql

4、yum查找

除了rpm 查询还可以通过yum search 查找对应可以安装的软件包

yum search mysql

5、其他查找方法

除了根据软件包来找文件位置之外,最常用的就是通过find查找某个关键字比如mysql所有包含mysql服务的文件路径

find / -name mysql

6、Which查找命令

Which命令是通过 PATH环境变量查找可执行文件路径,用于查找指向这个命令所在的文件夹;

which mysql

查找软件安装的目录

7、Whereis命令和find类似,不过不同的是whereis是通过本地架构好的数据库索引查找会比较快。如果没有更新到数据库里面的文件或命令则无法查找到信息

whereis mysql

8、软件是否安装;例如:jenkins是否安装

rpm -q | grep jenkins

9、可以直接使用 rpm -qal |grep mysql 查看mysql所有安装包的文件存储位置

 rpm -qal |grep jenkins #查看jenkins所有安装包的文件存储位置

注意:源码安装的方式通过rpm命令是无法找出来的

10、确定这个软件已经开启,则可以通过ps -aux |grep mysql,找出对一个的可执行文件所在的目录

[root@localhost yum.repos.d]# ps -aux |grep mysql

确定Nginx是以那个config文件启动的?

ps  -ef | grep nginx

CentOS 7设置、查看、删除环境变量的方法

centos查看环境变量与设置环境变量在使用过程中很常见,本文整理了一些常用的与环境变量相关的命令,感兴趣的朋友可以参考下希望对你有所帮助

1. 显示环境变量HOME(红色部分代表要输入的命令,#代表用户名)

$echo #HOME 
/home/redbooks

2. 设置一个新的环境变量hello

$export HELLO="Hello!" 
$echo #HELLO
Hello!

3. 使用env命令显示所有的环境变量

$env 
HOSTNAME=redbooks.safe.org
PVM_RSH=/usr/bin/rsh
Shell=/bin/bash
TERM=xterm
HISTSIZE=1000
...

4. 使用set命令显示所有本地定义的Shell变量

$set 
BASH=/bin/bash
BASH_VERSINFO=([0]="2"[1]="05b"[2]="0"[3]="1"[4]="release"[5]="i386-redhat-linux-gnu")
BASH_VERSION='2.05b.0(1)-release'
COLORS=/etc/DIR_COLORS.xterm
COLUMNS=80
DIRSTACK=()
DISPLAY=:0.0
...

5. 使用unset命令来清除环境变量

set可以设置某个环境变量的值。清除环境变量的值用unset命令。如果未指定值,则该变量值将被设为NULL。示例如下:

$export TEST="Test..." #增加一个环境变量TEST 
$env|grep TEST #此命令有输入,证明环境变量TEST已经存在了
TEST=Test...
$unset #TEST #删除环境变量TEST
$env|grep TEST #此命令没有输出,证明环境变量TEST已经存在了

6. 使用readonly命令设置只读变量

如果使用了readonly命令的话,变量就不可以被修改或清除了。示例如下:

$export TEST="Test..." #增加一个环境变量TEST 
$readonly TEST #将环境变量TEST设为只读
$unset TEST #会发现此变量不能被删除
-bash: unset: TEST: cannot unset: readonly variable
$TEST="New" #会发现此也变量不能被修改
-bash: TEST: readonly variable

环境变量的设置位于/etc/profile文件

如果需要增加新的环境变量可以添加下属行

export path=$path:/path1:/path2:/pahtN 

Linux 系统用户账号的管理

1. 用户账号的优势

  • 帮助系统管理员对使用系统的用户进行跟踪

  • 控制用户对系统资源的访问

  • 帮助用户组织文件,为用户提供安全保护

2. 添加新的用户

添加命令

useradd 选项 用户名

常用选项

  • -d<目录>, 设置用户主目录,默认值为用户的登录名,并放在 /home 目录下;如果此目录不存在,则同时使用 -m 选项,可以创建主目录。

  • -g<用户组>,指定用户所属的基本组

  • -G<用户组>,指定用户所属的附加组

  • -m,自动创建用户主目录,并把框架目录(默认为 /etc/skel )下的文件复制到用户主目录下。

    1
    2
    3
    4
    5
     ls -a /etc/skel/

    ----------output----------

    .. . bash_logout .bash_profile .bashrc
  • -r,建立系统帐号。

  • -s<Shell文件>,指定用户的登录Shell。

不常用选项

  • -c<备注>,描述新用户帐号,通常为用户全名,comment 为字符串。

  • -D,创建新帐号后保存为新帐号设置的默认信息。

  • -e<有效期限>,用 MM/DD/YYYY 格式设置帐号过期日期。

  • -f<缓冲天数>,指定在密码过期后多少天即关闭该帐号。

  • -M,不要自动建立用户的主目录。

  • -n,取消建立以用户名称为名的群组。

  • -u<用户号>,指定用户的用户号,如果同时有 -o 选项,则可以重复使用其他用户的标识号。

    • 在 CentOS7 中系统用户 UID 为 1~999,普通用户 UID 为 1000+;以前的 CentOS6 中系统用户 UID 为 1~499,普通用户 UID 为 500+。

    • 注意:UID 即每个用户的身份标识,虽然可以修改 /etc/passwd(命令设置的 UID 不允许重复),但尽量保持唯一性,类似于每个人的身份证号码。
  • 用户名:指定新账号的登录名。

示例1:

useradd -d /home/xlxiao -m xlxiao
# 等价于
useradd xlxiao
创建用户并设定用户主目录


示例2:

useradd gem -s /bin/sh -g group –G adm,root gem
创建用户,指定用户登录 shell,指定用户基本组,指定用户附加组
增加用户账号就是在 /etc/passwd 文件中为新用户增加一条记录,同时更新其他系统文件如 /etc/shadow, /etc/group 等。

3. 删除账号

删除命令

 userdel 选项 用户名

常用选项

  • -r,删除用户在系统文件中(主要是 /etc/passwd, /etc/shadow, /etc/group 等)的记录,同时删除用户的主目录

示例:

$ userdel -r xlxiao

4. 修改账号

修改账号即修改用户的相关属性,如用户名、主目录、用户组、登录 shell 等


修改命令

$ user 选项 用户名

常用选项

  • -d<目录>, 设置用户主目录,默认值为用户的登录名,并放在 /home 目录下;如果此目录不存在,则同时使用 -m 选项,可以创建主目录。

  • -g<用户组>,指定用户所属的基本组

  • -G<用户组>,指定用户所属的附加组

  • -m,自动创建用户主目录,并把框架目录(默认为 /etc/skel )下的文件复制到用户主目录下。

  • -r,建立系统帐号。

  • -s<Shell文件>,指定用户的登录Shell。

  • -l<帐号名称>,修改用户帐号名称。

  • 不常用选项

    • -L,锁定用户密码,使密码无效。

示例:

$ usermod -s /bin/ksh -d /home/z -g developer sam

5. 用户口令的管理

用户账号刚创建时没有口令,但是被系统锁定,无法使用,必须为其指定口令后才可以使用,即使是指定空口令。


口令命令

$ passwd 选项 用户名

常用选项

  • -l 锁定口令,即禁用账号。

  • -u 口令解锁。

  • -d 使账号无口令。

  • -f 强迫用户下次登录时修改口令。

示例:

$ passwd sam
---------- output ----------
New password:*******
Re-enter new password:*******
  • 普通用户修改自己的口令时,passwd命令会先询问原口令

  • 超级用户为用户指定口令时,就不需要知道原口令

示例:

$ passwd -d sam
为用户指定空口令

示例:

$ passwd -l sam
锁定 sam 账户,使其不能登录

解决Android Studio 出现 unable to access android sdk add-on list的方法

出现这个提示的原因主要是因为电脑第一次安装 Android Studio,启动后 Android Studio 没有检测到电脑有 SDK ,所以才有这个提示,

unable to access android sdk add-on list

下面说一下解决方法:

解决方法

  • 如果是 windows 系统,在 Android Studio 的安装目录下,找到 binidea.properties 文件。
  • 如果是 macOS 系统,右键应用程序中的 Android Studio.app ,选择 显示包内容 ,接着找到 Contents/bin/idea.properties 文件。
  • 打开 idea.properties 文件,在末尾加入以下配置,这个配置是设置初次打开 Android Studio 时,不检测 SDK 。
disable.android.first.run = true

如果不想这么设置的话,也可以点击 Cancel 然后按照一步步提示自动下载 SDK 。

CentOS7启动及排错

  • UEFi或BIOS初始化,运行POST开机自检
  • 选择启动设备
  • 引导装载程序, centos7是grub2
  • 加载装载程序的配置文件:
    /etc/grub.d/
    /etc/default/grub
    /boot/grub2/grub.cfg
  • 加载initramfs驱动模块加载内核选项
  • 内核初始化,centos7使用systemd代替init
  • 执行initrd.target所有单元,包括挂载/etc/fstab
  • 从initramfs根文件系统切换到磁盘根目录
  • systemd执行默认target配置,配置文件/etc/systemd/system/default.target
  • systemd执行sysinit.target初始化系统及basic.target准备操作系统
  • systemd启动multi-user.target下的本机与服务器服务
  • systemd执行multi-user.target下的/etc/rc.d/rc.local
  • Systemd执行multi-user.target下的getty.target及登录服务
  • systemd执行graphical需要的服务

设置内核参数

  • 设置内核参数,只影响当次启动
  • 启动时,在linux16行后添加systemd.unit=desired.target
  • systemd.unit=emergency.target
  • systemd.unit=rescue.target
  • rescue.target 比emergency 支持更多的功能,例如日志等
  • systemctl default 进入默认target

启动排错

  • 文件系统损坏
    先尝试自动修复,失败则进入emergency shell,提示用户修复
  • 在/etc/fstab不存在对应的设备和UUID
    等一段时间,如不可用,进入emergency shell
  • 在/etc/fstab不存在对应挂载点
    systemd尝试创建挂载点,否则提示进入emergency shell.
  • 在/etc/fstab不正确的挂载选项
    提示进入emergency shell

破解CentOS7的root口令方法一

  • 启动时任意键暂停启动
  • 按e键进入编辑模式
  • 将光标移动linux16开始的行,添加内核参数rd.break
  • 按ctrl-x启动
  • mount –o remount,rw /sysroot
  • chroot /sysroot
  • passwd root
  • touch /.autorelabel
  • exit
  • reboot破解

破解CentOS7的root口令方法二

  • 启动时任意键暂停启动
  • 按e键进入编辑模式
  • 将光标移动linux16开始的行,改为rw init=/sysroot/bin/sh
  • 按ctrl-x启动
  • chroot /sysroot
  • passwd root
  • touch /.autorelabel
  • exit
  • reboot

centous7设置默认启动内核,并删除

配置文件 :/boot/grub2/grub.cfg
修改:/etc/default/grub GRUB_DEFAULT=saved saved改为0
grub2-mkconfig -o /boot/grub2/grub.crg 重新生成

删除没用的内核
/boot/ 和 /lib/modules/ 里面内核版本的东西 3.10.0.xxxx
grub2-mkconfig -o /boot/grub2/grub.crg 重新生成

修复GRUB2

  • GRUB”the Grand Unified Bootloader”引导提示时可以使用命令行界面可从文件系统引导
  • 主要配置文件/boot/grub2/grub.cfg
  • 修复配置文件grub2-mkconfig > /boot/grub2/grub.cfg
  • 修复grub grub2-install /dev/sdaBIOS环境grub2-install UEFI环境
  • 调整默认启动内核vim /etc/default/grubGRUB_DEFAULT=0

删除boot下所有

  1. 进入救援模式
  2. 输入 1 continue
  3. 2 进入shell
  4. chroot /mnt/sysimage
  5. mkdir /mnt/cdroom
  6. mount -o /dev/cdroom /mnt/cdroom
  7. rpm -ivh /mnt/cdroom/Packages/kernel-3.10.0.693.e17.x86.rpm –force
  8. grub2-install /dev/sda
  9. 修复配置文件grub2-mkconfig > /boot/grub2/grub.cfg
  10. exit
  11. reboot

ScheduledExecutorService方法scheduleAtFixedRate与scheduleWithFixedDelay的区别

先看ScheduledExecutorService类的scheduleAtFixedRate()和scheduleWithFixedDelay()的方法签名。

scheduleAtFixedRate

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);

scheduleWithFixedDelay

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);

主要区别在第三个参数:

  • scheduleAtFixedRate的参数是period,它是以任务的开始时间计时,period时间过去后,如果任务已经执行完成,立即执行下一个任务。如果任务没有执行完,则需要等任务执行完毕后才能立即执行下一个任务。也就是说不会并行执行任务。
  • scheduleWithFixedDelay的参数是delay,是以任务结束时开始计时(计算延时),delay时间过去后,立即执行下一个任务。不会出现并行执行任务

scheduleAtFixedRate执行任务图


scheduleWithFixedDelay执行任务图

图来自:https://blog.csdn.net/jianghuiyun/article/details/96151861

Tomcat 8.5新安装环境初步配置优化

下载安装Tomcat

wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.gz
tar zxf apache-tomcat-8.5.37.tar.gz -C /usr/local
mv /usr/local/apache-tomcat-8.5.37 /usr/local/tomcat

tomcat是一个压缩包,下载完成后,只需要解压到安装目录即可。

环境配置优化

安装tomcat后,我们需要对tomcat做初始配置及优化。主要考虑以下几点:

  • 安全
    • 把webapps下除ROOT外的目录全部删除,Tomcat有一个用户管理页面就存在这个目录下面基本用不上放着并不安全。
  • 模式
    • tomcat有三种运行模式nio bio apr,默认为bio 我们来调整为apr模式。
  • 调整熵池
    • 提高熵池可以加快启动速度,有时你会发现启动时好久卡在session这块就是熵池太小的原因。
  • Jvm
    • 分配tomcat运行占用内存。
  • server.xml
    • 这部分将调整tomcat的配置文件中的线程以及线程池和压缩等参数。

开启apr模式

yum -y install apr-devel openssl-devel

进入你tomcat安装目录

cd /usr/local/tomcat/bin
tar zxf tomcat-native-1.2.16.tar.gz
cd tomcat-native-1.2.16-src/native
./configure && make && make install

修改server.xml配置

定义端口这里HTTP1.1修改成org.apache.coyote.http11.Http11AprProtocol

catalina.sh脚本中

CLASSPATH=下加入

JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib"

重启tomcat可看到http-apr-8080

加大熵池

可以查看我们系统默认的

cat /proc/sys/kernel/random/entropy_avail

安装熵服务并启动

yum install rng-tools
systemctl start rngd
cp /usr/lib//system/rngd.service /etc//system
vim /etc/systemd/system/rngd.service 编辑熵服务
ExecStart=/sbin/rngd -f -r /dev/urandom 对照更改
systemctl daemon-reload
systemctl restart rngd

这样你在查看熵大小会很惊讶的

JVM调整

修改catalina.sh,在CLASSPATH=下加入

JAVA_OPTS="-server -Xms5000m -Xmx5000m -Xmn512m -XX:+UseG1GC -XX:+PrintGCDetails  -XX:+PrintGCTimeStamps -Xloggc:../logs/gc.log"
  • Xms 初始化最小内存
  • Xmx 可使用最大内存
  • Xms和Xmx调整为相同减少内存频繁上下切换稳定些
  • Xmn 年轻代内存
  • -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:../logs/gc.log 输出gc日志方便查找问题
  • -XX:+UseG1GC 开启G1垃圾回收

server.xml调整

  <Executor 
name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="600"
minSpareThreads="30"
prestartminSpareThreads="true"
maxIdleTime="60000"
/>
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol"
executor="tomcatThreadPool"
enableLookups="false"
URIEncoding="UTF-8"
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla,traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
connectionTimeout="20000"
maxPostSize="-1"
maxHttpHeaderSize="8192"
acceptCount="600"
tcpNoDelay="true"
disableUploadTimeout="true"
redirectPort="8443" />

以上配置对应服务为 Centos7.2/4核16G,生产环境稳定运行

另一个还可以调整log日志的存储位置,防止日志过大妨碍服务运行

系统的Tcp连接数也应去修改,阿里云默认为2000,根据服务情况去调整,增加并发。

systemctl解决Nginx奔溃后实现自动重启

解决程序奔溃自动重启是Systemd的一个特性,它有一组命令构成,涉及到系统管理的方方面面。其中systemctl是 Systemd 的主命令,用于管理系统。

我们使用Systemd的自动重启特性,来实现nginx奔溃后自动重启。

执行命令:

systemctl edit nginx

在[Service]节点上修改如下:

[Service]
Restart=always
RestartSec=1
Type=forking
PIDFile=/run/nginx.pid

其中把Restart设置为always。

启动nginx

systemctl daemon-reload
systemctl start nginx

验证

执行监控nginx状态命令:

systemctl status nginx

kill掉nginx,你会发现nginx会自动重启


MySQL使用NOT IN存在null值导致结果错误的解决方法

house表:

create table house (address varchar(200) not null, heating varchar(50));

表中有两个字段,address地址,不能为null,凉爽程度heating 可以为null。

插入记录:

insert into house values ('A', null),('B','hot');

in查询语句:

select address from house where heating in ('cool');

结果为空,因为不存在heating为cool的房子。

not in查询语句:

select address from house where heating not in('cool');

我们可能预期应该输出A和B,实际结果输出为B。

在MySql中,NOT IN是使用列表中的值做相等比较, “!=”不相等时返回true。如果值为null,!=null始终为false。

NOT(TRUE) 为FALSE, NOT(FALSE) 为TRUE, 而NOT(UNKNOWN) 还是UNKNOWN。null表示UNKNOW

解决方法:

对in返回true取反,非true则是想要的结果

select address from house where heating in ('cool') is not TRUE;

Java判断ip是否属于指定的ip网段

更新于 2023.05.22 4分钟阅读 0 评论 5 推荐

    作者:

同一网段的ip是有相同的网络标识。

ip地址和子网掩码做“与”运算的到的结果为网络标识

比如两个IP:172.16.1.100(子网掩码:255.255.0.0)和172.16.2.100(子网掩码:255.255.0.0)。首先把ip地址和子网掩码转换为二进制,做与运算,然后转换为十进制,得到的结果为:172.16.0.0。所以可以说这两个ip是属于172.16.0.0网段。

网段表示方式

172.16.0.0/16

其中斜杆后面的16表示32位的二进制子网掩码的前16为为1,后面的为0。

java代码如下

public static boolean isInRange(String ip, String cidr) {
String[] ips = ip.split("\\.");
int ipAddr = (Integer.parseInt(ips[0]) << 24)
| (Integer.parseInt(ips[1]) << 16)
| (Integer.parseInt(ips[2]) << 8) | Integer.parseInt(ips[3]);
int type = Integer.parseInt(cidr.replaceAll(".*/", ""));
int mask = 0xFFFFFFFF << (32 - type);
String cidrIp = cidr.replaceAll("/.*", "");
String[] cidrIps = cidrIp.split("\\.");
int cidrIpAddr = (Integer.parseInt(cidrIps[0]) << 24)
| (Integer.parseInt(cidrIps[1]) << 16)
| (Integer.parseInt(cidrIps[2]) << 8)
| Integer.parseInt(cidrIps[3]);
return (ipAddr & mask) == (cidrIpAddr & mask);
}

使用如下:

public static void main(String[] args) {
System.out.println(isInRange("192.168.1.127", "192.168.1.64/26"));
System.out.println(isInRange("192.168.1.2", "192.168.0.0/23"));
System.out.println(isInRange("192.168.0.1", "192.168.0.0/24"));
System.out.println(isInRange("192.168.0.0", "192.168.0.0/32"));
}

Nginx重定向http到https

更新于 2019.07.02 1分钟阅读 0 评论 5 推荐

    Linux

    作者: cc
  1. CentOS安装JDK Page 1
  2. Linux使用wget和curl下载jdk Page 2
  3. Nginx重定向http到https Page 3

Nginx重定向http到https:

方法一

【推荐】使用响应码301,301内容参考HTTP 301 Moved Permanently

server {
    listen         [::]:80;
    return 301 https://$host$request_uri;
}

方法二

server {
    listen 80;
    rewrite ^(.*) https://$host$1 permanent;
 }

这里使用了rewrite和正则,有一定的性能影响。

Windows MySQL5.7.19安装失败:This application requires Visual Studio 2013 Redistributable

已安装Visual Studio 2013 Redistributable,安装MySQL5.7.19时报错。

错误信息:

1: Action 13:23:11: INSTALL. 
1: 1: MySQL Server 5.7 2: {F08E9C75-A42E-4962-8760-4CBD9CF35D7A} 
1: Action 13:23:12: FindRelatedProducts. Searching for related applications 
1: Action 13:23:12: AppSearch. Searching for installed applications 
1: Action 13:23:12: LaunchConditions. Evaluating launch conditions 
1: This application requires Visual Studio 2013 Redistributable. Please install the Redistributable then run this installer again. 
1: 1: MySQL Server 5.7 2: {F08E9C75-A42E-4962-8760-4CBD9CF35D7A} 3: 3 
1: The action 'Install' for product 'MySQL Server 5.7.19' failed.

解决方案:

Windows下安装MySQL5.7需要先安装Visual Studio 2013 Redistributable

如果仍然报错,安装更新Update for Visual C++ 2013 and Visual C++ Redistributable Package

参考:
https://dev.mysql.com/doc/refman/5.7/en/windows-installation.html
https://forums.mysql.com/read.php?169,659133,659152#msg-659152

【Java面试题】不使用if-else等条件语句,如果输入值为1返回0,输入值为0返回1

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    作者:

Java 面试题:

不使用条件语句实现方法,输入值为0返回1,输入值为1返回0。

答案1

return 1 - value;

答案2

使用异或运算^

return value ^ 1;

关于Java异常

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    作者:

在这篇博文里,我们思考下检查异常 (checked exception)和非检查异常(unchecked exception),特别是它们在函数式编程里的影响。
十几年前Java出现时,在当时它是相当有创意的。特别是它的异常处理机制,相对先前的C/C++有了很大的提高。例如,读取文件可以出现很多异常:文件可以不存在,可以为只读等等。

相关Java的伪代码类似于:

File file = new File("/path");
if (!file.exists) {
    System.out.println("文件不存在");
} else if (!file.canRead()) {
    System.out.println("文件不可读");
} else {
    // 最后读取文件,此处省略相关代码
}

分离try catch代码块的想法背后是分离业务代码和异常处理代码。

try {
    File file = new File("/path");
    // 读取文件,此处省略相关代码
} catch (FileNotFoundException e) {
    System.out.println("文件不存在);
} catch (FileNotReadableException e) {
    System.out.println("文件不可读");
}

当然,上面单独的代码是没用的。它可能构成读文件的专有方法。

public String readFile(String path) {
    if (!file.exists) {
        return null;
    } else if (!file.canRead()) {
        return null;
    } else {
        // 读取文件,此处省略相关代码
        return content;
    }
}

上面catch块的代码有一个问题:它返回的是null。这样:

  1. 调用的代码每次都需要检查null值。
  2. 没有办法知道文件是不存在还是不可读。

使用更函数化的实现来修复第一个问题,这样允许方法组合为:

public Optional<String> readFile(String path) {
    if (!file.exists) {
        return Optional.empty();
    } else if (!file.canRead()) {
        return Optional.empty();
    } else {
        // Finally read the file
        // Depending on the language
        // This could span seveal lines
        return Optional.of(content);
    }
}

可惜,这一点都没有改变第二个问题。那些追求纯粹函数式的实现的人可能要废弃之前的代码片段,而改为:

public Either<String, Failure> readFile(String path) {
    if (!file.exists) {
        return Either.right(new FileNotFoundFailure(path));
    } else if (!file.canRead()) {
        return Either.right(new FileNotReadableFailure(path));
    } else {
        // Finally read the file
        // Depending on the language
        // This could span seveal lines
        return Either.left(content);
    }
}

这相对于先前的代码有了很好的改进。现在的代码更加有意义,因为如果失败,右边的返回值会告诉失败的原因。

但还有一个问题,而且不是小问题。调用代码该怎么写呢?它需要处理失败。或者更加可能的做法是,让调用代码处理,依此类推,知道最上面的代码。

例如,在Go是这样的:

items, err := todo.ReadItems(file) if err != nil { fmt.Errorf("%v", err) }

如果代码在这里结束就相当好了。然而,err必须传给调用的代码,如上所述,是一直往上传。当然,有一个关键词panic,但它似乎不是处理异常的首选方式。

最奇怪的部分,这也正是人们对Java检查异常的抱怨的地方:它需要在异常出现的地方处理,方法的签名也需要做出相应的改变。

因此,我很喜欢非检查异常。唯一的缺点是它打破了纯粹的函数式编程——异常抛出被认为是副作用。除非你使用纯粹的函数式编程,否则没有必要避免使用非检查异常。

此外,编程语言和框架可以在最顶层提供处理异常的钩子,如在JVM,他们包括:

  • JDK,Thread.setDefaultUncaughtExceptionHandler()
  • Vaadin,VaadinSession.setErrorHandler()
  • Spring MVC,@ExceptionHandler
  • 等等

这样,你可以让异常冒泡到它们应该被处理的地方。拥抱(非检查)异常吧!

翻译自: Dzone的On Exceptions

使用Tomcat需要掌握的基本内容

更新于 2017.12.19 0分钟阅读 0 评论 5 推荐

    Tomcat

    作者: cc
  1. 使用Tomcat需要掌握的基本内容 Page 1

首先要知道:Tomcat是一个Servlet/JSP容器。

Tomcat作为一个Web应用服务器软件,它的核心功能是实现由JCP(Java Community Process)制定的Java Servlet,(JSP)JavaServer Pages, (EL)Java Expression Language 和 Java WebSocket规范,并提供了一些对Web应用很有用的特性。

本文基于Tomcat 8.0.x所写,它实现的是Servlet3.1和JSP2.3规范。

专有名词

在使用Tomcat前,最好先了解Tomcat设计的一些概念,以及在使用过程中会用到的变量名词。

Catalina

Tomcat由多个组件构成,Catalina是最核心的组件。它实现了Servlet/JSP规范,是Tomcat的Servlet容器。据闻它是以太平洋的一个小岛Catalina命名的。

Tomcat的安装包里有几个地方是以Catalina命名的。如bin目录的catalina.sh脚本,它是用来管理Tomcat容器,包括tomcat的启动和关闭。logs目录的catalina.out,它是tomcat容器的主日志。

Tomcat架构相关名词

Server:服务器,在Tomcat里它表示整个容器,它对应Tomcat的Server interface接口。

Service:服务,它是一个中间组件,它的作用是把一个或多个的Connector绑定到一个Engine引擎上。它对应Tomcat的 Service interface接口。

Engine:引擎,Service的请求处理流程。接收和处理Connector的请求,并返回响应。它对应tomcat的Engine interface

Connector:连接器,它用来与客户端通信。一个Tomcat服务器可以配置多个连接器,如处理http请求的HTTP Connector,处理AJP协议的AJP Connector(用来连接Tomcat服务器与其他web应用服务器的通信)。

Host:虚拟主机。它的作用是给Tomcat服务器关联网址,如majing.io。一个Engine可以包含多个虚拟主机,其中一个主机作为Engine的默认主机,它是通过Engine的defaultHost设置,默认主机将处理那些发送到tomcat服务器而未指定虚拟主机地址的请求。

Context: 表示部署的web应用。一个虚拟主机可以包含多个Context,但每个Context需要有唯一的路径。

环境变量的设置

Tomcat是一个Java的应用程序,它本身是不会直接使用环境变量。这些环境变量主要是tomcat的启动脚本使用。catalina.sh是Tomcat在*inux系统下的启动脚本,它会检测一些环境变量,使用这些环境变量来构造java命令,用来启动tomcat。

在catalina.sh脚本的开头列出了它所使用的环境变量,以及每个环境变量作用。其中CATALINA_HOME,CATALINA_BASE,JRE_HOME,JRE_HOME,CATALINA_OPTS以及CATALINA_PID是比较常用的环境变量。

CATALINA_HOME与CATALINA_BASE

  • CATALINA_HOME:必须,指向Tomcat的安装目录。如果没有设置CATALINA_HOME,脚本会自动检测并且设置为Tomcat的安装目录。
  • CATALINA_BASE:可选,表示tomcat的实例路径。在单个tomcat实例的情况下,它指向的就是$CATALINA_HOME。在部署多个实例的情况下,它表示自己所在实例的路径。

tomcat安装包里可以分为两类目录:

  • 属于tomcat的软件目录,包括bin和lib
  • tomcat实例运行相关目录,包括conf,logs,temp,webapps以及work

我们可以把tomcat运行的相关目录内容拷贝多份,每一份为一个tomcat实例,它的$CATALINA_HOME指向到tomcat软件所在目录(即tomcat的安装目录),$CATALINA_BASE指向到实例所在目录。但很少会使用这种部署方式。所以一般情况下$CATALINA_HOME和$CATALINA_BASE都是指向Tomcat的安装目录。

JRE_HOME与JAVA_HOME

  • JRE_HOME:jre的安装目录。
  • JAVA_HOME:jdk的安装目录。

这两个环境变量必须存在其中一个,如果两个环境变量都存在,使用JRE_HOME指定的目录。

CATALINA_OPTS与CATALINA_PID

CATALINA_OPTS和CATALINA_PID是比较常用到两个环境变量。

  • CATALINA_OPTS:可以在这个环境变量设置Java运行参数,如堆栈大小,GC参数等。CATALINA_OPTS所设置的参数只会用在tomcat的启动命令start,run以及debug,不会在stop命令里使用。
  • CATALINA_PID:配置tomcat的进程id存放位置。

JAVA_OPTS是一个容易与CATALINA_OPTS混淆的环境变量,它也是用来设置Java运行参数。与CATALINA_OPTS不同,JAVA_OPTS所设置的参数除了用在tomcat的启动命令start里外,还会用在tomcat的关闭命令stop里。

关闭tomcat,执行stop命令实际也是执行一个java命令,它不需要很大的内存等资源。为了避免执行stop命令时耗费很多资源,不要在JAVA_OPTS里设置内存限制相关参数。启动脚本所需要的JAVA运行参数往往都是在CATALINA_OPTS设置,这也是JAVA_OPTS不怎么使用的原因。

setenv.sh

catalina.sh会检测在$CATALINA_HOME/bin目录下是否存在setenv.sh脚本,如果存在则执行setenv.sh脚本。顾名思义,“setenv”是用来设置环境变量的,Tomcat推荐除了CATALINA_HOME和CATALINA_BASE外的环境变量在setenv.sh中设置。

示例:

JRE_HOME=/usr/java/latest
CATALINA_PID="$CATALINA_BASE/tomcat.pid"

默认情况下,$CATALINA_HOME/bin目录下是没有setenv.sh,可以自己新建此文件。

服务器配置

TODO

Red Hat/CentOS的Nginx升级

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    运维

    作者: cc
  1. Red Hat/CentOS的Nginx升级 Page 1
  2. Nginx gzip对javascript文件压缩无效 Page 2

在Linux系统,尽量不需要使用源码编译来安装软件,这样容易和系统的包管理混淆。

此次升级是nginx1.0.15升级到nginx1.12.1

升级前

查看nginx版本

$ nginx -v
nginx version: nginx/1.0.15

查看系统版本

# lsb_release -a
LSB Version:  :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch
Distributor ID: CentOS
Description:  CentOS release 6.8 (Final)
Release:    6.8
Codename:   Final

升级安装过程

添加yum安装仓库

在 /etc/yum.repos.d目录下新建nginx.repo,添加以下内容

CentOS

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

RHEL

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/rhel/$releasever/$basearch/
gpgcheck=0
enabled=1

$releasever:操作系统的主版本,如上面的CentOS6.8,它的主版本为6,把$releasever替换为6。redhat也是一样。

yum安装


#yum update nginx
检查新安装的nginx版本
# nginx -v
nginx version: nginx/1.12.1

重启nginx

# service nginx restart
停止 nginx:                       [确定]
正在启动 nginx:                     [确定]

Nginx gzip对javascript文件压缩无效

更新于 2017.12.19 10分钟阅读 0 评论 5 推荐

    运维

    作者: cc
  1. Red Hat/CentOS的Nginx升级 Page 1
  2. Nginx gzip对javascript文件压缩无效 Page 2

问题

Nginx从1.0.15升级到1.12.1后,原来开启的gzip对javascript文件压缩失效了。

原来nginx的gzip相关配置如下

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";

解决方法

这里需要先了解下javascript的mime type:

  • text/javascript:这是已被废弃的用法。
  • application/x-javascript:x表示试验中,由text/javascript迁移到application/x-javascript时用于实验的
  • application/javascript:RFC现在官方推荐使用的MIME type。

如果是html5,建议不要再script声明mime type。

从上面的配置可以看出,gzip_types是缺少application/javascript,添加上即可:

gzip_types text/plain text/css text/javascript application/javascript application/x-javascript application/xml  image/jpeg image/gif image/png;

参考:application/javascript or application/x-javascript

【Android Instant App】报错:Your Instant App APKs contain the domain 'xxx.com' that is already in use by another app

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    作者:

问题

两个Android的Instant App使用相同的域名报错:

Your Instant App APKs contain the domain 'xxx.com' that is already in use by another app

原因

Instant App的链接需要满足额外的两个条件:

1、Instant App用作链接的intent-filter需要同时支持http和https。例如

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="http" android:host="www.example.com" />
    <data android:scheme="https" />
</intent-filter>

2、每个域名只能在一个instant app里声明,这个有区别于安装的app。

解决方法

根据报错的信息,需要在这两个instant app里使用不同的域名。为了体现在同一主域名下,可以考虑在instant app里使用不同的子域名。

参考:How app links for instant apps are different

MacOSX启动XAMPP-VM报错:Error starting "XAMPP" stack: cannot calculate MAC address: signal: killed

更新于 2017.12.19 0分钟阅读 0 评论 5 推荐

    MacOS问题集

    作者: cc
  1. MacOSX启动XAMPP-VM报错:Error starting "XAMPP" stack: cannot calculate MAC address: signal: killed Page 1

问题

在MacOS启动xampp-vm时报错:

INFO: Starting "XAMPP" stack
ERROR: Error starting "XAMPP" stack: cannot calculate MAC address: signal: killed

环境:

  • macos:10.12.6
  • xampp:7.1.8

原因及方案

这可能是macos升级引起xampp启动出错,apachefriends已修复并发布了修复版本,到https://www.apachefriends.org/download.html#download-apple下载最新的xampp-vm-osx。

安装前需要删除~/.bitnami/stackman/helpers/hyperkit。

参考:https://community.apachefriends.org/viewtopic.php?f=29&t=76128&sid=5c50212a6acd7afe0298d2c4642842e0

CentOS安装JDK

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    Linux

    作者: cc
  1. CentOS安装JDK Page 1
  2. Linux使用wget和curl下载jdk Page 2
  3. Nginx重定向http到https Page 3

CentOS下有三种方式安装JDK。

下载压缩包安装

1. 下载压缩包参考Linux使用wget和curl下载jdk

2. 新建安装目录,并解压安装包到安装目录

[root@iZ9 ~]# mkdir/usr/java
[root@iZ9 ~]# cd /usr/java
[root@iZ9 ~]#  tar -zxvf jdk-8u144-linux-x64.tar.gz

3. 设置环境变量

[root@iZ9 java]# vim /etc/profile

在profile添加以下内容:

#set java environment
JAVA_HOME=/usr/java/jdk1.8.0_144
JRE_HOME=/usr/java/jdk1.8.0_144/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

令环境变量生效

[root@iZ9 java]# source /etc/profile
[root@iZ9 java]# java -version
java version "1.8.0_144"

rpm安装

1.下载rpm包,参考Linux使用wget和curl下载jdk

2.  安装rpm包

[root@iZ9 ~]# rpm -ivh jdk-8u144-linux-x64.rpm

rpm默认会把jdk安装在/usr/java/jdk1.8.0_144,然后通过链接到/usr/bin,所以不需要设置环境变量即可使用java,如需设置环境变量参考压缩包安装方式

yum安装

1、yum search搜索jdk包

[root@iZ9 ~]$ yum search java | grep jdk
ldapjdk-javadoc.x86_64 : Javadoc for ldapjdk
java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation
java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.8.0-openjdk-debug.x86_64 : OpenJDK Runtime Environment with full debug on
java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.8.0-openjdk-demo-debug.x86_64 : OpenJDK Demos with full debug on
java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.8.0-openjdk-devel-debug.x86_64 : OpenJDK Development Environment with
java-1.8.0-openjdk-headless.x86_64 : OpenJDK Runtime Environment
java-1.8.0-openjdk-headless-debug.x86_64 : OpenJDK Runtime Environment with full
java-1.8.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.8.0-openjdk-javadoc-debug.noarch : OpenJDK API Documentation for packages
java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk-src-debug.x86_64 : OpenJDK Source Bundle for packages with
ldapjdk.x86_64 : The Mozilla LDAP Java SDK

2. 选中合适的版本安装

[root@iZ9 ~]$ yum install java-1.8.0-openjdk

yum安装会把jdk安装在/usr/lib/jvm/java-1.8.0-openjdk.x86_64下,并通过链接到/usr/bin,所以不需要设置环境变量就可以直接使用。如需设置环境变量,参考压缩包安装方式。

另外,yum安装使用了alternatives来管理多个版本的软件,默认会链接到最新安装的jdk

Angular Material2报错:'md-form-field' is not a known element

更新于 2017.12.19 0分钟阅读 0 评论 5 推荐

    作者:

问题

使用Angular Material 2的md-form-field报未知元素的错误。错误信息如下:

Uncaught Error: Template parse errors:
'md-form-field' is not a known element:
 1. If 'md-form-field' is an Angular component, then verify that it is part 
of this module.
2. If 'md-form-field' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' 
to the '@NgModule.schemas' of this component to suppress this message. (" [ERROR ->]

解决

<md-form-field>为Angular Material  2.0.0-beta.10新增的选择器。

1、使用<md-form-field>,需要先安装Angular Material 2.0.0-beta.10以上版本

npm install --save @angular/material

2、在AppModule导入MdFormFieldModule

import { MdFormFieldModule } from '@angular/material';

@NgModule({
  imports: [
    ....
    MdFormFieldModule,
    ....
  ]

Android Instant App报错:Your site 'xxxxx.com' has not been linked through the Digital Assets Link protocol to your app

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    作者:

问题

上传Android的Instant app时报错:

Your site 'xxxxx.com' has not been linked through the Digital Assets Link protocol to your app. Please link your site through the Digital Assets Link protocol to your app.

解决

1、检查网络,外网访问https://xxxx.com/.well-known/assetlinks.json是否能访问到。
2、生成assetlinks.json文件可能使用的是debug key,改为release key即可。

Android Gradle报错:Failed to resolve: com.google.android.gms:play-services:11.2.0

更新于 2017.12.19 8分钟阅读 0 评论 5 推荐

    作者:

问题

更新com.google.android.gms:play-services到11.2.0后报错:

Error:(20, 10) Failed to resolve: com.google.android.gms:play-services:11.2.0
Install Repository and sync project
Show in File
Show in Project Structure dialog

build.gradle依赖包:

dependencies {
    compile 'com.google.android.gms:play-services:11.2.0'

    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.android.support:support-v4:25.3.1'
}

解决

Google Play services依赖包的仓库改为了maven.google.com。在build.gradle添加google maven仓库:

repositories {
    jcenter()
    maven {
        url "https://maven.google.com"
    }
}

repositories {
  jcenter()
   google()
}

参考:https://developers.google.com/android/guides/releases#august_2017_-_version_1120

AngularJS非字符插值计算规则

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    作者:

在AngularJS里,插值会把嵌入的表达式转换为字符串,对于非字符串转换规则如下:

1、undefined和null转换为空字符串''。

2、如果值是一个Object对象,但不是Number,Date和Array类型,$interpolate变量会先查找用户自定义的toString()函数,如果找到了,使用toString()函数来转换为字符串。注意,这里的用户自定义意味myObject.toString !== Object.prototype.toString。

3、如果也找不到用户自定义的toString()函数,那么使用JSON.stringify()来把对象转换为字符串。

Java 数值相等判断详解(特别注意包装类型之间的比较)

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    作者:

Java数值类型分为基本类型,包装类型。

  • 基本类型:byte、short、 int、long、float和double
  • 包装类型:Byte、Short、Integer、Long、Float和Double

数值比较可分为基本类型之间比较,基本类型与包装类类型比较,包装类型之间的比较。

基本类型比较

基本类型之间只能使用“==”做相等比较。比较结果就是数值是否相等。

int a=1, b=1,c=2;
System.out.println(a==b);  //输出true
System.out.println(a==c);  //输出false

基本类型与包装类型比较

包装类型可使用“==”和.equals()方法与基本类型的数字比较。

  • ==:使用==比较,包装类型对象会先拆箱(转为基本类型)后再和基本类型比较,比较结果为数值是否相等。
  • .equals(): 包装类型的.equals()方法比较包装的数值是否相等。
Integer a=1, b=1,c=2;
System.out.println(a==b);  //输出true
System.out.println(a==c);  //输出false

基本类型与包装类型的这两种方式都是比较数值,结果符合比较预期。

整型包装类型比较

包装类型的整型和浮点型它们各自的比较有一点差别,分开说明。

包装类型比较方式有==和equals()方法。

==比较:

以Integer为示例:

Integer a1 = 127, b1 = 127;
Integer a2 = 128, b2 = 128;
Integer a3 = new Integer(127), b3= new Integer(127);

System.out.println(a1 == b1);  //输出为true
System.out.println(a2 == b2);  //输出为false
System.out.println(a3 == b3);  //输出为false

示例中,同样是数值比较,a1和b1比较结果为true,而a2和b2比较结果却为false。两者之间的差别只有数值不同。a3和b3比较结果为false,虽然它们的数值都是127,与a1和b1不同的地方是,a3和b3是通过构造函数赋值。

Java出于性能考虑会在内存里构造一些常量池,这种做法叫做享元模式。在整型包装类型里用了这种方式,数值缓存在Integer内部类IntegerCache里,代码如下:

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

在IntegerCache的代码可以看出,缓存的的范围默认为[-128,127]。你也可以使用java.lang.Integer.IntegerCache.high属性来设置缓存的最大值,但最大值不能超过(Integer.MAX_VALUE - 129)。

在看下构造Integer对象的两种主要方法:

public Integer(int value) {
    this.value = value;
}

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

第一种是通过Integer构造函数来构造对象, 第二种是使用valueOf(int i)方法。

从valueOf(int i)代码可以看到,当参数i值在IntegerCache指定的范围内时,共享使用IntegerCache缓存的Integer对象。超出它的范围则直接构造Integer对象。

首先要知道,引用类型的对象的==比较是判断两个对象的内存地址是否一样,相同则为true。包装类型是引用类型的一种。

示例里比较解释如下:

  1. a1==b1:数值赋值,数值在[-128,127]范围内,a1和b1实际对象为IntegerCache缓存对象,对象地址相同,结果为true。
  2. a2==b2:数值赋值,数值超出[-128,127]范围,a2和b2为新构建对象,对象对应的内存地址不相同,结果为false。
  3. a3==b3:新构建对象,尽管数值相同,但对象内存地址不同,结果为false。

equals()比较:

equals()方法比较的是数值,数值相等则为true;上面的例子

System.out.println(a1.equals(b1));   //true
System.out.println(a2.equals(b2));   //true
System.out.println(a3.equals(b3));   //true

浮点包装类型比较

和其他引用类型比较一样。==比较的是包装类型对象的内存地址。而浮点包装类型equals()方法比较的是数值。

用法小结

包装类型的==实际比较的是对象的内存地址是否相同,equals()方法比较的是数值是否相等。

用法如下:

  1. 基本类型之间使用==作为相等判断,
  2. 基本类型和包装类型使用==或使用包装类型的equals()方法做相等判断
  3. 包装类型之间使用equals()方法做相等判断

Linux使用wget和curl下载jdk

更新于 2017.12.19 1分钟阅读 0 评论 5 推荐

    Linux

    作者: cc
  1. CentOS安装JDK Page 1
  2. Linux使用wget和curl下载jdk Page 2
  3. Nginx重定向http到https Page 3

在Linux下安装jdk主要有两种方式:下载安装包手动安装和使用Linux的安装工具(yum或ubuntu的apt)安装。使用Linux安装工具安装的是OpenJDK,如果我们想安装oracle的JDK则需要下载安装包手动安装。

下载Oracle JDK需要接受license,在Linux可以使用wget和curl来下载

Wget下载Java 8u151

64位的tar.gz和rpm包

wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.tar.gz
wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.rpm

32位的tar.gz和rpm包

wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-i586.tar.gz
wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-i586.rpm

-c / --continue
wget请求过程中会发生重定向,continue参数可以让wget继续完成未完成的请求。

--header "Cookie: oraclelicense=accept-securebackup-cookie"
header参数是为了接受oracle license。

对于wget < 1.3的版本需要加上选项--no-check-certificate

查看MySQL数据库空间使用情况

information_schema是MySQL的系统数据库,information_schema里的tables表存放了整个数据库各个表的使用情况。

可以使用sql来统计出数据库的空间使用情况,相关字段:

  • table_schema:数据库名
  • table_name:表名
  • table_rows:记录数
  • data_length:数据大小
  • index_length:索引大小

统计表使用空间

mysql> select concat(round(sum(data_length/1024/1024),2),'mb') as data from tables where table_schema='mydb' and table_name='mytable';
+--------+
| data |
+--------+
| 0.02mb |
+--------+
1 row in set (0.00 sec)

统计数据库使用空间

mysql> select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='mydb'; 
+--------+
| data |
+--------+
| 6.64MB |
+--------+
1 row in set (0.00 sec)

统计所有数据使用空间


mysql> select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables;                           
+--------+
| data |
+--------+
| 6.64MB |
+--------+
1 row in set (0.01 sec)

Java HTTP代理设置以及认证

更新于 2017.09.05 11分钟阅读 0 评论 5 推荐

    作者:

代理设置

java http/https设置代理有两种方式:使用系统属性设置以及使用Proxy设置。

使用系统属性设置代理

String PROXY_HOST = "127.0.0.1";//代理服务器地址
String PROXY_PORT = "80";//代理服务器端口
 
//HTTP代理
System.setProperty("http.proxyHost", PROXY_HOST); 
System.setProperty("http.proxyPort", PROXY_PORT);
 
//HTTPS代理
System.setProperty("https.proxyHost", PROXY_HOST);        
System.setProperty("https.proxyPort", PROXY_PORT);

使用系统属性设置代理是全局,应用程序里所有的http/https请求都会发往代理服务器,由代理服务器向目标服务器完成请求。

如果部分http/https请求不需要经过代理,可以使用系统属性‘nonProxyHosts’设置,它的值可以为主机列表,主机之间使用“|”分隔,也可以使用*号匹配多个主机。

Java网络属性参考:Networking Properties

使用Proxy设置代理

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); 
URLConnection conn = url.openConnection(proxy);

与使用系统属性设置全局代理不同,使用proxy可以为请求使用不同的代理。

认证

有些代理服务主机需要客户机认证。

全局认证

Java使用jave.net.Authenticator提供网络连接的认证信息,Authenticator是一个抽象类,它需要子类实现getPasswordAuthentication()方法来提供用于认证的密码信息。

示例:

public class BasicAuthenticator extends Authenticator { 
  String userName; 
  String password; 

  public BasicAuthenticator(String userName, String password) { 
    this.userName = userName; 
    this.password = password; 
  }

  @Override 
  protected PasswordAuthentication getPasswordAuthentication() { 
    return new PasswordAuthentication(userName, password.toCharArray()); 
  } 
}

除了实现Authenticator类外,还需要调用Authenticator的setDefault()方法来注册BasicAutheticator实例。

Authenticator.setDefault(new BasicAuthenticator(userName, password));

注册的这个实例是系统全局的。所有请求都会提供由BasicAutheticator的Basic认证的信息。

请求头信息认证

除了使用java的jave.net.Authenticator提供的全局认证外,也可以在请求头信息里包含认证信息。

String headerKey = "Proxy-Authorization";
String encoded = new String(Base64.encodeBase64((new String(username + ":" + password).getBytes())));
String headerValue = "Basic " + encoded;
conn.setRequestProperty(headerKey, headerValue);

Angular CLI 新建Bootstrap项目报Bootstrap dropdown require Popper.js错误

更新于 2017.09.03 1分钟阅读 0 评论 5 推荐

    作者:

问题


基于Angular cli新建bootstrap项目,angular-cli.json的script配置如下:

"scripts": [
  "../node_modules/jquery/dist/jquery.slim.min.js",
  "../node_modules/bootstrap/dist/js/bootstrap.min.js",
  "../node_modules/popper.js/dist/umd/popper.min.js"
]


Chrome control报错:

Uncaught Error: Bootstrap dropdown require Popper.js (https://popper.js.org)
    at eval (eval at webpackJsonp.../../../../script-loader/addScript.js.module.exports (addScript.js:9), :6:17548)
    at eval (eval at webpackJsonp.../../../../script-loader/addScript.js.module.exports (addScript.js:9), :6:23163)
    at eval (eval at webpackJsonp.../../../../script-loader/addScript.js.module.exports (addScript.js:9), :6:50902)
    at eval ()
    at webpackJsonp.../../../../script-loader/addScript.js.module.exports (addScript.js:9)
    at Object.../../../../script-loader/index.js!../../../../bootstrap/dist/js/bootstrap.min.js (bootstrap.min.js?f885:1)
    at __webpack_require__ (bootstrap a2f1d85ef068872b0530:54)
    at Object.2 (scripts.bundle.js:66)
    at __webpack_require__ (bootstrap a2f1d85ef068872b0530:54)
    at webpackJsonpCallback (bootstrap a2f1d85ef068872b0530:25)

解决方案


在angular-cli.json的script里,需要把popper.min.js放在bootstrap.min.js之前。