CentOS7.0安装mysql5.7

CentOS7.0里的yum默认不带mysql最新版本(其默认数据库是mariaDB,可替代mysql),所以如果要安装mysql需要参考A Quick Guide to Using the MySQL Yum Repository这个文档。

首先安装rpm源:

wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch
sudo rpm -Uvh mysql80-community-release-el7-3.noarch.rpm

然后要选择安装哪个版本,默认是最新版本(8.0),我们希望安装5.7:

sudo yum-config-manager --disable mysql80-community
sudo yum-config-manager --enable mysql57-community

检验版本配置成功:

yum repolist enabled | grep mysql

然后执行安装命令:

sudo yum install mysql-community-server

启动mysqld服务:

sudo service mysqld start

mysql安装后会生成一个随机的root用户密码,用下面的命令获取到:

sudo grep 'temporary password' /var/log/mysqld.log

修改root用户密码:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';

使用Apache Drill处理数据文件

本文针对drill版本1.8。

安装Drill

官网下载tar包并解压即可,linux和windows都是如此。
注意:drill要求java版本是8或以上。

命令行使用Drill

最简单的方式是用embedded模式启动drill(启动后可以在浏览器里访问 http://localhost:8047 来管理drill):

bin/drill-embedded

这样就以嵌入模式启动了drill服务并同时进入了内置的sqline命令行。如果drill服务已经启动,则可以这样进入sqline命令行(参考):

bin/sqline -u jdbc:drill:drillbit=localhost

作为例子,用SQL语法查询一下drill自带的数据(命令行里的cp表示classpath,注意查询语句最后要加分号结尾):

apache drill> SELECT * FROM cp.`employee.json` LIMIT 3;

查询任意数据文件的内容:

apache drill> SELECT * FROM dfs.`/home/hao/apache-drill-1.16.0/sample-data/region.parquet`;

退出命令行用!quit

配置和查看Drill参数

如果要永久性修改参数值,需要修改$DRILL_HOME/conf/drill-override.conf文件(见文档);SET、RESET命令可以在当前session里修改参数值(文档)。

配置参数:

SET `store.parquet.block-size` = 536870912

重置参数为缺省值:

RESET `store.parquet.block-size`

查看参数:

select * from sys.options where name = 'store.parquet.block-size'

在java代码里使用Drill

下面是在java代码里使用Drill的例子代码,要注意的一点是,JDBC的URL是jdbc:drill:drillbit=localhost,而不是很多教程上说的jdbc:drill:zk=localhost

package com.acme;

import java.sql.*;

public class DrillJDBCExample {
    static final String JDBC_DRIVER = "org.apache.drill.jdbc.Driver";
    //static final String DB_URL = "jdbc:drill:zk=localhost:2181";
    static final String DB_URL = "jdbc:drill:drillbit=localhost"; //for embedded mode installation

    static final String USER = "admin";
    static final String PASS = "admin";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try{
            Class.forName(JDBC_DRIVER);
            conn = DriverManager.getConnection(DB_URL,USER,PASS);

            stmt = conn.createStatement();
            /* Perform a select on data in the classpath storage plugin. */
            String sql = "select employee_id,first_name,last_name from cp.`employee.json`";
            ResultSet rs = stmt.executeQuery(sql);

            while(rs.next()) {
                int id  = rs.getInt("employee_id");
                String first = rs.getString("first_name");
                String last = rs.getString("last_name");

                System.out.print("ID: " + id);
                System.out.print(", First: " + first);
                System.out.println(", Last: " + last);
            }

            rs.close();
            stmt.close();
            conn.close();
        } catch(SQLException se) {
            //Handle errors for JDBC
            se.printStackTrace();
        } catch(Exception e) {
            //Handle errors for Class.forName
            e.printStackTrace();
        } finally {
            try{
                if(stmt!=null)
                    stmt.close();
            } catch(SQLException se2) {
            }
            try {
                if(conn!=null)
                    conn.close();
            } catch(SQLException se) {
                se.printStackTrace();
            }
        }
    }
}

让Drill访问数据库

根据要访问的数据库的不同,需要为Drill添加相应的驱动,方法见RDBMS Storage Plugin

利用Drill将csv格式转换为parquet格式

原理是在drill里创建一张格式为parquet的表,该表的路径(下例中的/parquet1)对应的是磁盘上的一个目录。

ALTER SESSION SET `store.format`='parquet';
ALTER SESSION SET `store.parquet.compression` = 'snappy';

CREATE TABLE dfs.tmp.`/parquet1` AS 
SELECT * FROM dfs.`/my/csv/file.csv`;

让drill支持.zip、.arc压缩格式

(暂缺)

参考资料

Drill in 10 Minutes
How to convert a csv file to parquet

Fragment里getActivity()为空问题

问题

一个常见的场景:fragment在onViewCreated()里执行一个任务(AsyncTask)加载一些数据,任务没有完成时,用户切换到其他界面,这时如果在代码里调用了getActivity()方法,得到的将是空值。

这是一个在本地不容易发现的问题,但通过在线异常报告(例如bugly或友盟)容易发现。

解决方法

同时采取以下两项措施:

  1. 在任务的doInBackground()的一开始就获取context,而不是在每处都是用getActivity()获取;
  2. onStop()onDetach()方法里取消正在执行的任务以避免onPostExecute()被继续执行。

参考资料

getActivity() returns null in Fragment function

应用计时手机权限配置指南

应用计时需要常驻手机后台才能准确计时,目前各个品牌的手机默认都会对后台应用做限制,以达到节电的目的,因此需要手工开启一些权限。

各品牌手机开启权限的方法如下:

1. 小米手机(MIUI)

开机自启动(必须)

方法1:安全中心 -> 应用管理 -> 权限 -> 自启动 -> 自启动管理
方法2:设置 -> 授权管理 -> 自启动管理

悬浮窗(建议)

悬浮窗提醒时长,以及强制模式禁用当前应用,这两项功能需要悬浮窗权限。
方法1:安全中心 -> 应用管理 -> 权限 -> 应用权限管理 -> 应用计时 -> 显示悬浮窗
方法2:设置 -> 授权管理 -> 应用权限管理 -> 应用计时 -> 显示悬浮窗

无障碍(建议)

当计时模式选择的是辅助模式时,这一项是必须配置的。
方法:设置 -> 更多设置 -> 无障碍

锁定后台(建议)

锁定后台的目的是避免一键内存清理。
MIUI10:打开最近任务列表,按住应用计时,在弹出菜单里选择加锁。
MIUI9:打开最近任务列表,下拉应用计时加锁。

后台弹出界面(建议)

强制模式下,如果选择了超时直接退出应用,需要此项权限。
方法:安全中心 -> 应用管理 -> 权限 -> 应用权限管理 -> 应用计时 -> 后台弹出界面

2. 华为手机(EMUI 9)

开机自启动(必须)

方法:设置 > 应用 > 自启动 > 应用计时 > 允许自启动

悬浮窗(建议)

悬浮窗提醒时长,以及强制模式禁用当前应用,这两项功能需要悬浮窗权限。
方法:设置 > 应用 > 应用计时 > 显示在其他应用之上

无障碍(建议)

方法:设置 > 智能辅助 > 无障碍 > 应用计时

锁定后台(建议)

锁定后台的目的是避免一键内存清理。
方法:打开最近任务列表,下拉应用计时加锁。

3. 魅族手机 (Flyme 7.2)

开机自启动(必须)

待补充

后台运行(建议)

方法: 手机管家 > 权限管理 > 应用管理 > 应用计时 > 后台管理 > 允许后台运行

悬浮窗(建议)

悬浮窗提醒时长,以及强制模式禁用当前应用,这两项功能需要悬浮窗权限。
方法:手机管家 > 权限管理 > 应用管理 > 应用计时 > 悬浮窗

无障碍(建议)

方法:设置 > 辅助功能 > 无障碍 > 应用计时

锁定后台(建议)

锁定后台的目的是避免一键内存清理。
方法:多任务列表,下拉应用计时加锁。

4. VIVO手机 (Funtouch OS)

开机自启动(必须)

方法:设置 > 更多设置权限管理应用计时单项权限设置自启动

悬浮窗(建议)

悬浮窗提醒时长,以及强制模式禁用当前应用,这两项功能需要悬浮窗权限。
方法:设置 > 更多设置权限管理应用计时单项权限设置悬浮窗

无障碍(建议)

方法:设置 > 更多设置 > 辅助功能 > 应用计时

锁定后台(建议)

锁定后台的目的是避免一键内存清理。
方法:多任务列表,下拉应用计时图标加锁。

后台弹出界面(建议)

方法:设置 > 更多设置权限管理应用计时单项权限设置后台弹出界面

由于市面手机机型和版本数量众多,以上内容难免有不完整或错误之处,请加QQ群763350557反馈您的宝贵意见。

感谢以下网友的贡献:

  • 吃瓜群众
  • 冬日可爱

Intellij IDEA输出jar包注意事项

Intellij IDEA Ultimate 2016.1

菜单File -> Project Structures -> Artifacts

注意:MANIFEST.MF文件不要使用默认的路径,应放在项目根目录下,否则打包后此文件不在jar包内或内容不正确。

 

输出"uber-jar"运行时可能会遇到错误“Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes”,此时可尝试删除jar包里META-INF目录下所有的.SF、.DSA和.RSA文件。

参考:https://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar

Win7访问家庭组共享文件夹提示没有权限

问题:Win7电脑访问Win10电脑的共享文件夹时,提示下面的错误:

解决方法:

1、在Win10高级共享设置里,勾选“关闭密码保护共享”。这样客户端访问时就不会提示输入用户名密码了(我遇到的情况是即使输入了正确的用户名密码也提示不正确,这个问题并没解决)。

2、在Win10共享的文件夹属性的“安全”页里,加入"Everyone"这个用户并设置足够的权限即可。并不像网上说的那样,需要修改组策略“网络安全:LAN 管理器身份验证级别”。

查看Android应用占用内存情况

要查看指定app在手机上占用多少运行内存,首先将手机连接到电脑,然后在命令行执行下面的命令(其中com.my.package.name是app的包名):

adb shell dumpsys meminfo com.my.package.name

执行结果通常如下,其中Pss那一列的值(单位:kB)是我们主要需要关注的:

adb-dumpsys

参考链接:

adb shell dumpsys meminfo - What is the meaning of each cell of its output?

AndroidStudio无法在MIUI安装APK问题

现象

AndroidStudio 2.3,在小米4c搭载miui8真机上运行程序,提示下面的错误信息:

Installation error: INSTALL_CANCELED_BY_USER

 

解决方案

在MIUI开发者选项里,关闭“启用MIUI优化”选项。

关闭此选项时被要求重启,重启后暂时没有发现日常使用有什么变化。

Update: 关闭此选项后发现手机发热和耗电明显,应该是对后台应用的拦截失效导致的。

turn_off_miui_opt

参考链接:

Android Studio: Application Installation Failed

JVM内存模型

JVM的内存分为堆(heap)和栈(thread stack)两类区域,分别存放不同数据,规则如下。

以下数据存放在heap中:

  • 所有对象(object)。但对象的method里的local variable存放在stack中。
  • 所有对象的member variable,不论是primitive或是指向一个对象。
  • 所有静态类的variable

以下数据存放在stack中(每个线程有自己的thread stack,互相不可见):

  • 当前线程执行过的所有方法(method)
  • 当前线程内所有local variable(method里的变量)。如果此变量指向一个对象,则变量存放在stack中而对象仍然存放在heap中。
  • 当前线程内所有primitive类型(如int, long, boolean)的local variable

java-memory-model-3

参考资料:

Java Memory Model

Java 内存区域和GC机制