squoosh

Google 开源的图片压缩器 - Squoosh。
Squoosh 可帮助网站开发人员快速压缩图片,在保持图片质量的同时,提升网站访问速度。Squoosh 使用起来也非常简单,在浏览器中打开页面后,可点击选择或直接往里面拖图片,在左下方可选择想要生成的图片格式,右下方选择图片质量,再下载即可。
而且Squoosh 用实时对比来展示压缩效果,你可以左右拖动滑块来比较,如下图左边是原图,右边是压缩后的图片,下面提供多种压缩选项。

website
GitHub

官网

JSON-RPC是一个无状态的、轻量级的跨语言远程过程调用(RPC)协议。

创建实例

InitCommonControls();
m_handleList = GetDlgItem(m_hWnd, IDC_LIST1);

LVCOLUMN LvCol;
memset(&LvCol, 0, sizeof(LvCol));
LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; // Type of mask
LvCol.cx = 200; // width between each coloum
LvCol.pszText = "分组"; // First Header
SendMessage(m_handleList, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);
LvCol.pszText = "设备编号";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);
LvCol.pszText = "设备名称";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);
LvCol.pszText = "是否启用";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);

插入一行

// 填充设备信息列表
LVITEMA item;
memset(&item, 0, sizeof(item)); // Zero struct's Members
// Setting properties Of members:
item.mask = LVIF_TEXT; // Text Style
item.cchTextMax = 256; // Max size of test
item.iItem = 0; // choose item
item.iSubItem = 0; // Put in first coluom
item.pszText = "Item 0"; // Text to display (can be from a char variable) (Items)

SendMessage(m_handleList, LVM_INSERTITEM, 0, (LPARAM)&item); // Send info to the Listview
char Temp[512];
for (int i = 1; i <= 5; i++) // Add SubItems in a loop
{
item.iSubItem = i;
sprintf(Temp, "SubItem %d", i);
item.pszText = Temp;
SendMessage(m_handleList, LVM_SETITEM, 0, (LPARAM)&item); // Enter text to SubItems
}

创建实例

InitCommonControls();
m_handleList = GetDlgItem(m_hWnd, IDC_LIST1);

LVCOLUMN LvCol;
memset(&LvCol, 0, sizeof(LvCol));
LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; // Type of mask
LvCol.cx = 200; // width between each coloum
LvCol.pszText = "分组"; // First Header
SendMessage(m_handleList, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);
LvCol.pszText = "设备编号";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);
LvCol.pszText = "设备名称";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);
LvCol.pszText = "是否启用";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);

插入一行

// 填充设备信息列表
LVITEMA item;
memset(&item, 0, sizeof(item)); // Zero struct's Members
// Setting properties Of members:
item.mask = LVIF_TEXT; // Text Style
item.cchTextMax = 256; // Max size of test
item.iItem = 0; // choose item
item.iSubItem = 0; // Put in first coluom
item.pszText = "Item 0"; // Text to display (can be from a char variable) (Items)

SendMessage(m_handleList, LVM_INSERTITEM, 0, (LPARAM)&item); // Send info to the Listview
char Temp[512];
for (int i = 1; i <= 5; i++) // Add SubItems in a loop
{
item.iSubItem = i;
sprintf(Temp, "SubItem %d", i);
item.pszText = Temp;
SendMessage(m_handleList, LVM_SETITEM, 0, (LPARAM)&item); // Enter text to SubItems
}

创建实例

InitCommonControls();
m_handleList = GetDlgItem(m_hWnd, IDC_LIST1);

LVCOLUMN LvCol;
memset(&LvCol, 0, sizeof(LvCol));
LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; // Type of mask
LvCol.cx = 200; // width between each coloum
LvCol.pszText = "分组"; // First Header
SendMessage(m_handleList, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);
LvCol.pszText = "设备编号";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);
LvCol.pszText = "设备名称";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);
LvCol.pszText = "是否启用";
SendMessage(m_handleList, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);

插入一行

// 填充设备信息列表
LVITEMA item;
memset(&item, 0, sizeof(item)); // Zero struct's Members
// Setting properties Of members:
item.mask = LVIF_TEXT; // Text Style
item.cchTextMax = 256; // Max size of test
item.iItem = 0; // choose item
item.iSubItem = 0; // Put in first coluom
item.pszText = "Item 0"; // Text to display (can be from a char variable) (Items)

SendMessage(m_handleList, LVM_INSERTITEM, 0, (LPARAM)&item); // Send info to the Listview
char Temp[512];
for (int i = 1; i <= 5; i++) // Add SubItems in a loop
{
item.iSubItem = i;
sprintf(Temp, "SubItem %d", i);
item.pszText = Temp;
SendMessage(m_handleList, LVM_SETITEM, 0, (LPARAM)&item); // Enter text to SubItems
}

临界区本身不是内核对象,它是工作在用户态的,所以速度快一些
互斥量、信号量、事件都是Windows的内核对象,当程序对这些对象进行控制时会自动转换到核心态。

C++ 方式

/// 实例容器锁
mutable std::mutex mutMapInst;

{
std::lock_guard<std::mutex>lk(m_devInfo.mutMapInst);
m_devInfo.mapInst.emplace(make_pair(instId, &dev));
}

MFC 方式

CMutex Mutex;

CSingleLock SingleLock(&Mutex);
SingleLock.Lock();

Win32 方式

CRITICAL_SECTION cs;

InitializeCriticalSection(&m_curInfo.cs);

EnterCriticalSection(&m_curInfo.cs);
m_curInfo.timeCmp = time(NULL);
LeaveCriticalSection(&m_curInfo.cs);

DeleteCriticalSection(&m_curInfo.cs);

同步事件

// 同步发送数据的,读取完毕后,在发送
HANDLE m_hEvent_write;

m_hEvent_write = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // initial state is nonsignaled
TEXT("WriteEvent") // object name
);

WaitForSingleObject(pwnd->m_hEvent_write, INFINITE);
// go on
::SetEvent(m_hEvent_write);

导数的含义:函数在某一点的导数就是函数在这一点上瞬时变化率,也是函数图像在这一点上的切线的斜率

作用:导数可以帮助我们判断函数的单调性

函数的单调性:增函数,减函数
同向为增,反向为减

一次函数 $f(x) = kx + b$
$$
\begin{cases}
k>0, &f(x) 为增\\
k<0, &f(x) 为减\\
\end{cases}
$$

如何求导

  1. 基本函数的求导
    $f(x) = C$ 的导数是 $f’(x) = 0$
    $f(x) = kx$ 的导数是 $f’(x) = k$
    $f(x) = x^2$ 的导数是 $f’(x) = 2x$
    $f(x) = x^\alpha$ 的导数是 $f’(x) = {\alpha}x^{\alpha-1}$
    $f(x) = sinx$ 的导数是 $f’(x) = cosx$
    $f(x) = cosx$ 的导数是 $f’(x) = -sinx$
    $f(x) = e^x$ 的导数是 $f’(x) = e^x$
    $f(x) = lnx$ 的导数是 $f’(x) = \frac{1}{x}$

$y=3x^3+8x^2-9x+6$
解:$y’=9x^2+16x-9$

$ a^2 = 100 $
$ a = \pm10 $
第一个表达式计算叫做开平方运算,100 叫做被开方数,$\pm10$ 叫做平方根
例如: 4 开平方 = $\pm2$ 9开平方 = $\pm3$
可以看到有两个互为相反数的平方根,其中正数的根叫做算术平方根。比如 4的算术平方根就是2,9的算术平方根就是3。
这里要注意平方根和算术平方根的区别
$0^2 = 0$ 所以 0 的平方根只有一个
只有0和正数有平方根
数学符号表示方法:
求4的算术平方根:$\sqrt{4}=2$
如果要表示开平方:$\pm{\sqrt{4}}=\pm2$

range for

string str("some string");  
// range for 语句
for(auto &c : str)
{
c = toupper(c);
}

for (auto&& [first,second] : mymap) {
// use first and second
}