MySQL分段统计函数INTERVAL和ELT

需求

期末考试成绩出来了,结果需要分为不及格(0-59),合格(60-84),优秀(80+)三个段,老师需要统计每个段成绩的分布情况。

分数表score结构如下:

id int
user_id int
score int

使用INTERVAL函数对学生成绩分段

SELECT user_id,score,INTERVAL(score,60,85) as step from score

INTERVAL函数会根据score返回0(少于60),1(60-74),2(85以及以上)

INTERVAL返回的结果进行分组:

SELECT INTERVAL(score,60,85),COUNT(*) AS num as step from score GROUP BY INTERVAL(score,60,85)

得到:

0, 5
1, 80
2, 15

使用ELT函数为阶段命名

ETL方法会建立重命名,将1,2,3分别转化为不及格,合格,优秀,但是etl不能是从0开始的,所以我们可以在INTERVAL分组时加一个0,将0分以下的划分为0,0-59的划为1,依次类推

SELECT INTERVAL(score,0,60,85),COUNT(*) AS num as step from score GROUP BY INTERVAL(score,60,85)

得到:

1, 5
2, 80
3, 15

最终SQL:

SELECT ELT(INTERVAL(score,0,60,85),"不及格","合格","优秀"),COUNT(*) AS num as step from score GROUP BY ELT(INTERVAL(score,0,60,85),"不及格","合格","优秀")

得到:

不及格, 5
合格, 80
优秀, 15

PHP 5/7/8编译安装实例

PHP 5.6

PHP 5只能用openssl 1.0, curl使用7.70.0,freetype 2.6.5

./configure --prefix=/usr/local/php/5.6 \
--enable-fpm \
--enable-bcmath \
--enable-calendar \
--enable-exif \
--with-gd \
--enable-gd-jis-conv \
--enable-mbstring \
--with-pdo-mysql \
--with-pdo-pgsql \
--enable-sockets \
--enable-opcache \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--with-xpm-dir \
--enable-gd-native-ttf  \
--enable-gd-jis-conv \
--with-openssl=/usr/local/openssl-1.0

make -j 6

sudo make install

/usr/local/php/5.6/bin/php -m

PHP 7.4

./configure \
--prefix=/usr/local/php/7.4 \
--enable-fpm \
--with-fpm-user=ning \
--with-fpm-group=ning \
--with-pdo-mysql \
--with-pdo-pgsql \
--with-iconv-dir \
--with-freetype \
--with-jpeg \
--with-zlib \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-ftp \
--enable-gd \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-soap \
--with-gettext \
--disable-fileinfo \
--enable-opcache \
--with-sodium \
--with-webp

make -j 6

sudo make install

/usr/local/php/7.4/bin/php -m

PHP 8.1

configure \
--prefix=/usr/local/php/8.1 \
--enable-fpm \
--with-fpm-user=ning \
--with-fpm-group=ning \
--with-pdo-mysql \
--with-pdo-pgsql \
--with-freetype \
--with-jpeg \
--with-zlib \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-ftp \
--enable-gd \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--enable-soap \
--with-gettext \
--disable-fileinfo \
--enable-opcache \
--with-sodium \
--with-webp

make -j 6

sudo make install

/usr/local/php/8.1/bin/php -m

Linux Shell清除过期文件

find $log_path -cmin +1 -type d | xargs rm -rf {} # 1分钟前创建的
find $log_path -mmin +1 -type d | xargs rm -rf {} # 1分钟前修改的
find $log_path -ctime +1 -type d | xargs rm -rf {} # 1天前创建的
find $log_path -mtime +1 -type d | xargs rm -rf {} # 1天前修改的
find $log_path/* -mtime +1 -type d | xargs rm -rf {} # 30天钟前修改的,不包括当前目录

nginx的多条件and配置

set $match_host '0';
set $match_url '0';
if ($host ~ "192.168.1.105") {
    set $match_host '1';
}
if ($request_uri ~* "test") {
    set $match_url '${match_host}1';
}
if ($match_url = '11'){
   return 404;
}

什么是全能程序员?全能程序员怎么来的?

最近看到阮一峰的《全能程序员 vs 特长程序员》提到观点,结合自身经历,发表一点不同的看法。

  • “软件行业"全能程序员"的出路,明显不如"特长程序员"”

  • "全能程序员"在这个行业是不受待见的,被视为"万金油"。

什么是全能程序员?全能程序员怎么来的?

一个程序员,如果长期在某一领域工作,可能会发现原有的知识不够用,这时候需要学习新的知识,恰好你乐意去学习,你也能挤出活创造时间和机会,然后你就去学习并掌握了,你运用和掌握的学习的知识,在使用的过程中你逐步发现他们的原理,了解新知识与旧知识的联系和异同,久而久之,你掌握了解的新知识越来越多,能解决的问题越来越多,虽然随着时间的迁移许多新知识也变成了旧知识,但是在别人眼里,你成了他们眼中各方面问题都能解决的“全能程序员”。所以:

  • 全能程序员的定义应该是:在某一领域,能够解决大多数别人不能解决问题。而不是能解决别能解决的问题的大多数。

  • 全能程序员是怎么来的:全能程序员是遇到问题后不断追根究底,在别人已经停止研究情况下,仍然不断学习和探索,直到到最终解决问题或者找到问题的最优解,在这个过程中不断积累成长起来的。

全能程序员的优势

  • 成为全能程序员是很多职位的最佳途径,如:CTO, devops, 架构师

  • 更好的解决问题的办法:如果将程序员比做木工,在全能手里,永远不止有锤子,全能程序员不可能只会干钉钉子的活,他们抛光会用狍子,打眼会用锉子,电锯和电转也是最先掌握的

  • 最快找到问题的解决办法:他们清楚整件事情的来龙去脉和原理,找问题不用开IDE,在心里就能完成DEBUG和需求分析,开IDE只是为了验证和最终解决问题

  • 最高效的解决问题方式:他们从架构上,组织上找到最有效率的协作方法,他们明白每多一道沟通就是浪费

  • 最节省资源:好比电脑CPU没在空耗,老板付一份工资找了一个需要几个人干的活

全能程序员的缺陷

  • 个人的精力是有限的,你不能一个解决所有问题,你仍然需要一个靠谱的团队,电脑可以不休息人需要休息

  • 思维切换需要时间,电脑可以多任务人往往不可以

  • 你个人的能力会被其他人平均,老板可能愿意付你2倍工资,往往没法付你10倍工资,即使你是10倍程序员

  • 你需要付出的比别人多,除非你乐意,否则没法坚持

全能程序员/全能非程序员的现实例子

全能非程序员的例子:

  • 毛泽东不仅会打仗,诗的气势普通人恐怕也很难达到;
  • 本杰明富兰克林不仅能当好总统还会发明创造;
  • 达芬奇不仅能画好蛋;
  • 马斯克创Paypal、造车、造火箭和造星链。。。

全能程序员的例子:

  • 几乎所有编程语言发明者都精通其他一门到多门语言
  • 合格的devops或者架构师都精通一门语言+数据库+非关系存储+linux+分布式

事情的本质

  • Python、C++是全能的,PHP、Go、R、Lisp是特长的,他们都是成功的
  • 罗技、格力专注成功,联想、华为、小米、通用不那么专注也很成功
  • 马云不会编程能带领阿里成为技术性领先的公司,马化腾、王兴、张小龙搞技术的也不会因此管理和产品能力就差一点

总结:全能和特长本不矛盾,各阶段选取合理的发展方向。作为技术人在一个学习好英语,掌握几门编程语言、几种数据库、学习下devops,学习管理、产品和运营,先成为一个领域专家,然后架构师,CTO,再自己创立公司,仍然不失为一条明确的路径。

linux(ubuntu/manjaro)让JetBrains(Phpstorm/Pycharm/Intellij)支持ibus中文

目前的解决方法:

  • 下载这个https://cache-redirector.jetbrains.com/intellij-jbr/jbr_jcef-11_0_7-linux-x64-b765.53.tar.gz JRE 并解压。
  • 然后Help | Find Action在IDE主菜单中点击,输入Choose Boot Java Runtime for the IDE,回车,然后点击New下拉,向下滚动,找到Add Custom Runtime选项,选择这个解压后的JRE运行,重启IDE。
  • 对于 2020.3.x 版本,您需要使用此步骤切换到此 JRE:https ://www.jetbrains.com/help/idea/2020.3/switching-boot-jdk.html#switch-jdk
  • 或者尝试使用上述步骤切换到 OpenJDK 11(AdoptJDK 11、OracleJDK 11)。

参考

Ubuntu下PHP 7和PHP 8多版本共存以及composer指定版本

修改更新源

sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt upgrade

安装PHP7以及常用扩展

sudo apt install php7.4-common php7.4-cgi php7.4-gd php7.4-mysql php7.4-xml php7.4-cli php7.4-json php7.4-sqlite3 php7.4-xmlrpc php7.4-bcmath php7.4-enchant
php7.4-opcache php7.4-readline php7.4-xsl php7.4-bz2 php7.4-curl  php7.4-fpm php7.4-mbstring php7.4-pgsql php7.4-tidy php7.4-zip

安装PHP8以及常用扩展

sudo apt install php8.0-common php8.0-cgi php8.0-gd php8.0-mysql php8.0-xml php8.0-cli php8.0-sqlite3 php8.0-xmlrpc php8.0-bcmath php8.0-enchant php8.0-opcache php8.0-readline php8.0-xsl php8.0-bz2 php8.0-curl  php8.0-fpm php8.0-mbstring php8.0-pgsql php8.0-tidy php8.0-zip

composer安装以及使用

安装composer

php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer

配置composer使用镜像

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

运行composer时指定PHP版本

php8.0 /usr/local/bin/composer
php7.4 /usr/local/bin/composer
alias composer7='php7.4 /usr/local/bin/composer'
alias composer8='php8.0 /usr/local/bin/composer'

使用symfony composer以及.php_version文件指定PHP版本

查看本地所有PHP版本

symfony local:php:list

显示结果

┌─────────┬────────────┬────────────┬─────────┬─────────┬─────────┬─────────┐
│ Version │ Directory  │  PHP CLI   │ PHP FPM │ PHP CGI │ Server  │ System? │
├─────────┼────────────┼────────────┼─────────┼─────────┼─────────┼─────────┤
│ 7.4.14  │ /usr/local │ bin/php    │         │         │ PHP CLI │ *       │
│ 7.4.16  │ /usr       │ bin/php7.4 │         │         │ PHP CLI │         │
└─────────┴────────────┴────────────┴─────────┴─────────┴─────────┴─────────┘

指定symfony composer使用PHP7

echo 7 > .php-version

指定symfony composer使用PHP8

echo 8 > .php-version

使用symfony composer安装或者更新包

symfony composer install

参考

Qt Windows CMakeLists.txt 注意事项

改为32位GUI启动

默认会出现命令行黑窗口,需要添加图形界面类型

if(WIN32)
    set(GUI_TYPE WIN32)
elseif(APPLE)
    set(GUI_TYPE MACOSX_BUNDLE)
endif()

add_executable(${CMAKE_PROJECT_NAME} ${GUI_TYPE} ${SRC} ${RES})

为QT应用添加管理员权限

set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\"")

解决复制dll错误问题

第一次复制成功后,注释以下代码

    foreach (QT_LIB ${REQUIRED_LIBS})
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/bin/Qt${QT_VERSION}${QT_LIB}${DEBUG_SUFFIX}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
    endforeach (QT_LIB)

设置CMAKE_PREFIX_PATH路径

set(CMAKE_PREFIX_PATH "D:\\Qt\\Qt5.12.9\\5.12.9\\msvc2017\\")

捕获Qt Crash全图教程

关键点

  • 在main.cpp引入SetUnhandledExceptionFilter程序奔溃时生成dmp文件(代码)
  • Build release时包含debug信息(图)
  • Link dbghelp.lib库(图)
  • Build post自动复制qt依赖库(图)

Qt捕获Crash示例代码下载

Qt捕获Crash关键代码

main.cpp

#include <QtWidgets/QApplication>
#include <QMessageBox>
#include <QDateTime>
#include <QDir>
#include <QDebug>
#include "QtCrashApplication.h"
#include "main.h"

#ifdef Q_OS_WIN
#include <Windows.h>
#include <DbgHelp.h>
#endif

#ifdef Q_OS_WIN
static LONG WINAPI exceptionCallback(struct _EXCEPTION_POINTERS* exceptionInfo)
{
    QCoreApplication* app = QApplication::instance();

    QString savePath = app->applicationDirPath() + "dump/";
    qDebug() << "save path :" << savePath;
    QDir dir(savePath);
    if (!dir.exists() && !dir.mkpath(savePath)) {
        app->exit(E_UNEXPECTED);
        return EXCEPTION_EXECUTE_HANDLER;
    }

    savePath.append("assit_");
    savePath.append(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
    savePath.append(".dmp");

    HANDLE dump = CreateFileW(savePath.toStdWString().c_str(), GENERIC_WRITE,
        0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == dump) {
        app->exit(E_UNEXPECTED);
        return EXCEPTION_EXECUTE_HANDLER;
    }

    MINIDUMP_EXCEPTION_INFORMATION miniDumpExceptionInfo;
    miniDumpExceptionInfo.ExceptionPointers = exceptionInfo;
    miniDumpExceptionInfo.ThreadId = GetCurrentThreadId();
    miniDumpExceptionInfo.ClientPointers = TRUE;
    DWORD idProcess = GetCurrentProcessId();
    MiniDumpWriteDump(GetCurrentProcess(), idProcess, dump,
        MiniDumpNormal, &miniDumpExceptionInfo, NULL, NULL);

    CloseHandle(dump);

    app->exit(E_UNEXPECTED);
    return EXCEPTION_EXECUTE_HANDLER;
}
#endif

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);

#ifdef Q_OS_WIN
    SetUnhandledExceptionFilter(exceptionCallback);
#endif

    QtCrashApplication w;
    w.show();
    return a.exec();
}

QtCrashApplication.cpp

#include "QtCrashApplication.h"

QtCrashApplication::QtCrashApplication(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    QObject::connect(ui.CrashButton, SIGNAL(clicked()), this, SLOT(crashMe()));
}

void QtCrashApplication::crashMe() {
    int i = 0;
    int n = 1 / i;
    ui.CrashButton->setText(QString(n));
}

新建项目

新建项目

配置项目

配置项目

项目配置向导

项目配置向导

项目配置向导2

项目配置向导2

编写会奔溃程序

编写会奔溃程序

程序运行截图

程序运行截图

点击运行后出现异常

点击运行后出现异常

自动生成依赖qt库

"$(QTDIR)\bin\windeployqt.exe" "$(OutDir.TrimEnd('\'))" --$(Configuration.toLower())

自动生成依赖qt库

自动生成依赖库

自动生成依赖库

生成release时生成debug信息

生成release时生成debug信息

包含dbghelp.lib库

包含dbghelp.lib库

查看生成记录

查看生成记录

查看结果

查看结果

参考