四川某商行笔试

面试:

先做三题,简单,但有一题做错,如下:

class Child {
    String s1 = new String("123");
    String s2 = "456";
    char s[] = {'a' , 'b' , 'c'};
    int a = 5;

public void change(String s1 , String s2 , char s[] , int a) {
        s1 = "112233";
        s2 = "445566";
        s[0] = 'A';
        a = 10;
}
public static void main(String[] args) {
        Child c = new Child();
        c.change(c.s1 , c.s2 , c.s , c.a);
        System.out.println(c.s1);
        System.out.println(c.s2);
        System.out.println(c.s);
        System.out.println(c.a);
}

应输出:

123 

456

Abc

5

=> s1和s2未发生改变(引用传递);s发生改变(引用传递);a未发生改变(值传递)

=> String类型是引用类型,按道理说引用传递,但为什么不发生改变?

=> String对象,值先放在常量池,对象放在堆,对象指向常量池的值。

=> String传到函数里赋新值,新值再次在常量池里创建,然后实参指向新的地址,但形参未发生指向的改变。因此Java归根结底是值传递!

(1)offer情况+为什么不去+实习公司薪资+转正薪资

(2)对数据库有了解吗,主键和外键,平时设计的时候会去设置吗?

(3)你会哪一块?擅长哪一块?对哪一方面最有热情,不惜一切去完成。

(4)SpringCloud和SpringBoot有什么区别?SpringCloud各个服务之间怎么通信?你的服务是有状态还是无状态的?我回答session,存放redis(有状态的);但是忘记说token(无状态)。

(5)对Python有了解吗?我回答否,但是会C/C++,从这个开始入门的。其实之前上课了解过一点。

(6)期望月薪多少?说实话,说低了....但该行平台很不错,想干一辈子,增长空间大。

(7)实习做的什么?你们实习公司产品的定位是什么,面向的用户是?整个系统的流程是怎么实现的,你有了解吗?我说到GRPC的时候,就被打断了。

(8)无反问环节。体验良好,但愿收到体检通知。


1.C++宏。

#define PI 3.14
标识符被宏定义后,则:标识符 == 宏名

程序中出现的是宏名;
在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换。

替换后才进行编译,宏替换是简单的替换。 
__LINE__  :当前程序行的行号,表示为十进制整型常量
__FILE__  :当前源文件名,表示字符串型常量
__DATE__ :转换的日历日期,表示为Mmm dd yyyy 形式的字符串常量,Mmm是由asctime产生的。
__TIME__  :转换的时间,表示"hh:mm:ss"形式的字符串型常量,是有asctime产生的。(asctime貌似是指的一个函数)

 ex:

#include<iostream>
#define LINE __LINE__
#define FILE __FILE__

#define TIME __TIME__
#define DATE __DATE__
using namespace std;
int main() { 
	cout<<LINE<<endl;
	cout<<FILE<<endl;
	cout<<TIME<<endl;
	cout<<DATE<<endl;
	return 0;
} 

2.数据库死锁特点。

产生死锁的四个必要条件:互斥;请求和保持;不可抢占;循环等待。

a. 使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制实现。
即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表
增加一个“version”字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。
此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,
如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
乐观锁机制避免了长事务中的数据库加锁开销(用户A和用户B操作过程中,都没有对数据库数据加锁),
大大提升了大并发量下的系统整体性能表现。Hibernate 在其数据访问引擎中内置了乐观锁实现。
需要注意的是,由于乐观锁机制是在我们的系统中实现,
来自外部系统的用户更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。

b. 使用悲观锁进行控制。悲观锁大多数情况下依靠数据库的锁机制实现,
如Oracle的Select … for update语句,以保证操作最大程度的独占性。
但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。
如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时
(如更改用户账户余额),如果采用悲观锁机制,也就意味着整个操作过程中
(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),
数据库记录始终处于加锁状态,可以想见,如果面对成百上千个并发,
这样的情况将导致灾难性的后果。所以,采用悲观锁进行控制时一定要考虑清楚。

  事务回退机制:略,后续有机会补充。

3.父子类,各有构造函数,各有普通函数,各有一个成员变量x,分别调用普通函数后的,x值的变化情况。

package com.example.kevintest.demo.msh;
public class Father {
    public Father() {
        System.out.println("father 构造函数");
    }
    public void  move() {
        System.out.println("father move");
    }
}
class Child extends Father {
    public Child() {
        System.out.println("child 构造函数");
    }
    public void  move() {
        System.out.println("child move");
    }
    public static void main(String[] args) {
        Father fc = new Child();
        fc.move();
        System.out.println("");
        Father f = new Father();
        f.move();
    }
}


console:
father 构造函数
child 构造函数
child move

father 构造函数
father move

4.Tomcat简述,怎么部署应用,常用开发工具?

5.JSP中上传数据到后台Servlet,用什么类对象接收的?用什么方法取出数据的?

request;

request.getParameter();

6.前中序遍历,求后序。

//层序遍历
void FloorPrint_QUEUE(pTreeNode &Tree) //层序遍历_队列实现
{
    queue < pTreeNode> q;
    if (Tree != NULL)
    {
        q.push(Tree);   //根节点进队列
    }

    while (q.empty() == false)  //队列不为空判断
    {
        cout << q.front()->data << " → "; 

        if (q.front()->leftPtr != NULL)   //如果有左孩子,leftChild入队列
        {
            q.push(q.front()->leftPtr);   
        }

        if (q.front()->rightPtr != NULL)   //如果有右孩子,rightChild入队列
        {
            q.push(q.front()->rightPtr);
        }
        q.pop();  //已经遍历过的节点出队列
    }
}

7.数据库索引采用的底层数据结构。

B+树。

索引的数据结构分为Hash和B+树。

Hash更适合单个值的查找,O(1);

B+树更适合范围查找,因为叶子节点形成了一个有序链表。

与B树的区别体现在:B+树中只有叶子节点才有value,非叶子节点只有key;B树所有节点都有key和value;

8.函数命名规范。

9.函数形参,包含指针和地址等情况的合法性。

10.SQL语句

11.Linux函数(10个左右)

消息队列的创建:

key_t ftok(char *pathname, char proj);

 创建进程:fork();

读文件:read();写文件:write;打开文件:open();

函数返回从TC1970-1-1 0:0:0开始到现在的秒数   :time_t time(time_t * timer)   

12.数据库类型

CREATE TABLE IF NOT EXISTS `runoob_tbl`(
   `runoob_id` INT UNSIGNED AUTO_INCREMENT,
   `runoob_title` VARCHAR(100) NOT NULL,
   `runoob_author` VARCHAR(40) NOT NULL,
   `submission_date` DATE,
   PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

13.创建数组的方法

14.冒泡排序最坏情况的时间复杂度

最坏的情况 => 对于 n 位的数列则有比较次数为 (n-1) + (n-2) + ... + 1 = n * (n - 1) / 2,这就得到了最大的比较次数。

15.C++指针类型的变量初始化。

16.doGet和doPost的区别?

等等。


(1)

Heap = 新生代(约1/3) + 老年代(约2/3);

新生代 = Eden(8/10)+ From Survivor(1/10) + To Survivor(1/10);8:1:1

新生代常用标记-复制算法;老年代常用标记-整理算法。

(2)多线程:

一、corePoolSize 线程池核心线程大小

线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,
他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。

二、maximumPoolSize 线程池最大线程数量

一个任务被提交到线程池以后,首先会找有没有空闲存活线程,
如果有则直接将任务交给这个空闲线程来执行,如果没有则会缓存到工作队列(后面会介绍)中,
如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,
而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,
它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。

三、keepAliveTime 空闲线程存活时间

一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,
这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定

四、unit 空闲线程存活时间单位

keepAliveTime的计量单位

五、workQueue 工作队列

新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。
jdk中提供了四种工作队列:

①ArrayBlockingQueue

基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

②LinkedBlockingQuene

基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

③SynchronousQuene

一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

④PriorityBlockingQueue

具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

六、threadFactory 线程工厂

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等

七、handler 拒绝策略

当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,
这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,
jdk中提供了4中拒绝策略:

(3)单例模式:

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

创建线程的三种方式:

1.继承Thread类

2.实现Runnable接口

3.实现Callable接口

1. sleep()方法:可以让正在运行的线程进入阻塞状态,直到休眠时间满了,进入就绪状态。
2. yield()方法:可以让正在运行的线程直接进入就绪状态,让出CPU的使用权。

sleep()是使线程暂停执行一段时间的方法。wait()也是一种使线程暂停执行的方法。例如,当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。并且可以调用notify()方法或者notifyAll()方法通知正在等待的其他线程。notify()方法仅唤醒一个线程(等待队列中的第一个线程)并允许他去获得锁。notifyAll()方法唤醒所有等待这个对象的线程并允许他们去竞争获得锁。具体区别如下:

1)  原理不同。sleep()方法是Thread类的静态方法,是线程用来控制自身流程的,他会使此线程暂停执行一段时间,而把执行机会让给其他线程,等到计时时间一到,此线程会自动苏醒。例如,当线程执行报时功能时,每一秒钟打印出一个时间,那么此时就需要在打印方法前面加一个sleep()方法,以便让自己每隔一秒执行一次,该过程如同闹钟一样。而wait()方法是object类的方法,用于线程间通信,这个方法会使当前拥有该对象锁的进程等待,直到其他线程调用notify()方法或者notifyAll()时才醒来,不过开发人员也可以给他指定一个时间,自动醒来。

2)  对锁的 处理机制不同。由于sleep()方法的主要作用是让线程暂停执行一段时间,时间一到则自动恢复,不涉及线程间的通信,因此,调用sleep()方法并不会释放锁。而wait()方法则不同,当调用wait()方法后,线程会释放掉他所占用的锁,从而使线程所在对象中的其他synchronized数据可以被其他线程使用。

3)  使用区域不同。wait()方法必须放在同步控制方法和同步代码块中使用,sleep()方法则可以放在任何地方使用。sleep()方法必须捕获异常,而wait()、notify()、notifyAll()不需要捕获异常。在sleep的过程中,有可能被其他对象调用他的interrupt(),产生InterruptedException。由于sleep不会释放锁标志,容易导致死锁问题的发生,因此一般情况下,推荐使用wait()方法。 

更多详见:https://blog.youkuaiyun.com/zenggeweiss/article/details/90342282

(4)

简单工厂模式;

单例模式;

组合模式;

需要着重看:代理模式、观察者模式 

【CNN-GRU-Attention】基于卷积神经网络和门控循环单元网络结合注意力机制的多变量回归预测研究(Matlab代码实现)内容概要:本文介绍了基于卷积神经网络(CNN)、门控循环单元网络(GRU)与注意力机制(Attention)相结合的多变量回归预测模型研究,重点利用Matlab实现该深度学习模型的构建与仿真。该模型通过CNN提取输入数据的局部特征,利用GRU捕捉时间序列的长期依赖关系,并引入注意力机制增强关键时间步的权重,从而提升多变量时间序列回归预测的精度与鲁棒性。文中涵盖了模型架构设计、训练流程、参数调优及实际案例验证,适用于复杂非线性系统的预测任务。; 适合人群:具备一定机器学习与深度学习基础,熟悉Matlab编程环境,从事科研或工程应用的研究生、科研人员及算法工程师,尤其适合关注时间序列预测、能源预测、智能优化等方向的技术人员。; 使用场景及目标:①应用于风电功率预测、负荷预测、交通流量预测等多变量时间序列回归任务;②帮助读者掌握CNN-GRU-Attention混合模型的设计思路与Matlab实现方法;③为学术研究、毕业论文或项目开发提供可复现的代码参考和技术支持。; 阅读建议:建议读者结合Matlab代码逐模块理解模型实现细节,重点关注数据预处理、网络结构搭建与注意力机制的嵌入方式,并通过调整超参数和更换数据集进行实验验证,以深化对模型性能影响因素的理解。
下载前必看:https://pan.quark.cn/s/da7147b0e738 《商品采购管理系统详解》商品采购管理系统是一款依托数据库技术,为中小企业量身定制的高效且易于操作的应用软件。 该系统借助VC++编程语言完成开发,致力于改进采购流程,增强企业管理效能,尤其适合初学者开展学习与实践活动。 在此之后,我们将详细剖析该系统的各项核心功能及其实现机制。 1. **VC++ 开发环境**: VC++是微软公司推出的集成开发平台,支持C++编程,具备卓越的Windows应用程序开发性能。 在该系统中,VC++作为核心编程语言,负责实现用户界面、业务逻辑以及数据处理等关键功能。 2. **数据库基础**: 商品采购管理系统的核心在于数据库管理,常用的如SQL Server或MySQL等数据库系统。 数据库用于保存商品信息、供应商资料、采购订单等核心数据。 借助SQL(结构化查询语言)进行数据的增加、删除、修改和查询操作,确保信息的精确性和即时性。 3. **商品管理**: 系统内含商品信息管理模块,涵盖商品名称、规格、价格、库存等关键字段。 借助界面,用户能够便捷地录入、调整和查询商品信息,实现库存的动态调控。 4. **供应商管理**: 供应商信息在采购环节中占据重要地位,系统提供供应商注册、联系方式记录、信用评价等功能,助力企业构建稳固的供应链体系。 5. **采购订单管理**: 采购订单是采购流程的关键环节,系统支持订单的生成、审批、执行和追踪。 通过自动化处理,减少人为失误,提升工作效率。 6. **报表与分析**: 系统具备数据分析能力,能够生成采购报表、库存报表等,帮助企业掌握采购成本、库存周转率等关键数据,为决策提供支持。 7. **用户界面设计**: 依托VC++的MF...
【DC-AC】使用了H桥MOSFET进行开关,电感器作为滤波器,R和C作为负载目标是产生150V的双极输出和4安培(双极)的电流(Simulink仿真实现)内容概要:本文档围绕一个基于Simulink的电力电子系统仿真项目展开,重点介绍了一种采用H桥MOSFET进行开关操作的DC-AC逆变电路设计,结合电感器作为滤波元件,R和C构成负载,旨在实现150V双极性输出电压和4A双极性电流的仿真目标。文中详细描述了系统结构、关键器件选型及控制策略,展示了通过Simulink平台完成建模与仿真的全过程,并强调了参数调整与波形分析的重要性,以确保输出符合设计要求。此外,文档还提及该仿真模型在电力变换、新能源并网等领域的应用潜力。; 适合人群:具备电力电子基础知识和Simulink仿真经验的高校学生、科研人员及从事电力系统、新能源技术等相关领域的工程技术人员;熟悉电路拓扑与基本控制理论的初级至中级研究人员。; 使用场景及目标:①用于教学演示H桥逆变器的工作原理与滤波设计;②支撑科研项目中对双极性电源系统的性能验证;③为实际工程中DC-AC转换器的设计与优化提供仿真依据和技术参考;④帮助理解MOSFET开关行为、LC滤波机制及负载响应特性。; 阅读建议:建议读者结合Simulink模型文件同步操作,重点关注H桥驱动信号生成、电感电容参数选取及输出波形的傅里叶分析,建议在仿真过程中逐步调试开关频率与占空比,观察其对输出电压电流的影响,以深化对逆变系统动态特性的理解。
【优化调度】基于遗传算法的公交车调度排班优化的研究与实现(Matlab代码实现)内容概要:本文围绕基于遗传算法的公交车调度排班优化展开研究,利用Matlab进行代码实现,旨在通过智能优化算法解决公共交通系统中的调度难题。文中详细阐述了遗传算法在公交车发车频率、线路排班、司机分配等实际问题中的建模与应用过程,通过设定适应度函数、编码方式、交叉与变异策略,实现对多目标(如运营成本最小化、乘客等待时间最短化)的优化求解。同时,结合实际运行数据进行仿真验证,展示了该方法相较于传统调度方式在效率与经济性方面的显著优势。; 适合人群:具备一定Matlab编程基础,从事交通运输、城市规划、智能优化算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于城市公交系统的日常排班与动态调度优化;②作为智能交通系统(ITS)中调度模块的核心算法研究;③为高校相关课程提供算法实践案例,帮助理解遗传算法在现实复杂调度问题中的具体实现路径。; 阅读建议:建议读者结合文中Matlab代码逐段分析算法实现细节,重点关注染色体编码设计与适应度函数构建逻辑,并尝试在不同规模数据集上进行仿真实验,以深入掌握遗传算法参数调优技巧及其在调度问题中的泛化能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值