文档章节

Alibaba 面经

hyssop
 hyssop
发布于 2016/09/03 12:51
字数 1931
阅读 141
收藏 4

女士们 and 乡亲们。今天分享一个面经。阿里巴巴。 阿里巴巴北京这面的公司工作环境真的是没的说啊,好好好~

走进去就感觉此处静悄悄,唯有思维在燃烧。

接下来我就针对本次阿里巴巴之行做一点儿总结。

代码要写好,泛型、设计模式是王道。我身边代码写的好的,没有不对设计模式和泛型有较深入理解的。

问题1: String常量池和string对象的问题。这个问题真的就是老生常谈。
考官问什么导致String t ="a"+"bc", String tt ="abc"一样?
答案肯定是编译器优化的结果。

问题2: if else代码优化

大家都知道if else代码是我们刚刚开始学习的时候经常用的。其实在工作当中遇到一对的if else是开发人员无法忍受的。当然switch在短的代码里用还是很优雅的。但是较长的时候就有点儿那个了。

怎么办?这时候就是编程模式发挥的时候了。我自己写了一段贴出来,大家一起感受下这段代码,叫不出设计模式的名称,但是在实际应用的时候很好用。

public interface Search {

    boolean match(Search search);
    
    String doSearch(Map<String, Object> params);
}

public class SearchA extends SearchRegistry {

    public SearchA() {
        super(1);
    }

    public String doSearch() {
        System.out.println("A");
        return "A";
    }

    @Override
    public String doSearch(Map<String, Object> params) {
        return doSearch();
    }
}
public class SearchB extends SearchRegistry {
    public SearchB() {
        super(2);
    }

    public String doSearch() {
        System.out.println("B");
        return  "B";
    }



    @Override
    public String doSearch(Map<String, Object> params) {
        return doSearch();
    }
}
 public abstract class SearchRegistry  implements Search  {
    public SearchRegistry(int i){
        this.i = i;
    }

    public int i;

    public boolean match(Search search) {
        if(this.getClass().isAssignableFrom(search.getClass())){
            return true;
        }
        return false;
    }
}
public class DelegateSearch extends SearchRegistry {

    List<Search> search = new ArrayList<Search>();

    public DelegateSearch() {
        super(Integer.MAX_VALUE);
    }

    public boolean match(int p) {
        return false;
    }

    public String doSearch(Map<String, Object> params) {
        for (Search s : search) {
            if (s.match((Search)params.get("type"))) {
                return s.doSearch(params);
            }
        }
        return null;
    }

    public void addSearch(Search search) {
        this.search.add(search);
    }
}
public class Test {
    public static void main(String[] args) {
        DelegateSearch delegateSearch = new DelegateSearch();
        delegateSearch.addSearch(new SearchA());
        delegateSearch.addSearch(new SearchB());
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("type",new SearchA());
        delegateSearch.doSearch(params);
    }
}

要说这设计模式叫啥,真说不上,幸好考官要写代码或者画图。

接下来就是问我的项目是如何组织实现的。报表这东西在阿里已经做到了高可配置。光做可配置报表已经无法满足广大开发人员的需求,开发人员要想做一个自己喜欢的报表,直接用拖拽的方式从新组织报表架构就可以了。

从中我觉得有几点值得学习的地方

第一、如何做到数据源适配,在不指定具体数据源的情况下适配到具体的数据源。

第二、底层数据的组织结构。底层的数据不要总认为是什么数据库出来的。数据的来源有很多种,数据的形式有很多种,代码要能够做到屏蔽数据的来源和格式,将其用nosql的形式按列存储。这样就能灵活将不同表的数据组织到一个前台页面当中了。

第三、前台页面要对插件做到有扩展性,不能只对echarts等有兼容,要多多种前端控件有兼容,做到配置页面可配置。定制更加的灵活。 接下来我们就仔细分析这个类,从中我们也能看出来阿里目前的面试是要扎实的代码功底,不想某些小公司说一些书本上的东西了。

从图中我们可以看出JdbcTemplate集成了JdbcAccessor,实现了JdbcOperations。

JdbcAccessor 该类主要提供了连接数据库的信息:dataSource(数据源)、exceptionTranslator(错误解析器)。

JdbcOperations 该类提供了操作数据库的所有方法。

<T> T execute(ConnectionCallback<T> action) throws DataAccessException;

执行jdbc数据访问的操作,实现了数据库连接回调接口,允许在spring环境下执行数据访问。就是说,参加spring管理实务和将jdbc的sqlExceptions转换成为DataAccessException类型。

<T> T execute(StatementCallback<T> action) throws DataAccessException;

执行jdbc数据访问的操作,实现了数据库语句级别的回调接口,允许在spring环境下执行数据访问。就是说,参加spring管理实务和将jdbc的sqlExceptions转换成为DataAccessException类型。

void execute(String sql) throws DataAccessException; 提供了sql语句执行操作,尤其是ddl语句。

<T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;

执行了一个给定的sql语句,使用ResultSetExtractor类型实例读取结果。

void query(String sql, RowCallbackHandler rch) throws DataAccessException;

执行一个sql语句,使用RowCallbackHandler按行处理结果

<T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;

执行给定的sql语句,通过rowMapper将每行信息映射到java对象上去.

<T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException;

执行给定的sql语句,通过rowMapper将单行结果映射到java对象上去. <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException;

使用jdbc语句,而非PreparedStatement执行给定sql。将结果映射到对应requiredType类型对象中去,并返回该对象。

Map<String, Object> queryForMap(String sql) throws DataAccessException;
执行一个返回Map的查询。执行的查询使用JDBC Statement,如果你想使用PreparedStatement采用方法queryForMap(String, Object...)。

<T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException;

使用JDBC Statement执行一个返回List的查询。执行的查询使用JDBC。 List<Map<String, Object>> queryForList(String sql) throws DataAccessException;

使用JDBC Statement执行一个返回List<Map<String, Object>>类型结果的查询。

SqlRowSet queryForRowSet(String sql) throws DataAccessException;

使用JDBC Statement执行一个返回SqlRowSet类型结果的查询。

int update(String sql) throws DataAccessException;

执行一个单sql更新操作(包括单插入、更新、删除)。

int[] batchUpdate(String... sql) throws DataAccessException;

使用单JDBC Statement执行多sql更新操作。

<T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException;

上面这些方法都是针对JDBC Statement,还有a prepared statement与其对应这里就不都介绍了。

JdbcTemplate

JdbcTemplate实现了操作数据库的多有操作。

首先是初始化的时候将数据源 、懒加载信息设置到父类中。并初始化父类的错误解析器exceptionTranslator。

	public JdbcTemplate(DataSource dataSource, boolean lazyInit) {
		setDataSource(dataSource);
		setLazyInit(lazyInit);
		afterPropertiesSet();
	}

其次,定义了四个内部类。

CloseSuppressingInvocationHandler:

connection类代理解析器InvocationHandler

SimplePreparedStatementCreator:

PreparedStatementCreator适配器,用于执行简单的sql语句。

SimpleCallableStatementCreator:

CallableStatementCreator适配器,用于执行简单的sql语句。

RowCallbackHandlerResultSetExtractor:

适配一个RowCallbackHandler在ResultSetExtractor中。

这四个内部类都是为了实现数据库访问操作扩展的实现。

JdbcTemplate里面的实现很多,我们看两个例子:

1、 public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException

public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
		Assert.notNull(sql, "SQL must not be null");
		Assert.notNull(rse, "ResultSetExtractor must not be null");
		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL query [" + sql + "]");
		}
		class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
			@Override
			public T doInStatement(Statement stmt) throws SQLException {
				ResultSet rs = null;
				try {
					rs = stmt.executeQuery(sql);
					ResultSet rsToUse = rs;
					if (nativeJdbcExtractor != null) {
						rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
					}
					return rse.extractData(rsToUse);
				}
				finally {
					JdbcUtils.closeResultSet(rs);
				}
			}
			@Override
			public String getSql() {
				return sql;
			}
		}
		return execute(new QueryStatementCallback());
	}
```	
该方法中定义了回调函数,回调函数中将结果处理器rse放置进来,通过处理器处理结果并返回。那么最终调用的是方法。  

 public <T> T execute(StatementCallback<T> action) throws DataAccessException
```java
public <T> T execute(StatementCallback<T> action) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Connection con = DataSourceUtils.getConnection(getDataSource());
		Statement stmt = null;
		try {
			Connection conToUse = con;
			if (this.nativeJdbcExtractor != null &&
					this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
				conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
			}
			stmt = conToUse.createStatement();
			applyStatementSettings(stmt);
			Statement stmtToUse = stmt;
			if (this.nativeJdbcExtractor != null) {
				stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
			}
			T result = action.doInStatement(stmtToUse);
			handleWarnings(stmt);
			return result;
		}
		catch (SQLException ex) {
			// Release Connection early, to avoid potential connection pool deadlock
			// in the case when the exception translator hasn't been initialized yet.
			JdbcUtils.closeStatement(stmt);
			stmt = null;
			DataSourceUtils.releaseConnection(con, getDataSource());
			con = null;
			throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
		}
		finally {
			JdbcUtils.closeStatement(stmt);
			DataSourceUtils.releaseConnection(con, getDataSource());
		}
	}

操作流程图如下:

输入图片说明

当然我是挂了,就写到这里,希望后来的小生能够成功~加油~

加公众号,共同进步:

输入图片说明

参考文章: http://blog.csdn.net/jjavaboy/article/details/44598877

欢迎加入qq群: 122567875 欢迎关注微信公众号:hyssop的后花园

© 著作权归作者所有

共有 人打赏支持
上一篇: spring 事务(1)
下一篇: 说说类型转换
hyssop
粉丝 19
博文 103
码字总数 111868
作品 0
昌平
程序员
私信 提问
Spring Cloud Alibaba迁移指南(三):极简的 Config

自 Spring Cloud 官方宣布 Spring Cloud Netflix 进入维护状态后,我们开始制作《Spring Cloud Alibaba迁移指南》系列文章,向开发者提供更多的技术选型方案,并降低迁移过程中的技术难度。 ...

中间件小哥
02/26
0
0
阿里巴巴C++程序员面试的10个问题,你会几个?

此前,w3cschool app开发者头条上分享了诸多名企程序员面经。 比如阿里巴巴java程序员面经,阿里巴巴前端开发程序员面经。这些面经吸引了大多数的程序员们的围观。 今天要给程序员们分享的是...

W3Cschool
2017/12/23
0
0
掘金秋招征文大赛评选结果

为期一月的掘金秋招技术征文活动结束了,获奖作者如下 一等奖3名 第一名 Kindle Paperwhite 面试过阿里等互联网大公司,我知道了这些套路 | 掘金技术征文 第二名 cherry樱桃G80-3800青轴 腾讯...

Plum
2017/10/11
0
0
滴滴出行java面试9个问题,你会几个?

此前,w3cschool app开发者头条发布了网易java面经、阿里巴巴java面经、小米java面经。 今天给程序员小伙伴们分享的是滴滴出行java面经。 通常而言,在学习java过程中,首先要学会自己抓住重...

W3Cschool
2017/12/08
0
0
您收到一封 2019 阿里云峰会 (北京) 邀请函

2019 年是阿里云成立的第 10 年,在过去的 10 年间,阿里云引领了国内云基础设施市场;在当下,我们希望可以和您一起分享阿里云的新战略和新思考。 2019 年将是云原生在中国爆发和落地的一年...

迷你芊宝宝
03/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

腾讯面试:一条SQL语句执行得很慢的原因有哪些?

说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你“输入URL回车之后,究竟发生了什么”一样,看看你能说出多少了。 之前腾讯面试的实...

java菜分享
34分钟前
9
0
Java 基本功 之 CAS

本文首发于个人公众号《andyqian》, 期待你的关注! 前言 在Java并发编程中,我们经常使用锁对竞争资源予以并发控制,以解决资源竞争的问题。但无论是使用 Lock 还是 Synchronized,随着锁机...

andyqian
38分钟前
4
0
信号量与条件变量的区别

注意信号量与条件变量的区别 信号量内容可见:http://www.cnblogs.com/charlesblc/p/6142868.html 信号量、共享内存,以及消息队列等System V IPC三剑客主要关注进程间通信; 而条件变量、互...

shzwork
49分钟前
1
0
在VirtualBox 6.0中安装fedora 30

操作系统安装完毕后首先进行更新。 sudo dnf update 重启虚拟机后,安装VirtualBox依赖的软件包。 sudo dnf install kernel-headers kernel-devel dkms gcc 最后,安装“增强功能”。...

gugudu
57分钟前
1
0
861. Score After Flipping Matrix

为了获得最大值,我们必须保证每一行列下标小的1尽可能的多(最高位的1尽可能多)。 首先,考虑我们可以进行的操作有 翻转列,进行列操作 翻转行,进行行操作 通过行操作 我们总是可以使得第...

reter
58分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部