2019年5月

  1. 先到github上拉一份发布版本的源码包下来
  2. 安装python, bazel(Google的开源编译工具), 以及gcc等编译环境必备工具 其中bazel的新版本在编译时会报错,根据stackoverflow上的建议,使用1.17.2版本的,可在其github的发布页面找到下载。
  3. python安装numpy包。
  4. ./configure
  5. bazel build --config=mkl --config=opt //tensorflow/tools/pip_package:build_pip_package 生成轮子,用于pip安装。由于打算使用intel的mkl进行加速,添加了--config=mkl的选项。不需要的可以删除。

该错误通常在update语句报出。原因是企图在set子句中调用from子句中给表设立的别名。这个别名通常用于子句中的where子句的条件判定。 例:

UPDATE Tab
SET THIS.prop1 = (SELECT propx FROM Tab WHERE propy = THIS.propy)
FROM Tab THIS
WHERE propz = valz;

预期效果是希望将满足where条件的数据进新更新,实际上会报出如下错误: The multi-part identifier 'THIS.prop1' could not be bound. 原因是DBMS并搞不懂你的THIS和上面提到的Tab之间的关系。 解决方法:UPDATE Tab->UPDATE THIS,即把要更新的表名设置为为自己定义的别名即可。

参考: https://blog.csdn.net/dxnn520/article/details/7915198

实验课上,要求将一个角色的权限授予另一个角色。 在咕果上搜了老半天,结果只找到怎么把角色赋予用户。(汗,怎么这波技术含量这么低) 然后找到了ALTER ROLE ADD MEMBEREXEC sp_roleaddmember两个指令用于添加用户至角色。 用法:

ALTER ROLE <role-name> ADD MEMBER <user-name>
EXEC sp_roleaddmember [@rolename=]<role-name>, [@membername=]<user-name>

根据StackOverflow上该回答中一位用户所言,两者在SQL Server 2012中没有区别,参考资料如下: https://msdn.microsoft.com/en-us/library/ms189775.aspx https://msdn.microsoft.com/en-us/library/ms187750.aspx

但是在使用时,惊奇的发现在可以将Role作为参数填入以上操作的user-name部分,可以正常执行不会报错。 在子角色(user-name)的所有权限中查不到父角色(role-name)的权限,但是在父角色的成员表中可以看到子角色。 经过尝试后,发现直接对用户赋予子角色时,会自动给用户注册一个父角色的权限。 也就是说,直接把需要附加给角色的角色权限作为该角色的父角色,数据库便会在执行指令时自动赋予其父角色的权限。

例: 有两个角色,JuniorRoleSeniorRole,要将JuniorRole的权限赋予SeniorRole(显然高级用户通常应该拥有初级用户的全部权限),在SQL Server中可以这么做:

ALTER ROLE JuniorRole ADD MEMBER SeniorRole;

之后在进行用户授权时,ALTER ROLE SeniorRole add SeniorUser不仅会为SeniorUser赋予SeniorRole的角色,还会为其赋予JuniorRole的角色,目的达成。

起因是高二的时候,看到有100+ RMB的SBC,还能运行Android。
当时父亲还是比较支持我去体验一下新东西的,于是便央求着父亲给我买了一块。
彼时的Pine A64有三个版本,分别是内存512MB,1GB,2GB的。存储空间全部靠外插卡,系统也从此处启动。
当时省钱观念还是比较强的,在考虑用途的同时选择了折中的1GB版。
然后拿它打了半年的废狗,当时用的三棒手机连cpu都没写是哪家的
然而在后来才发现java是个内存怪兽,早知道就直接上2GB的了。
然而,现在2GB的变成了Long Term Supply版,结构也重新被设计过,内存从DDR3L换成了LPDDR3,即低功耗版。
也就是说,现在的2GB的Pine A64已经不能使用以前的镜像了。
不过问题不大,现在看来玩玩GPIO,Python,以及搭建个小服务器什么的,性能还是绰绰有余的。
然后当时为了省钱,做了另一件事情——没有买配套的Wifi+Bluetooth模块。
其结果就是,每当要上网的时候,就要找个有网线的地方(捂脸)。
其实当时手头还是有usb的wifi模块的——万能的RTL88188EU
当时也试过在台式机上给这块网卡编译驱动,不过当时什么都不懂,看着教程一路makemake install就完事了。
后来才发现在半闭源的Android上编译驱动是件难事,而当时也几乎不懂Linux。

1.jpg

到了大学之后,有了更多的时间来研究这个东西,也学习了更多Linux和硬件相关的知识。
在全球巡回演唱会级别的咕咕之后,终于把这个问题解决。步骤如下:

其之一 获取内核源码

首先uname -a一下,从里面找出内核版本kernel version。我的是3.10.104

2.jpg

再到对应的内核仓库repository去看一下,找到对应的发行版本release
仓库地址:https://github.com/longsleep/linux-pine64
点releases去查看所有的发行版本。找到对应的源码source code包如下:

3.jpg

其中第四组数字为内核的修补号,对内核功能没有什么影响。这里选择最新的3.10.104-2-pine64版本。
下载后,使用对应的命令解压,应有如下的目录结构:

4.jpg

其之二 编译内核

在此采用~/Desktop/linux-pine64-3.10.104-2-pine64作为临时目录。

为稳妥起见其实是看不懂参数,获取当前内核的配置文件,作为接下来的配置文件。

cd ~/Desktop/linux-pine64-3.10.104-2-pine64
make mrproper  # clean all previously generated file
cp /proc/config.gz .
gunzip config
mv config .config

就在源码的根目录下直接完成了配置。

然后就直接是make编译生成内核。由于本人在编译gcc时深受-j,即多线程multithreading参数的折磨,再加上没贴散热片怕CPU烧掉,这里采用单线程编译。(当然有兴趣的可以试试-j(自动设置为最大可用线程数)或者-jX(指定为X线程编译))

放了一晚上(也不知道多久),编译完成。

其之三 安装内核头文件kernel_headers

这个编译镜像的人是真的让人服气,tmd一块开发板,你还把头文件排除在外,搞个红红的软链接soft link放在镜像里。
结果,凡是想要编译和内核相关模块的全都搞不了,况且这东西还不知道apt上的general版能不能适配。
好在内核的开发者为我们提供了继续开发的希望,将其中一些工序写成了脚本提供出来,其中恰好有我们需要的。
https://github.com/longsleep/build-pine64-image/blob/master/kernel/install_kernel_headers.sh
没错就是上面这个。
我是直接把脚本的部分内容复制出来执行(为了学习理解),有用的部分从27行开始到最后都是。
理论上把28行删掉,就能够直接将脚本在Pine A64上运行,但是我没有测试。(本机编译不需要跨平台)
其实感觉差不多就是直接运行脚本了。。
我的配置如下:

LINUX_ARCH=arm64
CROSS_COMPILE=
DEST=
TARGET=$DEST/usr/src/linux-pine64-3.10.104-2-pine64

完成一系列命令后,kernel_headers安装完成。
文件目录应当如下:

5.jpg

再在/lib/modules/<kernel-version>下配置好相关的文件链接:

sudo rm -f build
sudo ln -s /usr/src/linux-pine64-3.10.104-2-pine64 $(pwd)/build

这样系统就能正常调用了。

由于系统自身的架构声明为aarch64,实际使用的却是arm64的配置文件,推荐进行以下操作:

sudo ln -s /usr/src/linux-pine64-3.10.104-2-pine64/arch/arm64 \
/usr/src/linux-pine64-3.10.104-2-pine64/arch/aarch64

就可以让某些应用程序编译时获得正确的配置文件。(下文即是其中之一)

其之四 编译网卡驱动

这一部分是写起来最快乐的,因为步骤和一般x86 PC上的没有任何区别。
make allsudo make install,完事!

然后sudo modprobe 8188eu即可加载驱动。

附注:

  1. 请务必确保在安装好的头文件目录下有一个Module.symvers文件,该文件用于链接符号和对应的操作码。 若是缺少的话,加载驱动会失败,且在dmesg中会看到如下信息: 6.jpg 其中8188eu模块报出的是没有Module.symvers文件时的错误,下面的R8188EU是操作正确下发出的信息。 Module.symvers由内核编译时动态生成,这也是前面为什么要编译内核的原因。

  2. 如果有已经配置好的内核源码的话,可以通过使用make modules_prepare进行编译驱动模块的辅助程序配置。 该命令可以解决的问题诸如scripts/basic/fixdep not found一类的问题。

啊,写到下午一点,差不多写完了,肚子早饿了,吃饭去。

在写项目的时候,先写了个爬虫,用了官方的json库,写完运行,没问题。 之后打算把爬虫的信息处理之后用REST写成api,然后就选择了Springboot。 把项目内的源代码原封不动地复制过去,然后,报错了???

之后还是在神奇的stackoverflow上找到了原因:在spring-boot-starter-test组件里,调用了非官方的android-json库。 https://stackoverflow.com/questions/52980064/maven-spring-boot-found-multiple-occurrences-of-org-json-jsonobject-on-the-cl

而这两者之间的差距在于,我所使用的官方库在解析错误时报出的是非检查性异常RuntimeException,也就是不影响代码语法的错误,运行时碰到就直接输出报错信息,停止这一过程了。而android-json库报出的是检查性异常Exception,用户必须在编写代码时就考虑该问题的解决,即try-catch

解决方案在上文链接里也有提到,在pom.xml里把该组建排除依赖即可。在eclipse里可通过图形界面简单操作。

最后再来小声bb一段:怎么又是咕果家的东西……

真的是只有商业公司才上心吗,firefox又给自己搞事情……

不想用chrome啊……