1.A-algorithm
堆排序(大根堆)
public class HeapSort {
private int[] bigHeap = new int[100];
private int capacity = 100;
private int[] result = new int[100];
private int length = 0;
public int[] heapSort(int[] arr){
for(int i = 0; i<arr.length; i++){
HeapInsert(arr[i]);
}
int i = 0;
for(i=0; i<arr.length; i++){
result[i] = bigHeap[0];
Heapfy();
}
return result;
}
public void HeapInsert(int v){
int i = length;
int father = (i-1)/2;
bigHeap[length++] = v;
while (father>=0 && bigHeap[father]<v){
swap(father, i);
i = father;
father = (i-1)/2;
}
}
public void Heapfy(){
length -= 1;
swap(0,length);
int i = 0, lChild = i*2+1, rChild=i*2+2;
int max=0;
if(lChild>=length)
return;
if(rChild>=length){
if(bigHeap[i]<bigHeap[lChild]){
swap(i, lChild);
return;
}
}
max = bigHeap[lChild]>bigHeap[rChild] ? lChild : rChild;
while (bigHeap[i]<bigHeap[max]){
swap(i,max);
i = max;
lChild = i*2+1;
rChild = i*2+2;
if(lChild>=length)
return;
if(rChild>=length){
if(bigHeap[i]<bigHeap[lChild]){
swap(i, lChild);
return;
}else{
return;
}
}
max = bigHeap[lChild]>bigHeap[rChild] ? lChild : rChild;
}
}
private void swap(int j, int k){
int temp = bigHeap[j];
bigHeap[j] = bigHeap[k];
bigHeap[k] = temp;
}
public void printHeap(){
for(int i = 0; i<length; i++){
System.out.print(bigHeap[i]+",");
}
}
}
复制代码
2.R-review
原文:https://clickhouse.com/docs/en/concepts/olap
什么是 OLAP:
OLAP(Online Analytical Processing) ,是一个宽泛的概念,可以从 2 个角度去看:技术和商业。从更高的层级来看,可以反读以下单词:
Processing:表示处理一些源数据中…
Analytical: 表示...产生一些分析的报告和观点…
Online:表示实时的
商业角度的 OLAP
近些年,商人开始意识到数据的价值。那些盲目做决策的公司往往难以跟上竞争的步伐。那些成功公司的数据驱动的方法驱使他们收集所有的只要有点用的数据来做商业决策,并需要一种机制来实时分析这些数据。这就是 OLAP 数据库管理系统(DBMS)的用武之地。
在商业场景,OLAP 使得公司持续的计划、分析、报告业务活动,因此能使效率最大化,减少成本,最终占领市场份额。它既可以在内部系统中完成,也可以外包给 web/移动分析服务、CRM 服务等 SaaS 提供商。OLAP 是很多商业智能应用背后采用的技术。
ClickHouse 是一个 OLAP 数据库管理系统,通常用作 SaaS 解决方案的后端,用于分析特定领域的数据。然而,一些企业不愿意与第三方提供商共享数据,内部数据仓库场景也是可行的。
OLAP 的技术视角:
所有数据库管理系统都可以分为两组:联机分析处理(OLAP)和联机事务处理(OLTP)。前者侧重于生成报告,每个报告都基于大量的历史数据,但并不频繁。而后者通常处理连续的事务流,不断修改数据的当前状态。
在实践中,OLAP 和 OLTP 不是类别,而更像是范围。大多数实际系统通常侧重于其中一种,但如果还需要相反类型的工作,则提供一些解决方案或变通方法。这种情况通常迫使企业集成多个存储系统,这可能不是什么大问题,但是拥有更多的系统会增加维护成本。因此,近年来的趋势是 HTAP(混合事务/分析处理),即两种工作负载都由单个数据库管理系统处理得同样好。
ClickHouse 也不例外,最初,它被设计成尽可能快的 OLAP 系统,它仍然没有成熟的事务支持,但一些功能已经添加,如一致的读/写和突然的更新/删除数据。
OLAP 和 OLTP 系统之间的基本权衡仍然是:
(1)为了高效地构建分析报告,能够单独读取列是至关重要的,因此大多数 OLAP 数据库都是列式的。
(2)单独存储列会增加对行操作的成本,比如追加或就地修改,这与列的数量成正比(如果系统试图收集事件的所有细节以防万一,这可能会很大)。因此,大多数 OLTP 系统按行存储数据。
3.T
线程池的常用 2 种实现方式总结:
(1) JDK1.5 新增的 2 个 API ExcuterService 和 Executors
ExcuterService:真正的线程池接口。常用其子类ThreadPoolExcutor
①void excute(Runnable command):执行任务命令,没有返回值,一般用来执行Runnable
②<T>Future<T> submit (Callable<T> task) :执行任务,有返回值,一般用来执行Callable
③void shutdown() :关闭连接池
Excuters:工具类,线程池的工厂类,用于创建并返回不同类型的线程池
①Excuters.newCachedThreadPool( ) : 创建一个可根据需要创建新线程的线程池
②Excuters.newFixedThreadPool( n ): 创建一个可重用的固定线程池
③Excuters.newSingleThreadExcutor( ) : 创建一个只有一个线程的线程池
④Excuters.newScheduledThreadPool(n) : 创建一个线程池,延迟后运行命令或定期的执行。
eg1: 直接使用ExecutorService 接口
public static void main(String [] args){
ExecutorService service = Executors.newFixedThreadPool (10);
service.excute( new NumberThread1() );
service.excute(new NumberThread2());
service.shutdown();
}
class NumberThread1 implements Runnable{
publie void run(){
.......
}
}
class NumberThread2 implements Runnable{
publie void run(){
.....
}
}
复制代码
(2) 在《阿里巴巴 java 开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了资源的开销。而线程池不允许使用 Executors 去创建,而要通过 ThreadPoolExecutor 方式,这一方面是由于 jdk 中 Executor 框架虽然提供了如 newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活;另外由于前面几种方法内部也是通过 ThreadPoolExecutor 方式实现,使用 ThreadPoolExecutor 有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。
首先看下 ThreadPoolExecutor 的构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
构造函数的参数含义如下:
corePoolSize:指定了线程池中的线程数量,它的数量决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去;
maximumPoolSize:指定了线程池中的最大线程数量,这个参数会根据你使用的workQueue任务队列的类型,决定线程池会开辟的最大线程数量;
keepAliveTime:当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁;
unit:keepAliveTime的单位
workQueue:任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种;
threadFactory:线程工厂,用于创建线程,一般用默认即可;
handler:拒绝策略;当任务太多来不及处理时,如何拒绝任务;
复制代码
4.S
现在计算机学习者,有以下 3 点要重视和注意:
1)锚定目标。
明确自己以后要从事的方向,做算法还是开发?公考还是企业?走管理路线还是技术路线?
2)重视基础。
计算机行业,从业看中的一点就是编程能力,不要求什么都会,但是最起码的基础知识、数据库、入门算法以及编程开发的知识是要懂的,最起码程序员的入门那套东西要悉数掌握。
3)关注前沿。
目前主要就是借助 AI 大语言模型做开发,这是一个大的趋势。毕竟这是提高生产力的工具,掌握使用方法,可以快速转化产出。
#ARTS 打卡计划#
评论