CentOS 7 下安装 MySQL 5.7

 centos, mysql  CentOS 7 下安装 MySQL 5.7已关闭评论
8月 212019
 

原文链接:https://blog.csdn.net/u011886447/article/details/79796802

从 CentOS 7 系统开始,MariaDB 成为 yum 源中默认的数据库安装包。在 CentOS 7 及以上的系统中使用 yum 安装 MySQL 包将无法使用 MySQL。您可以选择使用完全兼容的 MariaDB,或依照本文介绍配置来继续使用 MySQL。本文以在 CentOS 7 下安装 MySQL 5.7.21 为例。

 

  1. 检查 MariaDB 是否安装

yum list installed | grep mariadb

 

 

 

  1. 卸载全部MariaDB 相关

yum -y remove mariadb*

 

  1. 下载 MySQL 的 YUM 源

进入到要下载到的路径:cd /usr/local/src

 

下载:wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

 

  1. 安装MySQL 的 YUM 源

rpm -ivh mysql57-community-release-el7-11.noarch.rpm

 

  1. 检查MySQL 的 YUM 源是否安装成功

yum repolist enabled | grep “mysql.*-community.*”

 

 

 

如图所示则安装成功。

 

  1. 查看 MySQL 版本

yum repolist all | grep mysql

 

 

 

  1. 安装 MySQL

yum install mysql-community-server

 

一直输 y 就可以了。

 

  1. 启动 MySQL 服务

systemctl start mysqld

 

  1. 测试连接 MySQL 服务

mysql -u root 或者 mysql

 

——————————————————————————–

 

提示:

 

刚安装的 MySQL 是没有密码的,这时如果出现:

 

ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: NO),解决如下:

 

① 停止 MySQL 服务:systemctl stop mysqld

 

② 以不检查权限的方式启动 MySQL: mysqld –user=root –skip-grant-tables &

 

③ 再次输入 mysql -u root 或者 mysql,这次就可以进来了。

 

④ 更新密码:

 

MySQL 5.7 以下版本:UPDATE mysql.user SET Password=PASSWORD(‘123456′) where USER=’root’;

 

MySQL 5.7 版本:UPDATE mysql.user SET authentication_string=PASSWORD(‘123456′) where USER=’root’;

 

⑤ 刷新:flush privileges;

 

⑥ 退出:exit;

 

设置完之后,输入 mysql -u root -p,这时输入刚设置的密码,就可以登进数据库了。

 

——————————————————————————–

 

  1. 防火墙设置

远程访问 MySQL,需要开放 3306 端口:

 

firewall-cmd –permanent –zone=public –add-port=3306/tcp

 

firewall-cmd –permanent –zone=public –add-port=3306/udp

 

firewall-cmd –reload

 

如果是 CentOS 7,需要将 MySQL 服务加入防火墙,然后重启防火墙:

 

firewall-cmd –zone=public –permanent –add-service=mysql

 

systemctl restart firewalld

 

——————————————————————————–

 

提示:

 

在输入 firewall-cmd –permanent –zone=public –add-port=3306/tcp 时可能会报 ‘FirewallD is not running’,是说防火墙本身就没有打开,解决方法:

 

① 查看防火墙状态:systemctl status firewalld,会发现状态是 dead,即防火墙未开启。

 

② 打开防火墙:systemctl start firewalld

 

③ 再次查看防火墙状态:systemctl status firewalld,这时会发现状态变为 running,即防火墙开启成功。

 

 

 

 

 

 

这时再输入开放 3306 端口的命令就没有问题了。

 

——————————————————————————–

 

  1. 设置允许远程访问

默认情况下 MySQL 是不允许远程连接的,所以在 Java 项目或者 MySQLWorkbench 等数据库连接工具连接服务器上的 MySQL 服务的时候会报 “Host ‘x.x.x.x’ is not allowed to connect to this MySQL server”。可以通过下面的设置解决。详细可以参考之前写的一篇文章 XXX is not allowed to connect to this MySQL server。

 

① grant all privileges on *.* to root@”%” identified by ‘0’;

 

② flush privileges;

 

——————————————————————————–

 

提示:

 

在执行第一条命令的时候,可能会报:

 

‘ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.’ 需要让我们重置密码。原因是因为我刚刚的命令中设置的数据库密码是0,这个密码过于简单,不符合 MySQL 的安全要求。只要重新设置一个复杂点的密码就可以了:

 

mysql> SET PASSWORD = PASSWORD(‘xxx’);   //xxx 是重置的新的复杂的密码

 

——————————————————————————–

 

思考:

 

之前设置简单密码是没有问题的,可能原因:

 

① 可能目前环境是 CentOS 7 + MySQL 5.7.21,安全性有所提升。

 

② 也有可能是之前的数据库设置过

 

mysql> set global validate_password_policy=0;

 

mysql> set global validate_password_length=1;

 

允许设置简单密码。

 

  1. 相关命令

MySQL 相关:

 

systemctl start mysqld    #启动mysql

 

systemctl stop mysqld    #停止mysqld

 

systemctl restart mysqld    #重启mysqld

 

systemctl enable mysqld    #设置开机启动

 

systemctl status mysqld    #查看 MySQL Server 状态

 

防火墙相关:

 

systemctl status firewalld    #查看防火墙状态

 

systemctl start firewalld    #打开防火墙

 

systemctl stop firewalld    #关闭防火墙

 

systemctl restart firewalld    #重启防火墙

 

 

您不能安装“Network Link Conditioner”偏好设置。“Network Link Conditioner”偏好设置是随 macOS 安装,不能被替换。

 mac  您不能安装“Network Link Conditioner”偏好设置。“Network Link Conditioner”偏好设置是随 macOS 安装,不能被替换。已关闭评论
8月 162019
 

其实出现这个提示,基本都是以前使用过Network Link Conditioner, 后来关闭后,Network Link Conditioner从“系统设置”里看不到了,然后再次从“Additional_Tools_for_Xcode_xxxx.dmg”中的Hardware目录里点击Network Link Conditioner .prefPane出现这样的提示, 其实这个程序已经安装了,可以通过操作spotlight找到并打开:

  • 按住 Command + Space 打开 spotlight 全局搜索
  • 搜索 Network Link Conditioner
  • 在结果列表里双击打开
  • 自动添加到设置面板并打开

DONE!

Swift中的!和?, 问号 和叹号 的使用和区别介绍

 swift  Swift中的!和?, 问号 和叹号 的使用和区别介绍已关闭评论
8月 132019
 

一般我们在一下两种情况下会遇到!和?的使用
1.声明变量时

var number :Int?
var str : String

2.在对变量操作时

number?.hashValue
str!.hashValue

由于这两种情况的意义不同,所以分开进行解释:

1.声明变量时
在声明一个变量时如果不手动初始化,Swift不会自动初始化该变量为一个默认值的。

var a : String
var b = a           //error:因为没有初始化a,a没有值

但是对于Optional的变量则不同,Optional的变量在声明时如果不初始化,Swift会自动将该变量初始化为nil。声明变量时在类型后添加?或者!就是告诉编译器这个一个Optional的变量,如果没有初始化,你就将其初始化为nil

var a : String?           //a 为nil
var b : String!           //b 为nil
var a_test = a            //a_test为nil
var b_test = b            //b_test为nil

但是这两者之间还是有一些区别的,介绍后面之后再讲。
Optional事实上是一个枚举类型,从下图可以看出,Optional包含None和Some两种类型,而nil就是Optional.None,非nil就是Optional.some。如果Optional变量在声明时不初始化,Swift会调用init()来初始化变量为nil,而用非nil的值初始化变量时,会通过Some(T)把该原始值包装,所以在之后使用的时候我们需要通过解包取出原始值才能使用。

请输入图片描述

2.对变量进行操作时

var arrayCount = dataList?.count

这时问号的意思类似于isResponseToSelector,即如果变量是nil,则不能响应后面的方法,所以会直接返回nil。如果变量非nil,就会拆Some(T)的包,取出原始值执行后面的操作。

var arrayCount = dataList!.count

这里的叹号和之前的问号则不同,这里表示我确定dataList一定是非nil的,所以直接拆包取出原始值进行处理。因此此处如果不小心让dataList为nil,程序就会crash掉。

回到上面声明时?和!区别的问题上去
声明变量时的?只是单纯的告诉Swift这是Optional的,如果没有初始化就默认为nil,而通过!声明,则之后对该变量操作的时候都会隐式的在操作前添加一个!。

总结

  1. 问号?
    a.声明时添加?,告诉编译器这个是Optional的,如果声明时没有手动初始化,就自动初始化为nil
    b.在对变量值操作前添加?,判断如果变量时nil,则不响应后面的方法。
  2. 叹号!
    a.声明时添加!,告诉编译器这个是Optional的,并且之后对该变量操作的时候,都隐式的在操作前添加!
    b.在对变量操作前添加!,表示默认为非nil,直接解包进行处理

 

来自:https://segmentfault.com/a/1190000000533936。

Swift闭包的用法,简介, IN用法

 swift  Swift闭包的用法,简介, IN用法已关闭评论
8月 072019
 

非常好的资料https://www.jianshu.com/p/7dcecea05dbb

 

本篇将详细总结介绍Swift闭包的用法;
闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift中的闭包与C和 Objective-C中的代码块(blocks)以及其他一些编程语言中的匿名函数比较相似。

主要内容:
1.闭包表达式
2.闭包的使用与优化
3.值捕获
4.逃逸闭包
5.自动闭包

一、闭包表达式

Swift闭包的三种存在形式:
1.全局函数是一个有名字但不会捕获任何值的闭包
2.嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
3.闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包
闭包表达式的语法一般有如下的一般形式:

{ (parameters) -> returnType in
    statements
}

说明:
1.闭包的外层是一个大括号,先写的参数和返回值,然后操作部分之前使用in;
2.闭包就相当于OC中的block, 也可以看做是匿名函数;
3.闭包表达式参数可以是in-out参数,但不能设定默认值;
4.闭包的函数体部分由关键字in引入,该关键字表示闭包参数和返回值类型已经完成,闭包函数体开始;

二、闭包的使用与优化

下面,我们使用Swift标准库中的sorted(by:)方法来测试闭包的使用。sorted(by:)方法允许外部传入一个用于排序的闭包函数将已知类型数组中的值进行排序,完成排序之后,该方法会返回一个与原数组大小相同,包含同类型元素已正确排序的新数组:

//定义一个整型数组
var someInts: [Int] = [5,9,7,0,1,3]
//定义一个排序函数
func biggerNumFirst(num1:Int, num2:Int) -> Bool{
    return num1 > num2
}
//普通用法:将biggerNumFirst函数传入sorted函数,实现排序
var sortInts = someInts.sorted(by: biggerNumFirst)
print(sortInts)     //[9, 7, 5, 3, 1, 0]

//闭包用法:为sorted函数参数传入一个闭包,实现排序
sortInts = someInts.sorted(by:{ (a:Int, b:Int) -> Bool in
    return a > b
})
print(sortInts)     //[9, 7, 5, 3, 1, 0]

注意:因为闭包不会在其他地方调用,所以不使用外部参数名

闭包使用起来十分灵活,我们可以在某些特定情况下对齐进行优化,下面是对上述闭包的优化:

2.1.根据上下文推断类型,省略参数类型与括号

由于排序闭包函数是作为sorted(by:)方法的参数传入的,Swift可以推断其类型和返回值类型。所以sorted(by:)方法被一个Int类型的数组调用,其参数必定是(Int,Int)->Bool类型的函数。最后,根据上下文推断类型,我们可以省略参数类型和参数周围的括号。

sortInts = someInts.sorted(by: {a,b in
    return a > b
})
print(sortInts)

2.2.对于不会发生歧义的闭包,可将其写成一行

sortInts = someInts.sorted(by:{a,b in return a > b})
print(sortInts)

2.3.单行闭包表达式,省略return关键字

省略return关键字的条件:
sorted(by:)方法的参数类型明确了闭包必须返回一个Bool类型值
单行闭包表达式中,其返回值类型没有歧义

sortInts = someInts.sorted(by: {a,b in a > b})
print(sortInts)

2.4.使用参数名缩写(不推荐使用)

Swift 自动为内联闭包提供了参数名称缩写功能,你可以直接通过$0,$1,$2 来顺序调用闭包的参数,以此类推。
如果我们在闭包表达式中使用参数名称缩写, 我们就可以在闭包定义中省略参数列表,并且对应参数名称缩写的类型会通过函数类型进行推断。in关键字也同样可以被省略,因为此时闭包表达式完全由闭包函数体构成:

sortInts = someInts.sorted(by: {$0>$1})
print(sortInts)

2.5.使用运算符简化闭包(不推荐使用)

Swift的Int类型定义了关于大于号(>)的字符串实现,其作为一个函数接受两个Int类型的参数并返回Bool类型的值。而这正好与sorted(by:)方法的参数需要的函数类型相符合。可以使用大于号来代替闭包

sortInts = someInts.sorted(by: >)
print(sortInts)

2.6.尾随闭包,解决长闭包的书写问题

如果你需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。
尾随闭包的写法:将闭包书写在函数括号之后,函数会支持将其作为最后一个参数调用,使用尾随闭包,不需要写出它的参数标签。

func someFunctionThatTakesAClosure(closure: () -> Void) {
    //函数体部分
    closure(); //调用闭包
}

//不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure(closure: {
    //闭包主体部分
})

//使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
    //闭包主体部分
}

//注意:如果闭包表达式是函数或方法的唯一参数,则当你使用尾随闭包时,你甚至可以把 () 省略掉:
someFunctionThatTakesAClosure {
    print("Hello World!")    //打印:Hello World!
}

总结Swift闭包主要的四种优化方法:
1.利用上下文推断参数和返回值类型,省略参数类型与括号
2.隐式返回单表达式闭包,即单表达式闭包可以省略return关键字
3.参数名称缩写
4.尾随闭包语法

三、值捕获

闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。Swift会为你管理在捕获过程中涉及到的所有内存操作。

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

代码分析:
1.makeIncrementer函数以amount为参数,以()->Int作为返回值类型,其函数体中还嵌套了另一个函数incrementer。
2.如果我们把incrementer单独拿出来,会发现其中runingTotal和amount变量都无法使用,因为这两个变量的引用是incrementer从外部捕获的。
3.Swift会负责被捕获变量的所有内存管理工作,包括对捕获的一份值拷贝,也包括释放不再需要的变量。

现在再来测试makeIncrementer函数的使用:

let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen();    //10
incrementByTen();    //20

let incrementBySeven = makeIncrementer(forIncrement: 7)
incrementBySeven()   //7
incrementBySeven();  //14

let alsoIncrementByTen = incrementByTen
alsoIncrementByTen() //30

代码分析:
1.incrementByTen与incrementBySeven,是通过makeIncrementer函数传入不同的增量参数amount而创建的;
2.两个函数都有属于各自的引用,其中的runningTotal变量都是从makeIncrementer中捕获的,但是已经各自没有关系;
3.函数和闭包都是引用类型,将其赋值给变量或者常量,都只是操作的它们的引用,而不会改变闭包或者函数本身;

四、逃逸闭包

当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。
逃逸闭包:在定义接受闭包作为参数的函数时,我们需要在参数名之前标注@escaping,以此表明这个闭包是允许”逃逸”出这个函数的。

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    //代码1:执行闭包,不需要添加@escaping
    //completionHandler();
    //代码2:函数外部对闭包进行了操作
    completionHandlers.append(completionHandler)
 }

代码分析:
someFunctionWithEscapingClosure(_:) 函数接受一个闭包作为参数,该闭包被添加到一个函数外定义的数组中。如果不将这个参数标记为@escaping,就会得到一个编译错误。

4.1.逃逸闭包的使用

逃逸闭包和非逃逸闭包在使用上有所不同。将一个闭包标记为@escaping(即逃逸闭包)后,在调用这个闭包时就必须在闭包中显式地引用 self。一个示例如下:

//定义一个带有非逃逸闭包参数的函数
func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

//定义一个可以使用闭包的类
class SomeClass {
    var x = 10
    func doSomething() {
        //调用逃逸闭包:必须在闭包中显式引用self
        someFunctionWithEscapingClosure { self.x = 100 }
        //调用非逃逸闭包:可以隐式引用self
        someFunctionWithNonescapingClosure { x = 200 }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)         //打印出 "200”

五、自动闭包

自动闭包:一种自动创建的闭包,用与包装传递给函数作为参数的表达式;自动闭包的特点:
1.自动闭包不接受任何参数;
2.自动闭包被调用的时候,会返回被包装在其中的表达式的值;
3.自动闭包是用一个普通的表达式来代替显式的闭包,能够省略闭包的花括号;

其实,我们经常调用采用自动闭包的函数,但是却少去实现这样的函数,assert函数就是其中之一:

 assert(condition:, message:)

assert函数中的condition参数可以接受自动闭包作为值,condition参数仅会在debug模式下被求值,在condidtion被调用返回值为false时,message参数将被使用。

5.1.自动闭包的基本使用

自动闭包能够实现延迟求值,直到调用这个闭包时,代码才会被执行。这对于有副作用或者高计算成本的代码来说是有益处的;下面的代码展示了自动闭包实现延时求值的具体做法:

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)    //打印出 “5"

//自动闭包不接受参数,只是一个表达式
let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)    //打印出 “5"

//调用自动闭包
print("Now serving \(customerProvider())!")   // Prints "Now serving Chris!"
print(customersInLine.count)               //打印出 "4”

代码分析:闭包实现了移除第一元素的功能,但是在闭包被调用之前,这个元素是不会被移除的。这就实现了延迟的作用

5.2.自动闭包在函数中的使用

现在将闭包作为参数传递给一个函数,同样可以实现延时求值行为。下面的serve函数接受了一个闭包参数(具有删除第一个元素且返回这个元素的功能)。

//customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}

//以闭包的形式传入参数
serve(customer: { customersInLine.remove(at: 0) } )  //打印出"Now serving Alex!”

现在使用自动闭包来实现上述函数功能,使用@autoclosure关键字,标明参数使用的是自动闭包,具体示例如下:

// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}
//由于标明了自动闭包,这里直接省略了闭包的花括号
serve(customer: customersInLine.remove(at: 0))  //打印出"Now serving Ewa!\n"

注意:
过度使用 autoclosures 会让你的代码变得难以理解。上下文和函数名应该能够清晰地表明求值是被延迟执行的。

5.3.可”逃逸”的自动闭包

一个自动闭包可以“逃逸”,这时候应该同时使用 @autoclosure 和 @escaping 属性,下面举例说明:

// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
    customerProviders.append(customerProvider)
}
//调用collectCustomerProviders,向数组中追加闭包
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))
print("Collected \(customerProviders.count) closures.")   //打印 "Collected 2 closures."
//循环数组中闭包,并且执行
for customerProvider in customerProviders {
    print("Now serving \(customerProvider())!")
}
// 打印 "Now serving Barry!"
// 打印 "Now serving Daniella!”

代码分析:
作为逃逸闭包:
collectCustomerProviders函数中,闭包customerProvider被追加到customerProviders中,而这个数据是定义在函数作用域范围之外的,这意味数组内的闭包能够在函数返回之后被调用,所以customerProvider必须允许
“逃逸”出函数作用域。

作为自动闭包:
调用collectCustomerProviders函数时,传入的闭包是表达式的形式,自动闭包省略了闭包花括号

 

xcode 10.2.1 里修改文件名,提示”rename failed”的解决方法

 mac, xcode  xcode 10.2.1 里修改文件名,提示”rename failed”的解决方法已关闭评论
8月 062019
 

新建xcode文件时,类名和文件名都起错了,文件里的类名可以修改(refactor->rename),但修改文件名时报错: rename failed,
可通过下面方式解决(此法似乎对类名修改报错也有效):

1.关闭 xCode
2.进入 ~/Library/Developer/Xcode/DerivedData 目录并删除包含 “ModuleCache”名的目录.
3.重新打开xcode
4.再尝试该名下。

Good Luck!

virtualbox 里使用itunes步骤及注意事项

 virtualBox  virtualbox 里使用itunes步骤及注意事项已关闭评论
8月 022019
 

在virtualbox 里想使用itunes,会发现插入usb端口,设备连接了但发现不了iphone设备等问题, 网上找到一篇英文等资料,有详细步骤及注意事项,大家可以参考下(我遇到的问题就是原来打开的是USB 1.0,实际需要打开:USB 2.0 EHCI controller ):

Ok, for the record, I’m not the biggest fan of iTunes for Windows, and that’s why when I needed to use iTunes I decided to install it within an Oracle Virtualbox virtual machine.

This configuration provides the benefit of portability and it also prevents Apple iTunes from wreaking havoc on your host PC.

Hooray for no iTunes on my host machine!!!

Anyway, this is how you do it,

How to set it up

  1. Download and install Oracle VirtualBox from https://www.virtualbox.org/
  2. Open VirtualBox and click MACHINE > NEW to create a new virtual machine.
  3. Select your OS and memory allocation. In my case I chose Microsoft Windows 7 32 bit
    Oracle VirtualBox Screenshot
  4. Choose option Create a virtual hard drive now. You can use the defaults for the next prompts. It’s advisable that you  allocate more hard disk space if you are going to store your media files within the Virtual Machine. In my situation I created a shared folder on my host which I mapped to the Virtual Machine.
  5. Plug in your iDevice to your PC.
  6. You should now see your Virtual Machine in the VirtualBox Manager window. Click SETTINGS to configuring your VM.
    Oracle VirtualBox screenshot
  7. You’ll need to mount the OS storage media within the Storagepanel to install your OS.
  8. Enable the Network Adapter in Bridged Mode so that you have internet access.
  9. In the USB pane, ensure the USB 2.0 EHCI controller is enabled otherwise your iDevice will not operate correctly. If you plugged in your iDevice then click the green ‘+’ button and select your iDevice, this will ensure that control of your device is passed straight to your VM automatically each time you start your VM. Otherwise you can manually ‘pass through’ the device once the VM is started.
    Oracle VirtualBox Screenshot
  10. It’s also advisable to enable 2D hardware acceleration and add additional Video Memory for improved performance.
  11. Click OK to save your changes
  12. Start your Virtual Machine and install the OS and Apple iTunes
  13. Setup your iTunes library to find your media files. It’s recommended that you use the ‘Consolidate Files‘ library option in iTunes to store all your media files in one single location, that way it’ll be easier for you to relocate your Virtual Machine in future to another PC.
  14. If you need access to the CD Drive on your host machine, simply start your Virtual Machine and ‘pass through’ control of your CD drive to your Virtual Machine through the DEVICES > CD/DVD DEVICES > HOST DRIVE option
  15. iTunes should now see your device and should sync successfully.
    iTunes Screenshot

Issues that I encountered

I had iTunes setup to consolidate all media files to an external USB drive. I experienced device ‘timeout‘ issues and ‘Could not connect to lockdown port‘ errors while syncing with my iPhone. After much hair pulling I realised that the timeouts were occurring only when I configured VirtualBox to ‘pass through’ my USB drive to the Virtual Machine. The issue was solved by instead creating a Shared Machine Folder within the Virtual Machine settings mapping to my USB drive.

I would certainly suggest that you create a snapshot of your Virtual Machine once you’ve created it incase anything goes wrong and you need to rollback to an earlier time.

iphone上提示“从 iCloud 照片图库下载这张照片时出错”,问题排查

 icloud  iphone上提示“从 iCloud 照片图库下载这张照片时出错”,问题排查已关闭评论
8月 012019
 

iphone上提示“从 iCloud 照片图库下载这张照片时出错”。建议您尝试以下任一操作:
1.请前往“设置”>“通用”>“用量”>“管理储存空间”,查看您的 iPhone 是否仍然有足够的可用空间。
2.轻点“设置”>“通用”>“日期与时间”。确保您的日期、时间和时区设置正确
3.查看“Apple 系统状态”页面,以确保目前不存在影响 iCloud 的中断或计划维护。
4.​尝试使用另一个网络进行下载。
5.更新您的 iPhone 至最新版本的 iOS
以下知识文章供您参考:
获取有关“iCloud 照片图库”的帮助

YAML 语言简介

 yaml  YAML 语言简介已关闭评论
7月 312019
 

YAML 语言教程

编程免不了要写配置文件,怎么写配置也是一门学问。

YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。

 

YAML文件编写时一定要注意空格:每个散列项冒号和值之间至少有一个空格!

 

一、简介

YAML 语言(发音 /ˈjæməl/ )的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。

它的基本语法规则如下。

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键,只允许使用空格。
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

# 表示注释,从这个字符一直到行尾,都会被解析器忽略。

YAML 支持的数据结构有三种。

  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars):单个的、不可再分的值

以下分别介绍这三种数据结构。

二、对象

对象的一组键值对,使用冒号结构表示。


animal: pets

转为 JavaScript 如下。

{ animal: 'pets' }

Yaml 也允许另一种写法,将所有键值对写成一个行内对象。


hash: { name: Steve, foo: bar }

转为 JavaScript 如下。

{ hash: { name: 'Steve', foo: 'bar' } }

三、数组

一组连词线开头的行,构成一个数组。

- Cat
- Dog
- Goldfish

转为 JavaScript 如下。

[ 'Cat', 'Dog', 'Goldfish' ]

数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

-
 - Cat
 - Dog
 - Goldfish

转为 JavaScript 如下。

[ [ 'Cat', 'Dog', 'Goldfish' ] ]

数组也可以采用行内表示法。


animal: [Cat, Dog]

转为 JavaScript 如下。

{ animal: [ 'Cat', 'Dog' ] }

四、复合结构

对象和数组可以结合使用,形成复合结构。


languages:
 - Ruby
 - Perl
 - Python 
websites:
 YAML: yaml.org 
 Ruby: ruby-lang.org 
 Python: python.org 
 Perl: use.perl.org 

转为 JavaScript 如下。

{ languages: [ 'Ruby', 'Perl', 'Python' ],
  websites: 
   { YAML: 'yaml.org',
     Ruby: 'ruby-lang.org',
     Python: 'python.org',
     Perl: 'use.perl.org' } }

五、纯量

纯量是最基本的、不可再分的值。以下数据类型都属于 JavaScript 的纯量。

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期

数值直接以字面量的形式表示。


number: 12.30

转为 JavaScript 如下。

{ number: 12.30 }

布尔值用truefalse表示。


isSet: true

转为 JavaScript 如下。

{ isSet: true }

null~表示。


parent: ~

转为 JavaScript 如下。

{ parent: null }

时间采用 ISO8601 格式。


iso8601: 2001-12-14t21:59:43.10-05:00

转为 JavaScript 如下。

{ iso8601: new Date('2001-12-14t21:59:43.10-05:00') }

日期采用复合 iso8601 格式的年、月、日表示。


date: 1976-07-31

转为 JavaScript 如下。

{ date: new Date('1976-07-31') }

YAML 允许使用两个感叹号,强制转换数据类型。


e: !!str 123
f: !!str true

转为 JavaScript 如下。

{ e: '123', f: 'true' }

六、字符串

字符串是最常见,也是最复杂的一种数据类型。

字符串默认不使用引号表示。


str: 这是一行字符串

转为 JavaScript 如下。

{ str: '这是一行字符串' }

如果字符串之中包含空格或特殊字符,需要放在引号之中。


str: '内容: 字符串'

转为 JavaScript 如下。

{ str: '内容: 字符串' }

单引号和双引号都可以使用,双引号不会对特殊字符转义。


s1: '内容\n字符串'
s2: "内容\n字符串"

转为 JavaScript 如下。

{ s1: '内容\\n字符串', s2: '内容\n字符串' }

单引号之中如果还有单引号,必须连续使用两个单引号转义。


str: 'labor''s day'

转为 JavaScript 如下。

{ str: 'labor\'s day' }

字符串可以写成多行,从第二行开始,必须有一个单空格缩进。换行符会被转为空格。


str: 这是一段
  多行
  字符串

转为 JavaScript 如下。

{ str: '这是一段 多行 字符串' }

多行字符串可以使用|保留换行符,也可以使用>折叠换行。


this: |
  Foo
  Bar
that: >
  Foo
  Bar

转为 JavaScript 代码如下。

{ this: 'Foo\nBar\n', that: 'Foo Bar\n' }

+表示保留文字块末尾的换行,-表示删除字符串末尾的换行。


s1: |
  Foo

s2: |+
  Foo


s3: |-
  Foo

转为 JavaScript 代码如下。

{ s1: 'Foo\n', s2: 'Foo\n\n\n', s3: 'Foo' }

字符串之中可以插入 HTML 标记。


message: |

  <p style="color: red">
    段落
  </p>

转为 JavaScript 如下。

{ message: '\n<p style="color: red">\n  段落\n</p>\n' }

七、引用

锚点&和别名*,可以用来引用。


defaults: &defaults
  adapter:  postgres
  host:     localhost

development:
  database: myapp_development
  <<: *defaults

test:
  database: myapp_test
  <<: *defaults

等同于下面的代码。


defaults:
  adapter:  postgres
  host:     localhost

development:
  database: myapp_development
  adapter:  postgres
  host:     localhost

test:
  database: myapp_test
  adapter:  postgres
  host:     localhost

&用来建立锚点(defaults),<<表示合并到当前数据,*用来引用锚点。

下面是另一个例子。

- &showell Steve 
- Clark 
- Brian 
- Oren 
- *showell 

转为 JavaScript 代码如下。

[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

八、函数和正则表达式的转换

这是 JS-YAML 库特有的功能,可以把函数和正则表达式转为字符串。


# example.yml
fn: function () { return 1 }
reg: /test/

解析上面的 yml 文件的代码如下。

var yaml = require('js-yaml');
var fs   = require('fs');

try {
  var doc = yaml.load(
    fs.readFileSync('./example.yml', 'utf8')
  );
  console.log(doc);
} catch (e) {
  console.log(e);
}

从 JavaScript 对象还原到 yaml 文件的代码如下。

var yaml = require('js-yaml');
var fs   = require('fs');

var obj = {
  fn: function () { return 1 },
  reg: /test/
};

try {
  fs.writeFileSync(
    './example.yml',
    yaml.dump(obj),
    'utf8'
  );
} catch (e) {
  console.log(e);
}

九、参考链接

转自:http://www.ruanyifeng.com/blog/2016/07/yaml.html

docker 在mac系统下, 修改/etc/docker/daemon.json期望改变dns无效解决方法

 docker  docker 在mac系统下, 修改/etc/docker/daemon.json期望改变dns无效解决方法已关闭评论
7月 252019
 

mac系统下,直接修改/etc/docker/daemon.json期望改变容器的dns是无效的,正确的方式是:

点击应用程序里的docker.app 或者 点击顶部工具条中 “鲸鱼”的icon –> 选择“preferences”  –> daemon –> advanced , 在这里更改, 修改完后点击 “apply && restart”,  再运行容器时, 可以看到容器中/etc/resolv.conf的dns已经是修改后的了。

MYSQL 中 ON DUPLICATE KEY UPDATE / REPLACE 单语句处理重复插入时更新

 mysql  MYSQL 中 ON DUPLICATE KEY UPDATE / REPLACE 单语句处理重复插入时更新已关闭评论
7月 252019
 

来自:https://lobert.iteye.com/blog/1604122 , 讲的很清楚,记录下

 

mysql当插入重复时更新的方法:

第一种方法:

 示例一:插入多条记录

假设有一个主键为 client_id clients 表,可以使用下面的语句:

 

Sql代码  

  1. INSERT INTO clients  
  2. (client_id,client_name,client_type)  
  3. SELECT supplier_id,supplier_name,‘advertising’  
  4. FROM suppliers  
  5. WHERE not exists(select * from clients where clients.client_id=suppliers.supplier_id);  

 

示例一:插入单条记录

Sql代码  

  1. INSERT INTO clients  
  2. (client_id,client_name,client_type)  
  3. SELECT 10345,‘IBM’,‘advertising’  
  4. FROM dual  
  5. WHERE not exists (select * from clients where clients.client_id=10345);  

 

使用 dual 做表名可以让你在 select 语句后面直接跟上要插入字段的值,即使这些值还不存在当前表中。

第二种方法: 

INSERT ON DUPLICATE KEY UPDATE的使用(本文重点)

如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE。例如,如果列a被定义为UNIQUE,并且包含值1,则以下两个语句具有相同的效果:

 

Sql代码  

  1. mysql>INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;  
  2. mysql>UPDATE table SET c=c+1 WHERE a=1;  

 

如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2

注释:如果列b也是唯一列,则INSERT与此UPDATE语句相当:

 

Sql代码  

  1. mysql>UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;  

 

如果a=1 OR b=2与多个行向匹配,则只有一个行被更新。通常,您应该尽量避免对带有多个唯一关键字的表使用ON DUPLICATE KEY子句。

您可以在UPDATE子句中使用VALUES(col_name)函数从INSERT…UPDATE语句的INSERT部分引用列值。换句话说,如果没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函数特别适用于多行插入。VALUES()函数只在INSERT…UPDATE语句中有意义,其它时候会返回NULL

示例:

 

Sql代码  

  1. mysql>INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)  
  2.           ->ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);  

 

本语句与以下两个语句作用相同:

 

Sql代码  

  1. mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)  
  2.           ->ON DUPLICATE KEY UPDATE c=3;  
  3. mysql>INSERT INTO table (a,b,c) VALUES (4,5,6)  
  4.           ->ON DUPLICATE KEY UPDATE c=9;  

 

当您使用ON DUPLICATE KEY UPDATE时,DELAYED选项被忽略。

第三种方法:

 

REPLACE语句

  我们在使用数据库时可能会经常遇到这种情况。如果一个表在一个字段上建立了唯一索引,当我们再向这个表中使用已经存在的键值插入一条记录,那将会抛出一个主键冲突的错误。当然,我们可能想用新记录的值来覆盖原来的记录值。如果使用传统的做法,必须先使用DELETE语句删除原先的记录,然后再使用INSERT插入新的记录。而在MySQL中为我们提供了一种新的解决方案,这就是REPLACE语句。使用REPLACE插入一条记录时,如果不重复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。

  使用REPLACE的最大好处就是可以将DELETEINSERT合二为一,形成一个原子操作。这样就可以不必考虑在同时使用DELETEINSERT时添加事务等复杂操作了。

  在使用REPLACE时,表中必须有唯一索引,而且这个索引所在的字段不能允许空值,否则REPLACE就和INSERT完全一样的。

  在执行REPLACE后,系统返回了所影响的行数,如果返回1,说明在表中并没有重复的记录,如果返回2,说明有一条重复记录,系统自动先调用了DELETE删除这条记录,然后再记录用INSERT来插入这条记录。如果返回的值大于2,那说明有多个唯一索引,有多条记录被删除和插入。

  REPLACE的语法和INSERT非常的相似,如下面的REPLACE语句是插入或更新一条记录。

  REPLACE INTO users (id,name,age) VALUES(123, ‘赵本山‘, 50);

  

 

  插入多条记录:

  REPLACE INTO users(id, name, age)

Sql代码  

  1. VALUES(123, 赵本山, 50), (134,‘Mary’,15);  
  2.   
  3. REPLACE也可以使用SET语句  
  4.   
  5. REPLACE INTO users SET id = 123, name = 赵本山, age = 50;  

 

  上面曾提到REPLACE可能影响3条以上的记录,这是因为在表中有超过一个的唯一索引。在这种情况下,REPLACE将考虑每一个唯一索引,并对每一个索引对应的重复记录都删除,然后插入这条新记录。假设有一个table1表,有3个字段a, b, c。它们都有一个唯一索引。

  CREATE TABLE table1(a INT NOT NULL UNIQUE,b INT NOT NULL UNIQUE,c INT NOT NULL UNIQUE);

 

  假设table1中已经有了3条记录

  a b c

  1 1 1

  2 2 2

  3 3 3

  下面我们使用REPLACE语句向table1中插入一条记录。

  REPLACE INTO table1(a, b, c) VALUES(1,2,3);

 

  返回的结果如下

  Query OK, 4 rows affected (0.00 sec)

  在table1中的记录如下

  a b c

  1 2 3